import React, { useState, useEffect, useCallback } from 'react';
import { Link } from 'react-router-dom';
import { RefreshCw } from 'lucide-react';
import { toast } from 'sonner';
import { api } from '@/api';
import { cn, fmtUptime, fmtBytes } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { MarkdownText } from '@/components/MarkdownText';

// ─── Skeleton Card ────────────────────────────────────────────────────────────

function SkeletonCard() {
  return (
    <div className="bg-card rounded-xl border border-border shadow-sm p-6 animate-pulse">
      <div className="flex items-center justify-between mb-4">
        <div className="h-3 w-20 bg-muted rounded" />
        <div className="h-3 w-12 bg-muted rounded" />
      </div>
      <div className="space-y-3">
        {[1, 2, 3].map((i) => (
          <div key={i} className="flex items-center justify-between py-2 border-b border-border/50 last:border-0">
            <div className="h-3 w-24 bg-muted rounded" />
            <div className="h-3 w-16 bg-muted rounded" />
          </div>
        ))}
      </div>
    </div>
  );
}

// ─── Stat Row ─────────────────────────────────────────────────────────────────

function StatRow({ label, value, last }) {
  return (
    <div className={cn(
      'flex items-center justify-between py-2',
      !last && 'border-b border-border/50',
    )}>
      <span className="text-sm text-muted-foreground">{label}</span>
      <span className="text-sm font-medium tabular-nums">{value ?? '—'}</span>
    </div>
  );
}

function formatMemory(runtime) {
  if (runtime.memory_used_bytes ?? runtime.memory?.used ?? runtime.memory) {
    return fmtBytes(runtime.memory_used_bytes ?? runtime.memory?.used ?? runtime.memory);
  }
  if (runtime.memory_mb) return `${runtime.memory_mb} MB`;
  return null;
}

function formatBytesMaybe(value) {
  return value === undefined || value === null ? null : fmtBytes(value);
}

function formatDateTime(value) {
  if (!value) return null;
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return date.toLocaleString();
}

function StatusPill({ tone = 'muted', children }) {
  const cls = {
    good: 'bg-emerald-500/10 text-emerald-500 border-emerald-500/25',
    warn: 'bg-amber-500/10 text-amber-500 border-amber-500/25',
    bad: 'bg-red-500/10 text-red-500 border-red-500/25',
    muted: 'bg-muted text-muted-foreground border-border',
  }[tone];

  return (
    <span className={cn(
      'inline-flex items-center rounded-full border px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide',
      cls,
    )}>
      {children}
    </span>
  );
}

function StatusCard({ title, status, tone = 'muted', children }) {
  return (
    <div className="bg-card rounded-xl border border-border shadow-sm p-6">
      <div className="flex items-center justify-between gap-3 mb-4">
        <h3 className="text-xs font-bold uppercase tracking-widest text-muted-foreground">{title}</h3>
        {status && <StatusPill tone={tone}>{status}</StatusPill>}
      </div>
      <div className="space-y-0">{children}</div>
    </div>
  );
}

const CATEGORY_ORDER = ['Added', 'Changed', 'Fixed', 'Removed', 'Deprecated', 'Security'];

// ─── Release Notes Section ────────────────────────────────────────────────────

function ReleaseNotesSection({ version, historyMeta }) {
  if (!version) {
    return (
      <div className="mt-4">
        <div className="h-28 rounded-lg bg-muted/50 animate-pulse" />
      </div>
    );
  }

  // Group notes by category, preserving CATEGORY_ORDER priority
  const grouped = CATEGORY_ORDER.reduce((acc, cat) => {
    const notes = version.notes?.filter((n) => n.category === cat) ?? [];
    if (notes.length) acc[cat] = notes;
    return acc;
  }, {});

  // Catch any categories not in CATEGORY_ORDER
  version.notes?.forEach((n) => {
    if (!grouped[n.category]) {
      grouped[n.category] = [...(grouped[n.category] ?? []), n];
    }
  });

  const categories = Object.keys(grouped);

  const preview = categories.length ? grouped[categories[0]]?.[0]?.text : null;

  return (
    <StatusCard title="Release Notes" status={`v${version.version}`} tone="good">
      <StatRow label="Latest Release" value={categories[0] ?? null} />
      <StatRow label="Last Updated" value={formatDateTime(historyMeta?.updated_at)} />
      <div className="py-2 border-b border-border/50">
        <p className="text-sm text-muted-foreground">Preview</p>
        <p className="text-sm font-medium mt-1">
          <MarkdownText text={preview ?? 'No release notes available.'} />
        </p>
      </div>
      <div className="pt-3">
        <Button asChild variant="outline" size="sm">
          <Link to="/release-notes">View Full Release Notes</Link>
        </Button>
      </div>
    </StatusCard>
  );
}

// ─── StatusPage ───────────────────────────────────────────────────────────────

