import { useState } from 'react';
import { CheckCircle2, AlertTriangle, XCircle, RefreshCw, Cpu, FileText, HardDrive, Globe, Sparkles } from 'lucide-react';
import { Card, CardBody, CardHeader, CardTitle, CardDescription } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { Ring } from '@/components/ui/Progress';
import { Loading, ErrorState, Toast } from '@/components/ui/States';
import { api, type CheckCategory, type CheckStatus, type SystemCheck } from '@/lib/api';
import { useQuery } from '@/hooks/useQuery';
import { cn } from '@/lib/cn';

const CATEGORY_META: Record<CheckCategory, { label: string; icon: React.ComponentType<{ className?: string }>; description: string }> = {
  core:       { label: 'Core requirements', icon: Cpu,        description: 'Things the plugin needs to run at all.' },
  php:        { label: 'PHP runtime',       icon: FileText,   description: 'Tuning that affects how large a site you can back up.' },
  filesystem: { label: 'Filesystem',        icon: HardDrive,  description: 'Where backups are written.' },
  wordpress:  { label: 'WordPress',         icon: Globe,      description: 'Integration with WordPress core.' },
  optional:   { label: 'Optional features', icon: Sparkles,   description: 'Needed for specific destination types.' },
};

const STATUS_META: Record<CheckStatus, { icon: React.ComponentType<{ className?: string }>; color: string; tone: string; label: string }> = {
  pass: { icon: CheckCircle2,  color: 'text-emerald-500', tone: 'bg-emerald-50 text-emerald-700 ring-emerald-200', label: 'OK' },
  warn: { icon: AlertTriangle, color: 'text-amber-500',   tone: 'bg-amber-50 text-amber-800 ring-amber-200',       label: 'Warning' },
  fail: { icon: XCircle,       color: 'text-red-500',     tone: 'bg-red-50 text-red-700 ring-red-200',             label: 'Action needed' },
};

