import { useEffect, useState, type ReactNode } from 'react'
import {
  fetchAdminMe,
  fetchAdminSummary,
  fetchAdminTimeSeries,
  type AdminSummary,
  type AdminTimeSeriesResponse,
  type AdminTimeBucket
} from '../services/adminApi.js'
import { BarChart2, Bookmark, ChevronLeft, Database, Image, MapPin, Mic, Users } from 'lucide-react'

function formatNumber(value: number): string {
  return value.toLocaleString()
}

function formatBytes(bytes: number | undefined): string {
  if (bytes === undefined || bytes === null) return '—'
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  const num = bytes / Math.pow(k, i)
  return `${num.toFixed(1)} ${sizes[i]}`
}

function KpiCard({
  icon,
  label,
  value
}: {
  icon: ReactNode
  label: string
  value: number | string
}) {
  return (
    <div className="stats-kpi-card glass">
      <div className="stats-kpi-icon">{icon}</div>
      <div className="stats-kpi-body">
        <span className="stats-kpi-label">{label}</span>
        <span className="stats-kpi-value">{typeof value === 'number' ? formatNumber(value) : value}</span>
      </div>
    </div>
  )
}

function TimeSeriesChart({
  title,
  seriesKey,
  data
}: {
  title: string
  seriesKey: string
  data: AdminTimeSeriesResponse | null
}) {
  if (!data) {
    return null
  }

  const metric = data.series.find((s) => s.metric === seriesKey)
  if (!metric || metric.points.length === 0) {
    return (
      <div className="form-card glass">
        <div className="form-header">
          <BarChart2 className="form-icon" />
          <h2>{title}</h2>
        </div>
        <p className="dashboard-status-msg">Keine Daten im gewählten Zeitraum.</p>
      </div>
    )
  }

  const max = metric.points.reduce((acc, p) => (p.count > acc ? p.count : acc), 0) || 1

  return (
    <div className="form-card glass">
      <div className="form-header">
        <BarChart2 className="form-icon" />
        <h2>{title}</h2>
      </div>
      <div className="stats-bar-chart" role="img" aria-label={title}>
        {metric.points.map((point) => {
          const heightPct = Math.max(2, (point.count / max) * 100)
          return (
            <div key={point.date} className="stats-bar-column" title={`${point.date}: ${point.count}`}>
              <span className="stats-bar-value">{point.count > 0 ? String(point.count) : ''}</span>
              <div className="stats-bar-track">
                <div className="stats-bar stats-bar--distance" style={{ height: `${heightPct}%` }} />
              </div>
              <span className="stats-bar-label">{point.date.slice(5)}</span>
            </div>
          )
        })}
      </div>
    </div>
  )
}

interface AdminDashboardProps {
  onBack: () => void
}

export default function AdminDashboard({ onBack }: AdminDashboardProps) {
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [summary, setSummary] = useState<AdminSummary | null>(null)
  const [timeSeries, setTimeSeries] = useState<AdminTimeSeriesResponse | null>(null)
  const [bucket, setBucket] = useState<AdminTimeBucket>('day')
  const [windowDays, setWindowDays] = useState(90)

  useEffect(() => {
    let cancelled = false

    async function load() {
      try {
        setLoading(true)
        setError(null)

        await fetchAdminMe()
        const [summaryRes, tsRes] = await Promise.all([
          fetchAdminSummary(),
          fetchAdminTimeSeries({ bucket, windowDays })
        ])

        if (!cancelled) {
          setSummary(summaryRes)
          setTimeSeries(tsRes)
        }
      } catch (err: unknown) {
        if (!cancelled) {
          const message =
            err instanceof Error && err.message ? err.message : 'Fehler beim Laden des Admin-Dashboards'
          setError(message)
        }
      } finally {
        if (!cancelled) {
          setLoading(false)
        }
      }
    }

    void load()

    return () => {
      cancelled = true
    }
  }, [bucket, windowDays])

  if (loading && !summary) {
    return (
      <div className="admin-page">
        <p className="dashboard-status-msg">Admin-Dashboard wird geladen…</p>
      </div>
    )
  }

  if (error) {
    return (
      <div className="admin-page">
        <header className="admin-header">
          <button type="button" className="btn-back" onClick={onBack}>
            <ChevronLeft size={16} />
            Zur App
          </button>
        </header>
        <p className="dashboard-status-msg">{error}</p>
      </div>
    )
  }

  if (!summary) {
    return (
      <div className="admin-page">
        <p className="dashboard-status-msg">Keine Admin-Daten verfügbar.</p>
      </div>
    )
  }

  return (
    <div className="admin-page">
      <header className="admin-header">
        <div className="admin-header-left">
          <button type="button" className="btn-back" onClick={onBack}>
            <ChevronLeft size={16} />
            Zur App
          </button>
          <div>
            <h1 className="admin-title">Admin-Dashboard</h1>
            <p className="admin-subtitle">
              Übersicht über Nutzung und Wachstum von Kapteins Daagbok.
            </p>
          </div>
        </div>
      </header>

      <main className="admin-main">
        <section className="stats-kpi-grid admin-kpi-grid">
          <KpiCard icon={<Users size={20} />} label="Registrierte Benutzer" value={summary.totalUsers} />
          <KpiCard icon={<Bookmark size={20} />} label="Logbücher" value={summary.totalLogbooks} />
          <KpiCard icon={<Image size={20} />} label="Fotos" value={summary.totalPhotos} />
          <KpiCard icon={<Mic size={20} />} label="Sprachmemos" value={summary.totalVoiceMemos} />
          <KpiCard icon={<MapPin size={20} />} label="GPS-Tracks" value={summary.totalGpsTracks} />
          <KpiCard
            icon={<BarChart2 size={20} />}
            label="Einträge mit AI-Zusammenfassung"
            value={summary.aiSummaryEntries}
          />
          <KpiCard icon={<Database size={20} />} label="Datenbankgröße" value={formatBytes(summary.dbSize)} />
        </section>

        <section className="admin-controls">
          <div className="admin-control-group">
            <span className="admin-control-label">Zeitraum</span>
            <div className="admin-control-buttons">
              {[30, 90, 365].map((days) => (
                <button
                  key={days}
                  type="button"
                  className={days === windowDays ? 'btn primary' : 'btn secondary'}
                  onClick={() => setWindowDays(days)}
                >
                  {days} Tage
                </button>
              ))}
            </div>
          </div>
          <div className="admin-control-group">
            <span className="admin-control-label">Aggregation</span>
            <div className="admin-control-buttons">
              {(['day', 'week', 'month'] as AdminTimeBucket[]).map((b) => (
                <button
                  key={b}
                  type="button"
                  className={b === bucket ? 'btn primary' : 'btn secondary'}
                  onClick={() => setBucket(b)}
                >
                  {b === 'day' ? 'Tag' : b === 'week' ? 'Woche' : 'Monat'}
                </button>
              ))}
            </div>
          </div>
        </section>

        <section className="admin-charts-grid">
          <TimeSeriesChart title="Neue Benutzer" seriesKey="users_created" data={timeSeries} />
          <TimeSeriesChart title="Neue Logbücher" seriesKey="logbooks_created" data={timeSeries} />
          <TimeSeriesChart title="Foto-Aktivität" seriesKey="photos_updated" data={timeSeries} />
          <TimeSeriesChart title="Datenbankgröße (MB)" seriesKey="database_size" data={timeSeries} />
        </section>
      </main>
    </div>
  )
}