export default function StatusPage() {
  const [data, setData]         = useState(null);
  const [version, setVersion]   = useState(null);
  const [historyMeta, setHistoryMeta] = useState(null);
  const [loading, setLoading]   = useState(true);

  const load = useCallback(async () => {
    setLoading(true);
    setVersion(null);
    setHistoryMeta(null);
    try {
      const [statusData, versionData] = await Promise.all([
        api.status(),
        api.version(),
      ]);
      setData(statusData);
      setVersion(versionData);
      try {
        const historyData = await api.releaseHistory();
        setHistoryMeta({
          version: historyData.version,
          updated_at: historyData.updated_at,
        });
      } catch {
        setHistoryMeta(null);
      }
    } catch (err) {
      toast.error(err.message || 'Failed to load status.');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { load(); }, [load]);

  // Flatten nested status shape gracefully
  const app   = data?.application  ?? data?.app  ?? {};
  const rt    = data?.runtime      ?? {};
  const db    = data?.database     ?? data?.db   ?? {};
  const stats = data?.statistics   ?? data?.stats ?? {};
  const worker = data?.worker ?? data?.jobs ?? {};
  const notifications = data?.notifications ?? data?.email ?? {};
  const backups = data?.backups ?? data?.backup ?? {};
  const server = data?.server ?? data?.clock ?? {};
  const tracker = data?.tracker ?? data?.tracker_health ?? {};
  const cleanup = data?.cleanup ?? {};
  const errors = data?.errors ?? data?.recent_errors ?? [];

  const dbOk = db.connected ?? (db.status === 'connected') ?? true;
  const workerOk = worker.running ?? worker.enabled ?? null;
  const notificationsConfigured = notifications.configured ?? notifications.smtp_configured ?? null;
  const backupsEnabled = backups.enabled ?? null;
  const recentErrors = Array.isArray(errors) ? errors : [];

  return (
    <div>

      {/* Page header — flat on background */}
      <div className="flex flex-col gap-3 mb-8 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h1 className="text-2xl font-bold tracking-tight">Server Status</h1>
          <p className="text-sm text-muted-foreground mt-0.5">
            {data ? 'All systems operational' : 'Loading…'}
          </p>
        </div>
        <Button variant="outline" size="sm" onClick={load} disabled={loading}>
          <RefreshCw className={cn('h-3.5 w-3.5 mr-1.5', loading && 'animate-spin')} />
          Refresh
        </Button>
      </div>

      {/* 2x2 grid of stat cards */}
      {loading ? (
        <div className="grid gap-4 mb-6 md:grid-cols-2">
          <SkeletonCard />
          <SkeletonCard />
          <SkeletonCard />
          <SkeletonCard />
        </div>
      ) : (
        <div className="grid gap-4 mb-6 md:grid-cols-2">

          {/* Application */}
          <StatusCard title="Application" status="Online" tone="good">
            <StatRow label="Version"     value={(app.version ?? data?.version) ? `v${app.version ?? data?.version}` : null} />
            <StatRow label="Environment" value={app.environment ?? app.env ?? data?.environment ?? data?.env} />
            <StatRow
              label="Uptime"
              value={fmtUptime(app.uptime_seconds ?? app.uptime ?? data?.uptime_seconds ?? 0)}
              last
            />
          </StatusCard>

          {/* Runtime */}
          <StatusCard title="Runtime">
            <StatRow label="Node.js"  value={rt.node_version ?? rt.node ?? data?.node_version} />
            <StatRow label="Platform" value={rt.platform ?? data?.platform} />
            <StatRow label="Architecture" value={rt.arch ?? data?.arch} />
            <StatRow label="Memory" value={formatMemory(rt)} last />
          </StatusCard>

          {/* Database */}
          <StatusCard title="Database" status={dbOk ? 'Connected' : 'Error'} tone={dbOk ? 'good' : 'bad'}>
            <StatRow label="Size" value={formatBytesMaybe(db.size_bytes ?? db.size)} />
            <StatRow label="Last Modified" value={formatDateTime(db.last_modified ?? db.modified_at)} />
            <StatRow label="Free Disk" value={formatBytesMaybe(db.free_disk_bytes ?? db.disk_free_bytes)} />
            <div className="flex items-start justify-between py-2">
              <span className="text-sm text-muted-foreground">File path</span>
              <code className="text-xs bg-muted px-1.5 py-0.5 rounded font-mono max-w-[55%] break-all text-right">
                {db.file ?? db.path ?? db.filename ?? '—'}
              </code>
            </div>
          </StatusCard>

          {/* Statistics */}
          <StatusCard title="Statistics">
            <StatRow label="Active Bills"    value={stats.active_bills ?? stats.bills ?? stats.active_bill_count} />
            <StatRow label="Total Payments"  value={stats.total_payments ?? stats.payments} />
            <StatRow label="Users"           value={stats.users ?? stats.user_count} />
            <StatRow label="Sessions"        value={stats.active_sessions ?? stats.sessions} last />
          </StatusCard>

        </div>
      )}

      {!loading && (
        <>
          <div className="mb-3">
            <h2 className="text-xs font-bold uppercase tracking-widest text-muted-foreground">
              Operations
            </h2>
          </div>

          <div className="grid gap-4 mb-6 md:grid-cols-2 xl:grid-cols-3">
            <StatusCard
              title="Daily Worker"
              status={workerOk === null ? 'Pending' : workerOk ? 'Running' : 'Stopped'}
              tone={workerOk === null ? 'muted' : workerOk ? 'good' : 'bad'}
            >
              <StatRow label="Enabled" value={worker.enabled === undefined ? null : worker.enabled ? 'Yes' : 'No'} />
              <StatRow label="Last Run" value={formatDateTime(worker.last_run_at ?? worker.last_success_at)} />
              <StatRow label="Next Run" value={formatDateTime(worker.next_run_at)} />
              <StatRow label="Last Error" value={worker.last_error} last />
            </StatusCard>

            <StatusCard
              title="Notifications"
              status={notificationsConfigured === null ? 'Pending' : notificationsConfigured ? 'Configured' : 'Missing'}
              tone={notificationsConfigured === null ? 'muted' : notificationsConfigured ? 'good' : 'warn'}
            >
              <StatRow label="Enabled" value={notifications.enabled === undefined ? null : notifications.enabled ? 'Yes' : 'No'} />
              <StatRow label="SMTP" value={notificationsConfigured === undefined || notificationsConfigured === null ? null : notificationsConfigured ? 'Configured' : 'Not configured'} />
              <StatRow label="Last Sent" value={formatDateTime(notifications.last_sent_at)} />
              <StatRow label="Failures" value={notifications.failures ?? notifications.failed_count} last />
            </StatusCard>

            <StatusCard
              title="Backups"
              status={backupsEnabled === null ? 'Pending' : backupsEnabled ? 'Enabled' : 'Disabled'}
              tone={backupsEnabled === null ? 'muted' : backupsEnabled ? 'good' : 'warn'}
            >
              <StatRow label="Last Backup" value={formatDateTime(backups.last_backup_at)} />
              <StatRow label="Backup Count" value={backups.count ?? backups.backup_count} />
              <StatRow label="Retention" value={backups.keep_count ?? backups.retention_count} />
              <StatRow label="Last Error" value={backups.last_error} last />
            </StatusCard>

            <StatusCard
              title="Maintenance"
              status={cleanup.last_run_at ? 'OK' : 'Pending'}
              tone={cleanup.last_run_at ? 'good' : 'muted'}
            >
              <StatRow label="Last Run" value={formatDateTime(cleanup.last_run_at)} />
              <StatRow
                label="Import Sessions"
                value={cleanup.last_result?.import_sessions?.pruned != null
                  ? `${cleanup.last_result.import_sessions.pruned} pruned`
                  : null}
              />
              <StatRow
                label="Temp Export Files"
                value={cleanup.last_result?.temp_export_files?.removed != null
                  ? `${cleanup.last_result.temp_export_files.removed} removed`
                  : null}
              />
              <StatRow
                label="Backup Partials"
                value={cleanup.last_result?.backup_partials?.removed != null
                  ? `${cleanup.last_result.backup_partials.removed} removed`
                  : null}
                last
              />
            </StatusCard>

            <StatusCard title="Server Clock">
              <StatRow label="Server Time" value={formatDateTime(server.now ?? data?.server_time)} />
              <StatRow label="Server Date" value={server.today ?? data?.today} />
              <StatRow label="Timezone" value={server.timezone ?? data?.timezone} />
              <StatRow label="UTC Offset" value={server.utc_offset} last />
            </StatusCard>

            <StatusCard title="Tracker Health">
              <StatRow label="Bills This Month" value={tracker.bills_this_month} />
              <StatRow label="Payments This Month" value={tracker.payments_this_month} />
              <StatRow label="Overdue" value={tracker.overdue_count} />
              <StatRow label="Skipped" value={tracker.skipped_count} last />
            </StatusCard>

            <StatusCard
              title="Recent Errors"
              status={recentErrors.length ? `${recentErrors.length} Open` : 'None'}
              tone={recentErrors.length ? 'bad' : 'good'}
            >
              {recentErrors.length ? (
                recentErrors.slice(0, 4).map((err, index) => (
                  <div
                    key={`${err.timestamp ?? err.message ?? index}`}
                    className={cn(
                      'py-2',
                      index !== Math.min(recentErrors.length, 4) - 1 && 'border-b border-border/50',
                    )}
                  >
                    <p className="text-sm font-medium leading-tight">{err.source ?? err.type ?? 'Application'}</p>
                    <p className="text-xs text-muted-foreground mt-0.5 line-clamp-2">
                      {err.message ?? String(err)}
                    </p>
                  </div>
                ))
              ) : (
                <>
                  <StatRow label="Last Error" value={null} />
                  <StatRow label="Open Incidents" value="0" last />
                </>
              )}
            </StatusCard>
          </div>
        </>
      )}

      {/* Release Notes */}
      <ReleaseNotesSection version={version} historyMeta={historyMeta} />

    </div>
  );
}
