'use client';

import Link from 'next/link';
import { useCallback, useEffect, useState } from 'react';
import { ArrowLeft, Loader2, RefreshCw } from 'lucide-react';

type QueueJob = {
  id: string;
  status: string;
  attempts: number;
  lastError: string | null;
  messageId: string | null;
  scheduledAt: string;
  createdAt: string;
  sentAt: string | null;
  campaignId: string;
  campaignName: string;
  recipientEmail: string;
};

type QueueResponse = {
  jobs: QueueJob[];
  countsByStatus: Record<string, number>;
  limit: number;
  error?: string;
};

function statusPillClass(status: string): string {
  switch (status) {
    case 'sent':
      return 'bg-emerald-100 text-emerald-900 dark:bg-emerald-950/50 dark:text-emerald-200';
    case 'pending':
      return 'bg-amber-100 text-amber-900 dark:bg-amber-950/50 dark:text-amber-200';
    case 'sending':
      return 'bg-sky-100 text-sky-900 dark:bg-sky-950/50 dark:text-sky-200';
    case 'failed':
    case 'bounced':
      return 'bg-red-100 text-red-900 dark:bg-red-950/50 dark:text-red-200';
    default:
      return 'bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200';
  }
}

export default function QueuePage() {
  const [data, setData] = useState<QueueResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch('/api/sending/queue');
      const body = (await res.json()) as QueueResponse & { error?: string };
      if (!res.ok) {
        setError(body.error ?? `HTTP ${res.status}`);
        setData(null);
        return;
      }
      setData(body);
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Netzwerkfehler');
      setData(null);
    } finally {
      setLoading(false);
    }
  }, []);

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

  return (
    <div className="min-h-screen bg-zinc-50 text-zinc-900 dark:bg-zinc-950 dark:text-zinc-100">
      <div className="mx-auto max-w-6xl px-4 py-8">
        <div className="mb-6 flex flex-wrap items-center justify-between gap-3">
          <div className="flex items-center gap-3">
            <Link
              href="/"
              className="inline-flex items-center gap-1.5 rounded-md border border-zinc-200 bg-white px-2.5 py-1.5 text-sm font-medium text-zinc-700 shadow-sm hover:bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200 dark:hover:bg-zinc-800"
            >
              <ArrowLeft className="h-4 w-4" />
              Zurück zum Builder
            </Link>
            <h1 className="text-lg font-semibold">Sende-Warteschlange</h1>
          </div>
          <button
            type="button"
            onClick={() => void load()}
            disabled={loading}
            className="inline-flex items-center gap-2 rounded-md border border-zinc-200 bg-white px-3 py-1.5 text-sm font-medium text-zinc-700 shadow-sm hover:bg-zinc-50 disabled:opacity-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200 dark:hover:bg-zinc-800"
          >
            {loading ? <Loader2 className="h-4 w-4 animate-spin" /> : <RefreshCw className="h-4 w-4" />}
            Aktualisieren
          </button>
        </div>

        <div className="mb-6 rounded-lg border border-zinc-200 bg-white p-4 text-sm text-zinc-700 shadow-sm dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-300">
          <p className="font-medium text-zinc-900 dark:text-zinc-100">Worker</p>
          <p className="mt-1">
            Jobs mit Status <code className="rounded bg-zinc-100 px-1 py-0.5 text-xs dark:bg-zinc-800">pending</code>{' '}
            werden vom Send-Worker abgearbeitet. In Docker ist das typischerweise ein eigener Service (z.&nbsp;B.{' '}
            <code className="rounded bg-zinc-100 px-1 py-0.5 text-xs dark:bg-zinc-800">docker compose up worker</code>
            ). Lokal: <code className="rounded bg-zinc-100 px-1 py-0.5 text-xs dark:bg-zinc-800">npm run worker</code>.
            Die Web-App startet den Worker nicht selbst (kein Zugriff auf den Host-Prozess / Docker-Socket).
          </p>
        </div>

        {error && (
          <div className="mb-4 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-900 dark:border-red-900/50 dark:bg-red-950/40 dark:text-red-200">
            {error}
          </div>
        )}

        {data && Object.keys(data.countsByStatus).length > 0 && (
          <div className="mb-4 flex flex-wrap gap-2">
            {Object.entries(data.countsByStatus)
              .sort(([a], [b]) => a.localeCompare(b))
              .map(([status, n]) => (
                <span
                  key={status}
                  className={`inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium ${statusPillClass(status)}`}
                >
                  {status}
                  <span className="tabular-nums opacity-80">{n.toLocaleString('de-DE')}</span>
                </span>
              ))}
          </div>
        )}

        {loading && !data ? (
          <div className="flex items-center gap-2 text-sm text-zinc-500">
            <Loader2 className="h-4 w-4 animate-spin" />
            Lade Warteschlange …
          </div>
        ) : data?.jobs.length === 0 ? (
          <p className="text-sm text-zinc-500">Keine Jobs in den zugänglichen Workspaces.</p>
        ) : data ? (
          <div className="overflow-x-auto rounded-lg border border-zinc-200 bg-white shadow-sm dark:border-zinc-800 dark:bg-zinc-900">
            <table className="min-w-full divide-y divide-zinc-200 text-left text-xs dark:divide-zinc-800">
              <thead className="bg-zinc-50 dark:bg-zinc-950/80">
                <tr>
                  <th className="whitespace-nowrap px-3 py-2 font-semibold text-zinc-600 dark:text-zinc-400">Status</th>
                  <th className="whitespace-nowrap px-3 py-2 font-semibold text-zinc-600 dark:text-zinc-400">Kampagne</th>
                  <th className="whitespace-nowrap px-3 py-2 font-semibold text-zinc-600 dark:text-zinc-400">Empfänger</th>
                  <th className="whitespace-nowrap px-3 py-2 font-semibold text-zinc-600 dark:text-zinc-400">Versuche</th>
                  <th className="whitespace-nowrap px-3 py-2 font-semibold text-zinc-600 dark:text-zinc-400">Erstellt</th>
                  <th className="min-w-[120px] px-3 py-2 font-semibold text-zinc-600 dark:text-zinc-400">Fehler</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-zinc-100 dark:divide-zinc-800">
                {data.jobs.map((j) => (
                  <tr key={j.id} className="hover:bg-zinc-50/80 dark:hover:bg-zinc-800/40">
                    <td className="whitespace-nowrap px-3 py-2">
                      <span className={`rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase ${statusPillClass(j.status)}`}>
                        {j.status}
                      </span>
                    </td>
                    <td className="max-w-[200px] truncate px-3 py-2 font-medium text-zinc-800 dark:text-zinc-200" title={j.campaignName}>
                      {j.campaignName}
                    </td>
                    <td className="max-w-[220px] truncate px-3 py-2 text-zinc-600 dark:text-zinc-400" title={j.recipientEmail}>
                      {j.recipientEmail}
                    </td>
                    <td className="whitespace-nowrap px-3 py-2 tabular-nums text-zinc-600 dark:text-zinc-400">{j.attempts}</td>
                    <td className="whitespace-nowrap px-3 py-2 text-zinc-500 dark:text-zinc-500">
                      {new Date(j.createdAt).toLocaleString('de-DE')}
                    </td>
                    <td className="max-w-[280px] truncate px-3 py-2 text-red-700 dark:text-red-300" title={j.lastError ?? ''}>
                      {j.lastError ?? '—'}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
            <p className="border-t border-zinc-100 px-3 py-2 text-[10px] text-zinc-500 dark:border-zinc-800">
              Zeige bis zu {data.limit.toLocaleString('de-DE')} neueste Jobs (alle Workspaces deiner Session).
            </p>
          </div>
        ) : null}
      </div>
    </div>
  );
}
