import { useState } from 'react'
import { Line, Bar, Pie, Doughnut } from 'react-chartjs-2'
import GeoMaps from './GeoMaps'
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  BarElement,
  Title,
  Tooltip,
  Legend,
  ArcElement,
} from 'chart.js'
import type { AdminStats } from '../AdminPage'

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  BarElement,
  Title,
  Tooltip,
  Legend,
  ArcElement,
)

interface Props {
  stats: AdminStats | null
  statsStatus: 'loading' | 'error' | 'ready'
  opsStatus: { buildCommit: string | null; buildNumber: string | null; deployedAt: string | null; cachePurge: { ok: boolean; at: string | null; error: string | null }; deployHook: { ok: boolean; at: string | null; error: string | null } } | null
  formatDate: (date: string | null) => string
  maskIp: (ip: string) => string
  maintenanceMsg: string | null
  selectedBackup: string
  backupFiles: Array<{ filename: string; sizeBytes: number; createdAt: string | null; reason: string; adminUpdatedAt: string | null; totalHits: number; totalVisits: number }>
  selectedBackupPreview: { filename: string; sizeBytes: number; createdAt: string | null; reason: string; adminUpdatedAt: string | null; totalHits: number; totalVisits: number } | null
  onBackupSelect: (filename: string) => void
  onRestore: () => void
  onExport: () => void
  onBackupNow: () => void
  onPrune: () => void
  onClear: () => void
  onPurgeCache: () => void
  onDeployHook: () => void
  onRefreshStatus: () => void
}