export function System() {
  const { data, isLoading, error, refetch } = useQuery(() => api.system.get(), []);
  const [toast, setToast] = useState<{ msg: string; tone: 'success' | 'danger' } | null>(null);

  if (isLoading) return <Loading label="Running system checks…" />;
  if (error)     return <ErrorState error={error} onRetry={refetch} />;
  if (!data)     return null;

  const { checks, summary } = data;
  const byCategory: Record<CheckCategory, SystemCheck[]> = {
    core: [], php: [], filesystem: [], wordpress: [], optional: [],
  };
  for (const c of checks) byCategory[c.category]?.push(c);

  // Health-card framing
  const ringTone = summary.fail > 0 ? 'danger' : (summary.warn > 0 ? 'warn' : 'ok');
  const ringColor = ringTone === 'danger' ? '#ef4444' : ringTone === 'warn' ? '#f59e0b' : '#1dd1a1';

  return (
    <div className="space-y-5 max-w-[1400px]">
      {/* Hero / score */}
      <Card>
        <CardBody className="flex flex-col sm:flex-row items-start sm:items-center gap-5">
          <div className="relative inline-flex items-center justify-center shrink-0">
            <svg width={108} height={108} className="-rotate-90">
              <circle cx={54} cy={54} r={50} stroke="#eef0f2" strokeWidth={8} fill="none" />
              <circle cx={54} cy={54} r={50} stroke={ringColor} strokeWidth={8} strokeLinecap="round" fill="none"
                strokeDasharray={2 * Math.PI * 50}
                strokeDashoffset={(2 * Math.PI * 50) - (summary.health_score / 100) * (2 * Math.PI * 50)}
              />
            </svg>
            <div className="absolute inset-0 flex flex-col items-center justify-center">
              <span className="text-2xl font-semibold text-ink-900">{summary.health_score}</span>
              <span className="text-[10px] uppercase tracking-wider text-ink-500">health</span>
            </div>
          </div>

          <div className="flex-1 min-w-0">
            <h2 className="text-base font-semibold text-ink-900">System requirements</h2>
            <p className="text-sm text-ink-500 mt-0.5">
              {summary.fail > 0
                ? `${summary.fail} blocker${summary.fail > 1 ? 's' : ''}. Fix these before relying on the plugin.`
                : summary.warn > 0
                  ? `${summary.warn} warning${summary.warn > 1 ? 's' : ''}. Non-blocking, but worth knowing about.`
                  : 'Everything looks healthy. Your host is well-suited for Backreload.'}
            </p>
            <div className="flex items-center gap-2 mt-3 flex-wrap">
              <StatPill count={summary.pass} status="pass" />
              <StatPill count={summary.warn} status="warn" />
              <StatPill count={summary.fail} status="fail" />
              <span className="text-xs text-ink-500 ml-1">of {summary.total} checks</span>
            </div>
          </div>

          <div className="flex flex-col sm:flex-row gap-2 shrink-0">
            <Button
              variant="ghost"
              size="sm"
              title="Force PHP opcache + WP object cache to reload. Useful on shared hosting where you can't restart PHP-FPM. Click this after the plugin updates to make sure the new code is actually running."
              onClick={async () => {
                try {
                  const r = await api.system.refreshCache();
                  // Build a short, single-line summary so it fits the toast.
                  // Fallback "n/a" covers hosts without WP object cache.
                  setToast({
                    msg: `PHP cache: ${r.opcache} · WP object cache: ${r.wp_cache ?? 'n/a'}`,
                    tone: 'success',
                  });
                  refetch();
                } catch (e: any) {
                  setToast({ msg: `Cache refresh failed: ${e?.message ?? String(e)}`, tone: 'danger' });
                }
              }}
            >
              Refresh PHP cache
            </Button>
            <Button variant="secondary" leftIcon={<RefreshCw className="h-4 w-4" />} onClick={refetch}>
              Re-run checks
            </Button>
          </div>
        </CardBody>
      </Card>

      {/* Groups */}
      {(Object.keys(byCategory) as CheckCategory[]).map((cat) => {
        const items = byCategory[cat];
        if (items.length === 0) return null;
        const meta = CATEGORY_META[cat];
        const Icon = meta.icon;
        return (
          <Card key={cat}>
            <CardHeader>
              <div className="flex items-center gap-3">
                <span className="h-8 w-8 grid place-items-center rounded-lg bg-ink-100 text-ink-700">
                  <Icon className="h-4 w-4" />
                </span>
                <div>
                  <CardTitle>{meta.label}</CardTitle>
                  <CardDescription>{meta.description}</CardDescription>
                </div>
              </div>
            </CardHeader>
            <CardBody className="p-0">
              <ul>
                {items.map((c, i) => (
                  <CheckRow key={c.id} check={c} isLast={i === items.length - 1} />
                ))}
              </ul>
            </CardBody>
          </Card>
        );
      })}

      {toast && <Toast message={toast.msg} tone={toast.tone} onClose={() => setToast(null)} />}
    </div>
  );
}

function StatPill({ count, status }: { count: number; status: CheckStatus }) {
  const meta = STATUS_META[status];
  const Icon = meta.icon;
  return (
    <span className={cn('inline-flex items-center gap-1.5 px-2 py-1 text-xs font-medium rounded-md ring-1 ring-inset', meta.tone)}>
      <Icon className="h-3.5 w-3.5" />
      {count} {status === 'pass' ? 'passing' : status === 'warn' ? 'warnings' : 'failures'}
    </span>
  );
}

function CheckRow({ check, isLast }: { check: SystemCheck; isLast: boolean }) {
  const meta = STATUS_META[check.status];
  const Icon = meta.icon;
  return (
    <li className={cn('px-5 py-3.5 flex items-start gap-3', !isLast && 'border-b border-ink-100')}>
      <Icon className={cn('h-5 w-5 mt-0.5 shrink-0', meta.color)} />
      <div className="flex-1 min-w-0">
        <div className="flex items-start sm:items-center gap-2 sm:gap-3 flex-col sm:flex-row">
          <p className="text-sm font-medium text-ink-900">{check.label}</p>
          <span className="text-xs text-ink-700 font-mono break-all">{check.value}</span>
        </div>
        <p className="text-xs text-ink-500 mt-1">{check.requirement}</p>
        {check.help && (
          <p className="text-xs text-ink-600 mt-1.5 bg-ink-50 border border-ink-100 rounded-md px-2.5 py-1.5">
            {check.help}
          </p>
        )}
      </div>
    </li>
  );
}