export function AnalyticsPanel({
  stats,
  statsStatus,
  opsStatus,
  formatDate,
  maskIp,
  maintenanceMsg,
  selectedBackup,
  backupFiles,
  selectedBackupPreview,
  onBackupSelect,
  onRestore,
  onExport,
  onBackupNow,
  onPrune,
  onClear,
  onPurgeCache,
  onDeployHook,
  onRefreshStatus,
}: Props) {
  const [chartTab, setChartTab] = useState<'overview' | 'breakdown' | 'geographic' | 'referrers'>('overview')
  const [expandedVisitor, setExpandedVisitor] = useState<string | null>(null)

  if (statsStatus === 'loading') return <p className="admin-stats-note">Loading analytics…</p>
  if (statsStatus === 'error') return <p className="admin-stats-note">Failed to load analytics.</p>
  if (!stats) return null

  // Normalize fields that may be missing from older data
  const realHits = stats.realHits ?? 0
  const botHits = stats.botHits ?? 0
  const totalHits = stats.totalHits ?? 0
  const last7DaysReal = stats.last7DaysReal ?? stats.last7Days.map((d: { day: string; hits: number }) => ({ day: d.day, hits: 0 }))
  const last7DaysBot = stats.last7DaysBot ?? stats.last7Days.map((d: { day: string; hits: number }) => ({ day: d.day, hits: 0 }))
  const last30DaysRealTotal = stats.last30DaysRealTotal ?? 0
  const last30DaysBotTotal = stats.last30DaysBotTotal ?? 0
  const topPathsReal = stats.topPathsReal ?? stats.topPaths
  const topPathsBot = stats.topPathsBot ?? []
  const botReasons = stats.botReasons ?? []

  // Chart data - Daily trend
  const dailyChartData = {
    labels: stats.last7Days.map((d: { day: string; hits: number }) => d.day),
    datasets: [
      {
        label: 'Real Visitors',
        data: last7DaysReal.map((d: { day: string; hits: number }) => d.hits),
        borderColor: '#c9a84c',
        backgroundColor: 'rgba(201, 168, 76, 0.1)',
        tension: 0.4,
        fill: true,
      },
      {
        label: 'Bot Traffic',
        data: last7DaysBot.map((d: { day: string; hits: number }) => d.hits),
        borderColor: '#666',
        backgroundColor: 'rgba(102, 102, 102, 0.1)',
        tension: 0.4,
        fill: true,
      },
    ],
  }

  // Chart data - Bot breakdown (pie)
  const botPieData = {
    labels: botReasons.map((b: { reason: string; count: number }) => b.reason.replace(/-/g, ' ')),
    datasets: [{
      data: botReasons.map((b: { reason: string; count: number }) => b.count),
      backgroundColor: [
        '#c9a84c',
        '#a0853d',
        '#6d5a2e',
        '#8b7635',
        '#9e8843',
        '#bbb477',
        '#7a6930',
        '#5a4820',
        '#c0a060',
        '#746c36',
      ],
      borderColor: '#1a1a15',
      borderWidth: 2,
    }],
  }

  // Traffic ratio (doughnut)
  const trafficRatioData = {
    labels: ['Real Visitors', 'Bot Traffic'],
    datasets: [{
      data: [realHits, botHits],
      backgroundColor: ['#c9a84c', '#999'],
      borderColor: '#1a1a15',
      borderWidth: 2,
    }],
  }

  // Top paths comparison
  const topPathsLabels = Array.from({ length: Math.max(topPathsReal.length, topPathsBot.length) }, (_, i: number) => {
    const realPath = topPathsReal[i]?.path || ''
    const botPath = topPathsBot[i]?.path || ''
    return realPath || botPath || `Path ${i + 1}`
  }).slice(0, 8)

  const topPathsChartData = {
    labels: topPathsLabels,
    datasets: [
      {
        label: 'Real Hits',
        data: topPathsLabels.map((_label, i) => topPathsReal[i]?.hits || 0),
        backgroundColor: '#c9a84c',
      },
      {
        label: 'Bot Hits',
        data: topPathsLabels.map((_label, i) => topPathsBot[i]?.hits || 0),
        backgroundColor: '#999',
      },
    ],
  }

  // 30-day trend chart
  const last30DaysReal = stats.visitors.last30DaysReal ?? []
  const thirtyDayChartData = {
    labels: last30DaysReal.map((d: { day: string; hits: number }) => d.day.slice(5)),
    datasets: [{
      label: 'Real Visitors',
      data: last30DaysReal.map((d: { day: string; hits: number }) => d.hits),
      borderColor: '#c9a84c',
      backgroundColor: 'rgba(201, 168, 76, 0.08)',
      tension: 0.3,
      fill: true,
      pointRadius: 2,
    }],
  }

  // Device breakdown (doughnut)
  const deviceBreakdown = stats.visitors.deviceBreakdown ?? { mobile: 0, desktop: 0, tablet: 0, unknown: 0 }
  const deviceChartData = {
    labels: ['Desktop', 'Mobile', 'Tablet', 'Unknown'],
    datasets: [{
      data: [deviceBreakdown.desktop, deviceBreakdown.mobile, deviceBreakdown.tablet, deviceBreakdown.unknown],
      backgroundColor: ['#c9a84c', '#a0853d', '#6d5a2e', '#444'],
      borderColor: '#1a1a15',
      borderWidth: 2,
    }],
  }

  const chartOptions = {
    responsive: true,
    maintainAspectRatio: true,
    plugins: {
      legend: {
        labels: {
          color: '#f0ead8',
          font: { size: 12 },
        },
      },
      tooltip: {
        backgroundColor: '#2a2518',
        titleColor: '#f0ead8',
        bodyColor: '#f0ead8',
        borderColor: '#c9a84c',
        borderWidth: 1,
      },
    },
    scales: {
      y: {
        beginAtZero: true,
        ticks: { color: '#7a7060' },
        grid: { color: '#2a2518' },
      },
      x: {
        ticks: { color: '#7a7060' },
        grid: { color: '#2a2518' },
      },
    },
  }

  return (
    <section className="admin-panel-section" aria-label="Analytics">
      <div className="admin-panel-head">
        <h2>Analytics Dashboard</h2>
        <p>Real-time insights into site traffic, bot detection, visitor behavior, and data management.</p>
      </div>

      {/* KPI Grid */}
      <div className="admin-stats-grid">
        <article>
          <h3>Total Hits</h3>
          <p>{stats.totalHits.toLocaleString()}</p>
          <small>All page requests</small>
        </article>
        <article>
          <h3>Real Traffic</h3>
          <p>{realHits.toLocaleString()}</p>
          <small>{totalHits > 0 ? ((realHits / totalHits) * 100).toFixed(1) : '0.0'}% of total</small>
        </article>
        <article>
          <h3>Bot Traffic</h3>
          <p>{botHits.toLocaleString()}</p>
          <small>{totalHits > 0 ? ((botHits / totalHits) * 100).toFixed(1) : '0.0'}% of total</small>
        </article>
        <article>
          <h3>Last 30 Days</h3>
          <p>{last30DaysRealTotal.toLocaleString()}</p>
          <small>Real hits • {last30DaysBotTotal.toLocaleString()} bots</small>
        </article>
        <article>
          <h3>Unique Visitors</h3>
          <p>{stats.visitors.uniqueVisitors.toLocaleString()}</p>
          <small>Tracked with consent</small>
        </article>
        <article>
          <h3>Returning Rate</h3>
          <p>{stats.visitors.totalVisits > 0 ? `${Math.round((stats.visitors.returningVisits / stats.visitors.totalVisits) * 100)}%` : '0%'}</p>
          <small>{stats.visitors.returningVisits.toLocaleString()} return visits</small>
        </article>
      </div>

      {/* Chart Tabs */}
      <div className="admin-tabs admin-tabs--charts">
        <button type="button" className={`admin-tab${chartTab === 'overview' ? ' admin-tab--active' : ''}`} onClick={() => setChartTab('overview')}>Overview</button>
        <button type="button" className={`admin-tab${chartTab === 'breakdown' ? ' admin-tab--active' : ''}`} onClick={() => setChartTab('breakdown')}>Bot &amp; Devices</button>
        <button type="button" className={`admin-tab${chartTab === 'geographic' ? ' admin-tab--active' : ''}`} onClick={() => setChartTab('geographic')}>Geographic</button>
        <button type="button" className={`admin-tab${chartTab === 'referrers' ? ' admin-tab--active' : ''}`} onClick={() => setChartTab('referrers')}>Referrers</button>
      </div>

      {/* Overview Charts */}
      {chartTab === 'overview' && (
        <>
          <div className="admin-analytics-grid">
            <div className="admin-analytics-card">
              <h3 className="admin-analytics-card-title">7-Day Trend (Real vs Bot)</h3>
              <Line data={dailyChartData} options={chartOptions} />
            </div>
            <div className="admin-analytics-card">
              <h3 className="admin-analytics-card-title">Traffic Composition</h3>
              <Doughnut data={trafficRatioData} options={{...chartOptions, plugins: {...chartOptions.plugins}}} />
            </div>
          </div>
          <div className="admin-analytics-grid" style={{ marginTop: '1rem' }}>
            <div className="admin-analytics-card admin-analytics-card--wide">
              <h3 className="admin-analytics-card-title">30-Day Real Visitor Trend</h3>
              <Line data={thirtyDayChartData} options={chartOptions} />
            </div>
          </div>
        </>
      )}

      {/* Bot & Device Charts */}
      {chartTab === 'breakdown' && (
        <>
          <div className="admin-analytics-grid">
            <div className="admin-analytics-card">
              <h3 className="admin-analytics-card-title">Device Breakdown</h3>
              <Doughnut data={deviceChartData} options={{...chartOptions, plugins: {...chartOptions.plugins}}} />
            </div>
            <div className="admin-analytics-card">
              <h3 className="admin-analytics-card-title">Device Counts</h3>
              <ul className="admin-bot-reason-list">
                <li><span>Desktop</span><strong>{deviceBreakdown.desktop.toLocaleString()}</strong></li>
                <li><span>Mobile</span><strong>{deviceBreakdown.mobile.toLocaleString()}</strong></li>
                <li><span>Tablet</span><strong>{deviceBreakdown.tablet.toLocaleString()}</strong></li>
                {deviceBreakdown.unknown > 0 && <li><span>Unknown</span><strong>{deviceBreakdown.unknown.toLocaleString()}</strong></li>}
              </ul>
            </div>
          </div>
          <div className="admin-analytics-grid" style={{ marginTop: '1rem' }}>
            <div className="admin-analytics-card">
              <h3 className="admin-analytics-card-title">Bot Sources</h3>
              {botReasons.length === 0 ? (
                <p className="admin-stats-note">No bot traffic detected.</p>
              ) : (
                <Pie data={botPieData} options={{...chartOptions, plugins: {...chartOptions.plugins}}} />
              )}
            </div>
            <div className="admin-analytics-card">
              <h3 className="admin-analytics-card-title">Bot Detection Details</h3>
              {botReasons.length === 0 ? (
                <p className="admin-stats-note">No bots detected yet.</p>
              ) : (
                <ul className="admin-bot-reason-list">
                  {botReasons.map((reason: { reason: string; count: number }) => (
                    <li key={reason.reason} className="admin-bot-reason-item">
                      <span>{reason.reason.replace(/-/g, ' ')}</span>
                      <strong>{reason.count.toLocaleString()}</strong>
                    </li>
                  ))}
                </ul>
              )}
            </div>
          </div>
        </>
      )}

      {/* Geographic Charts */}
      {chartTab === 'geographic' && (
        <div className="admin-analytics-geo">
          <div className="admin-analytics-card admin-analytics-card--wide">
            <h3 className="admin-analytics-card-title">Top Pages</h3>
            <Bar data={topPathsChartData} options={{...chartOptions, indexAxis: 'y' as const}} />
          </div>
          <GeoMaps
            topCountries={stats.visitors.topCountries}
            topStates={stats.visitors.topStates}
          />
        </div>
      )}

      {/* Referrers Tab */}
      {chartTab === 'referrers' && (
        <div className="admin-analytics-grid">
          <div className="admin-analytics-card admin-analytics-card--wide">
            <h3 className="admin-analytics-card-title">Top Traffic Sources</h3>
            {(stats.visitors.topReferrers ?? []).length === 0 ? (
              <p className="admin-stats-note">No referrer data yet. Referrers are captured on SPA navigations after consent.</p>
            ) : (
              <ul className="admin-bot-reason-list">
                {(stats.visitors.topReferrers ?? []).map((item: { referrer: string; count: number }) => (
                  <li key={item.referrer}>
                    <span>{item.referrer}</span>
                    <strong>{item.count.toLocaleString()}</strong>
                  </li>
                ))}
              </ul>
            )}
          </div>
        </div>
      )}

      {/* Recent Visitors Table */}
      <div className="admin-stats-head admin-stats-head--visitors">
        <h2>Visitor Details</h2>
        <p>Real-time tracking of visitor activity, geography, and returning behavior.</p>
      </div>
      <p className="admin-privacy-note">Privacy: visitor analytics only run after cookie consent. IPs below are masked.</p>

      <div className="admin-stats-grid admin-stats-grid--visitor">
        <article><h3>Total Visits</h3><p>{stats.visitors.totalVisits.toLocaleString()}</p></article>
        <article><h3>Unique Visitors</h3><p>{stats.visitors.uniqueVisitors.toLocaleString()}</p></article>
        <article><h3>Returning Visits</h3><p>{stats.visitors.returningVisits.toLocaleString()}</p></article>
        <article><h3>First Visit</h3><p>{formatDate(stats.visitors.firstVisitAt)}</p></article>
      </div>

      <div className="admin-stats-lists">
        <div>
          <h3>Top Countries</h3>
          <ul>
            {stats.visitors.topCountries.map((item: { name: string; hits: number }) => (
              <li key={item.name}><span>{item.name}</span><strong>{item.hits.toLocaleString()}</strong></li>
            ))}
          </ul>
        </div>
        <div>
          <h3>Top States</h3>
          <ul>
            {stats.visitors.topStates.map((item: { name: string; hits: number }) => (
              <li key={item.name}><span>{item.name}</span><strong>{item.hits.toLocaleString()}</strong></li>
            ))}
          </ul>
        </div>
      </div>

      <div className="admin-visits-table-wrap">
        <h3>Recent Visitor Log</h3>
        {stats.visitors.recentVisits.length === 0 ? (
          <p className="admin-stats-note">No visitor records yet.</p>
        ) : (
          <div className="admin-visits-table-scroll">
            <table className="admin-visits-table">
              <thead>
                <tr>
                  <th>Time</th>
                  <th>IP</th>
                  <th>Country</th>
                  <th>Path</th>
                  <th>Referrer</th>
                  <th>Device</th>
                  <th>Returning</th>
                  <th>Visit #</th>
                </tr>
              </thead>
              <tbody>
                {stats.visitors.recentVisits.map(row => {
                  const rowKey = `${row.visitorId}-${row.at}`
                  const isExpanded = expandedVisitor === rowKey
                  return (
                    <>
                      <tr
                        key={rowKey}
                        className={`admin-visitor-row${isExpanded ? ' admin-visitor-row--expanded' : ''}`}
                        style={{ cursor: 'pointer' }}
                        onClick={() => setExpandedVisitor(isExpanded ? null : rowKey)}
                        title="Click to view page history"
                      >
                        <td>{formatDate(row.at)}</td>
                        <td><code className="admin-visitor-ip">{maskIp(row.ip)}</code></td>
                        <td>{row.country || '—'}</td>
                        <td className="admin-visitor-path" title={row.path}>{row.path}</td>
                        <td className="admin-visitor-path" title={row.referrer || ''}>{row.referrer || '—'}</td>
                        <td>{row.device || '—'}</td>
                        <td>
                          <span className={`admin-visitor-tag admin-visitor-tag--${row.returningVisitor ? 'returning' : 'new'}`}>
                            {row.returningVisitor ? 'Returning' : 'New'}
                          </span>
                        </td>
                        <td className="admin-visitor-count">{row.visitCount} {isExpanded ? '▲' : '▼'}</td>
                      </tr>
                      {isExpanded && (row.pageHistory ?? []).length > 0 && (
                        <tr key={`${rowKey}-history`} className="admin-visitor-history-row">
                          <td colSpan={8}>
                            <div className="admin-visitor-history">
                              <p className="admin-visitor-history-label">Full page history for this visitor ({(row.pageHistory ?? []).length} pages):</p>
                              <ol className="admin-visitor-history-list">
                                {[...(row.pageHistory ?? [])].reverse().map((entry, i) => (
                                  <li key={i} className="admin-visitor-history-entry">
                                    <span className="admin-visitor-history-time">{formatDate(entry.at)}</span>
                                    <span className="admin-visitor-history-path">{entry.path}</span>
                                    {entry.referrer && <span className="admin-visitor-history-ref">from {entry.referrer}</span>}
                                  </li>
                                ))}
                              </ol>
                            </div>
                          </td>
                        </tr>
                      )}
                      {isExpanded && (row.pageHistory ?? []).length === 0 && (
                        <tr key={`${rowKey}-history-empty`} className="admin-visitor-history-row">
                          <td colSpan={8}><p style={{ padding: '0.5rem 1rem', color: '#8a7f5a', margin: 0, fontSize: '0.85rem' }}>No page history yet — history is built from SPA navigations after consent.</p></td>
                        </tr>
                      )}
                    </>
                  )
                })}
              </tbody>
            </table>
          </div>
        )}
      </div>

      {/* Contact Summary */}
      <div className="admin-stats-head admin-stats-head--visitors">
        <h2>Contact Summary</h2>
        <p>Submission totals from the contact form.</p>
      </div>
      <div className="admin-stats-grid">
        <article><h3>Total Contact Messages</h3><p>{stats.contactTotals.totalSubmissions.toLocaleString()}</p></article>
        <article><h3>Total Bible Questions</h3><p>{stats.contactTotals.totalQuestions.toLocaleString()}</p></article>
      </div>

      {/* Deployment & Cache Status */}
      <div className="admin-stats-head admin-stats-head--visitors">
        <h2>Deployment &amp; Cache Status</h2>
        <p>Current deployment metadata and cache purge health for the live app.</p>
      </div>
      <div className="admin-stats-grid">
        <article><h3>Build Commit</h3><p>{opsStatus?.buildCommit ?? 'Not available'}</p></article>
        <article><h3>Build Number</h3><p>{opsStatus?.buildNumber ?? 'Not available'}</p></article>
        <article><h3>Deployed At</h3><p>{formatDate(opsStatus?.deployedAt ?? null)}</p></article>
        <article><h3>Cache Purge</h3><p>{opsStatus?.cachePurge.ok ? 'Healthy' : 'Needs setup'}</p><p>{formatDate(opsStatus?.cachePurge.at ?? null)}</p></article>
      </div>

      {/* Data Management */}
      <div className="admin-stats-head admin-stats-head--visitors">
        <h2>Data Management</h2>
        <p>Export, backup, or retain only recent analytics data.</p>
      </div>
      <div className="admin-stats-grid">
        <article><h3>Hit Stats Write</h3><p>{stats.writeStatus.hitStats.ok ? 'Healthy' : 'Error'}</p><p>{formatDate(stats.writeStatus.hitStats.at)}</p></article>
        <article><h3>Visitor Stats Write</h3><p>{stats.writeStatus.visitorStats.ok ? 'Healthy' : 'Error'}</p><p>{formatDate(stats.writeStatus.visitorStats.at)}</p></article>
        <article><h3>Backup Status</h3><p>{stats.writeStatus.backups.ok ? 'Healthy' : 'Error'}</p><p>{formatDate(stats.writeStatus.backups.at)}</p></article>
      </div>
      <div className="admin-actions admin-actions--maintenance">
        <button type="button" className="btn-admin-reset" onClick={onExport}>Export JSON</button>
        <button type="button" className="btn-admin-reset" onClick={onBackupNow}>Backup Now</button>
        <button type="button" className="btn-admin-reset" onClick={onPrune}>Prune Old Data</button>
        <button type="button" className="btn-admin-remove" onClick={onClear}>Clear Analytics</button>
      </div>
      <div className="admin-actions admin-actions--maintenance">
        <button type="button" className="btn-admin-reset" onClick={onPurgeCache}>Purge Cache</button>
        <button type="button" className="btn-admin-reset" onClick={onDeployHook}>Trigger Deploy</button>
        <button type="button" className="btn-admin-reset" onClick={onRefreshStatus}>Refresh Status</button>
      </div>
      <div className="admin-restore-row">
        <label htmlFor="restore-backup">Restore Backup</label>
        <select id="restore-backup" value={selectedBackup} onChange={e => onBackupSelect(e.target.value)} disabled={backupFiles.length === 0}>
          {backupFiles.length === 0 && <option value="">No backups found</option>}
          {backupFiles.map(file => <option key={file.filename} value={file.filename}>{file.filename}</option>)}
        </select>
        <button type="button" className="btn-admin-reset" onClick={onRestore} disabled={!selectedBackup}>Restore Selected Backup</button>
      </div>
      {selectedBackupPreview && (
        <div className="admin-restore-preview">
          <h3>Restore Preview</h3>
          <p><strong>Backup:</strong> {selectedBackupPreview.filename}</p>
          <p><strong>Created:</strong> {formatDate(selectedBackupPreview.createdAt)}</p>
          <p><strong>Size:</strong> {(selectedBackupPreview.sizeBytes / 1024).toFixed(1)} KB</p>
          <p><strong>Total Hits:</strong> {selectedBackupPreview.totalHits.toLocaleString()}</p>
          <p><strong>Total Visits:</strong> {selectedBackupPreview.totalVisits.toLocaleString()}</p>
        </div>
      )}
      {maintenanceMsg && <p className="admin-stats-note">{maintenanceMsg}</p>}
    </section>
  )
}
