/* eslint-disable @next/next/no-img-element */
"use client";

import { useRef, useState } from "react";
import {
  AlertTriangle, Check, Copy, Download, Globe, Image as ImageIcon,
  Moon, Search, Sun, Upload, X,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";

type Check = { id: string; label: string; status: "pass" | "warn" | "fail"; msg: string; fix?: string };
type IconRow = {
  rel: string; kind: string; href: string; declaredSizes: string; declaredType: string;
  source: string; w: number; h: number; bytes: number; reachable: boolean; square: boolean | null; imgType: string;
};
type PreviewData = { tab: string | null; apple: string | null; android: string | null; title: string; appName: string; host: string };
type Probe = {
  ok: boolean; message?: string;
  site: { origin: string };
  icons: IconRow[];
  checks: Check[];
  score: number;
  preview: PreviewData;
  recommendedHead: string;
};

const EXAMPLES = ["github.com", "stripe.com", "toolaro.org"];
const PACK_SIZES = [16, 32, 48, 180, 192, 512];

export function FaviconTester() {
  const [mode, setMode] = useState<"url" | "upload">("url");

  return (
    <div className="space-y-6">
      <div className="flex flex-wrap gap-2">
        <button onClick={() => setMode("url")} className={tab(mode === "url")}>
          <Globe className="mr-1.5 inline h-4 w-4" /> Website prüfen
        </button>
        <button onClick={() => setMode("upload")} className={tab(mode === "upload")}>
          <Upload className="mr-1.5 inline h-4 w-4" /> Eigenes Bild testen
        </button>
      </div>

      {mode === "url" ? <UrlMode /> : <UploadMode />}
    </div>
  );
}

/* ------------------------------------------------------------------ URL mode */

function UrlMode() {
  const [url, setUrl] = useState("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [data, setData] = useState<Probe | null>(null);

  async function run(target?: string) {
    const q = (target ?? url).trim();
    if (!q) { setError("Bitte eine Adresse eingeben."); return; }
    if (target) setUrl(target);
    setLoading(true);
    setError(null);
    try {
      const res = await fetch("/api/tools/favicon-tester", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ url: q }),
      });
      const json = (await res.json()) as Probe;
      if (!json.ok) { setError(json.message ?? "Prüfung fehlgeschlagen."); setData(null); }
      else setData(json);
    } catch {
      setError("Verbindungsfehler. Bitte erneut versuchen.");
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="space-y-6">
      <div className="space-y-3">
        <div className="flex flex-col gap-2 sm:flex-row">
          <Input
            value={url}
            onChange={(e) => setUrl(e.target.value)}
            onKeyDown={(e) => e.key === "Enter" && run()}
            placeholder="z. B. github.com"
            inputMode="url"
            spellCheck={false}
            className="flex-1"
          />
          <Button onClick={() => run()} disabled={loading} className="shrink-0">
            {loading ? <span className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-white/40 border-t-white" /> : <Search className="mr-2 h-4 w-4" />}
            Prüfen
          </Button>
        </div>
        <div className="flex flex-wrap items-center gap-2 text-sm text-gray-500">
          <span className="font-medium">Beispiele:</span>
          {EXAMPLES.map((e) => (
            <button key={e} onClick={() => run(e)} className="rounded-full border border-gray-200 px-3 py-1 text-xs font-medium text-gray-600 transition-colors hover:bg-gray-50">{e}</button>
          ))}
        </div>
        {error && <p className="text-sm font-medium text-red-600">{error}</p>}
        <p className="text-xs leading-relaxed text-gray-500">
          Wir laden nur die öffentliche Startseite und ihre Icon-Dateien. Nichts wird gespeichert. Interne/lokale Adressen sind aus Sicherheitsgründen blockiert.
        </p>
      </div>

      {data && (
        <div className="space-y-6">
          <Scorecard score={data.score} host={data.site.origin.replace(/^https?:\/\//, "")} count={data.icons.length} />
          <Section title="So sieht es überall aus"><Surfaces d={data.preview} /></Section>
          <Section title="Prüfung & Empfehlungen"><Checks checks={data.checks} /></Section>
          <Section title="Gefundene Icon-Dateien"><IconTable icons={data.icons} /></Section>
          <Section title="Empfohlener <head>-Code"><CodeBlock code={data.recommendedHead} /></Section>
        </div>
      )}
    </div>
  );
}

/* --------------------------------------------------------------- Upload mode */

function UploadMode() {
  const [src, setSrc] = useState<string | null>(null);
  const [pack, setPack] = useState<{ size: number; url: string; name: string }[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [drag, setDrag] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  function handleFile(file: File) {
    setError(null);
    if (!/^image\//.test(file.type) && !/\.(png|jpe?g|svg|webp)$/i.test(file.name)) {
      setError("Bitte ein Bild wählen (PNG, JPG, SVG oder WebP)."); return;
    }
    if (file.size > 8 * 1024 * 1024) { setError("Datei zu groß (max. 8 MB)."); return; }
    const reader = new FileReader();
    reader.onload = () => {
      const dataUrl = String(reader.result);
      const img = new Image();
      img.onload = () => build(img, dataUrl);
      img.onerror = () => setError("Bild konnte nicht gelesen werden.");
      img.src = dataUrl;
    };
    reader.readAsDataURL(file);
  }

  function build(img: HTMLImageElement, dataUrl: string) {
    setSrc(dataUrl);
    const out: { size: number; url: string; name: string }[] = [];
    for (const size of PACK_SIZES) {
      const canvas = document.createElement("canvas");
      canvas.width = canvas.height = size;
      const ctx = canvas.getContext("2d")!;
      const s = Math.min(img.width, img.height);
      ctx.imageSmoothingQuality = "high";
      ctx.drawImage(img, (img.width - s) / 2, (img.height - s) / 2, s, s, 0, 0, size, size);
      const name = size === 180 ? "apple-touch-icon.png" : size === 192 ? "icon-192.png" : size === 512 ? "icon-512.png" : `favicon-${size}x${size}.png`;
      out.push({ size, url: canvas.toDataURL("image/png"), name });
    }
    setPack(out);
  }

  const preview: PreviewData = { tab: src, apple: src, android: src, title: "Deine Website", appName: "Deine App", host: "deine-domain.de" };

  return (
    <div className="space-y-6">
      <div
        onClick={() => inputRef.current?.click()}
        onDragOver={(e) => { e.preventDefault(); setDrag(true); }}
        onDragLeave={() => setDrag(false)}
        onDrop={(e) => { e.preventDefault(); setDrag(false); const f = e.dataTransfer.files[0]; if (f) handleFile(f); }}
        className={`cursor-pointer rounded-xl border-2 border-dashed p-10 text-center transition-colors ${drag ? "border-blue-500 bg-blue-50" : "border-gray-300 hover:border-blue-400 hover:bg-gray-50"}`}
      >
        <Upload className="mx-auto mb-3 h-9 w-9 text-blue-600" />
        <p className="font-semibold text-gray-900">Bild hierher ziehen oder klicken</p>
        <p className="mt-1 text-sm text-gray-500">PNG, JPG, SVG oder WebP · am besten quadratisch, mind. 512×512</p>
        <input ref={inputRef} type="file" accept="image/png,image/jpeg,image/svg+xml,image/webp,.png,.jpg,.jpeg,.svg,.webp" hidden onChange={(e) => e.target.files?.[0] && handleFile(e.target.files[0])} />
      </div>
      {error && <p className="text-sm font-medium text-red-600">{error}</p>}

      {src && (
        <div className="space-y-6">
          <Section title="Live-Vorschau deines Icons"><Surfaces d={preview} /></Section>
          <Section title="Fertiger Favicon-Pack">
            <p className="mb-4 text-sm text-gray-500">Direkt im Browser erzeugt – nichts wird hochgeladen. Lade die Größen herunter, leg sie ins Web-Root und binde sie mit dem Code unten ein.</p>
            <div className="grid grid-cols-[repeat(auto-fill,minmax(96px,1fr))] gap-3">
              {pack.map((p) => (
                <div key={p.size} className="rounded-lg border border-gray-200 p-3 text-center">
                  <img src={p.url} alt={`${p.size}px`} className="mx-auto" style={{ width: Math.min(p.size, 56), height: Math.min(p.size, 56) }} />
                  <div className="mt-2 text-xs font-semibold text-gray-500">{p.size}×{p.size}</div>
                  <a href={p.url} download={p.name} className="mt-1.5 inline-flex items-center gap-1 text-xs font-semibold text-blue-600 hover:underline">
                    <Download className="h-3 w-3" /> {p.name.replace(/\.png$/, "")}
                  </a>
                </div>
              ))}
            </div>
          </Section>
          <Section title="<head>-Code zum Einbinden">
            <CodeBlock code={`<link rel="icon" href="/favicon.ico" sizes="any">\n<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">\n<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">\n<link rel="manifest" href="/site.webmanifest">\n<meta name="theme-color" content="#0f172a">`} />
          </Section>
        </div>
      )}
    </div>
  );
}

/* -------------------------------------------------------------- Sub-components */

function Section({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <div>
      <h3 className="mb-4 flex items-center gap-3 text-xs font-bold uppercase tracking-[0.14em] text-gray-500 after:h-px after:flex-1 after:bg-gray-200 after:content-['']">{title}</h3>
      {children}
    </div>
  );
}

function Scorecard({ score, host, count }: { score: number; host: string; count: number }) {
  const col = score >= 80 ? "#16a34a" : score >= 50 ? "#d97706" : "#dc2626";
  const verdict = score >= 80 ? "Stark – deine Icons sitzen." : score >= 50 ? "Solide, mit Luft nach oben." : "Da fehlt einiges.";
  return (
    <div className="flex flex-wrap items-center gap-5 rounded-xl border-2 border-ink-primary bg-surface-raised p-5 shadow-[6px_6px_0_rgb(var(--brand-500))]">
      <div className="relative h-24 w-24 shrink-0">
        <svg viewBox="0 0 36 36" className="h-24 w-24 -rotate-90">
          <circle cx="18" cy="18" r="15.9155" fill="none" stroke="#e5e7eb" strokeWidth="3.4" />
          <circle cx="18" cy="18" r="15.9155" fill="none" stroke={col} strokeWidth="3.4" strokeLinecap="round" strokeDasharray={`${score} 100`} className="transition-all duration-700" />
        </svg>
        <div className="absolute inset-0 flex flex-col items-center justify-center">
          <b className="text-2xl font-black leading-none" style={{ color: col }}>{score}</b>
          <small className="text-[0.6rem] font-bold uppercase tracking-wide text-gray-400">von 100</small>
        </div>
      </div>
      <div>
        <h3 className="text-lg font-black text-ink-primary">{verdict}</h3>
        <p className="text-sm text-gray-500">Geprüft: <span className="font-semibold text-ink-primary">{host}</span> · {count} Icon-Dateien gefunden</p>
      </div>
    </div>
  );
}

function Checks({ checks }: { checks: Check[] }) {
  return (
    <div className="grid gap-2.5">
      {checks.map((c) => {
        const tone = c.status === "pass" ? "bg-green-500" : c.status === "warn" ? "bg-amber-500" : "bg-red-500";
        const border = c.status === "pass" ? "border-green-200" : c.status === "fail" ? "border-red-200" : "border-gray-200";
        const Ico = c.status === "pass" ? Check : c.status === "warn" ? AlertTriangle : X;
        return (
          <div key={c.id} className={`grid grid-cols-[auto_1fr] items-start gap-3 rounded-lg border bg-white p-3.5 ${border}`}>
            <div className={`mt-0.5 flex h-6 w-6 items-center justify-center rounded-md text-white ${tone}`}><Ico className="h-3.5 w-3.5" strokeWidth={3} /></div>
            <div>
              <p className="text-sm font-bold text-gray-900">{c.label}</p>
              <p className="mt-0.5 text-sm leading-relaxed text-gray-500">{c.msg}</p>
              {c.fix && <div className="mt-2"><CodeBlock code={c.fix} small /></div>}
            </div>
          </div>
        );
      })}
    </div>
  );
}

function IconTable({ icons }: { icons: IconRow[] }) {
  return (
    <div className="overflow-x-auto">
      <table className="w-full border-collapse text-sm">
        <thead>
          <tr className="text-left text-[0.68rem] uppercase tracking-wide text-gray-400">
            <th className="border-b-2 border-gray-200 p-2.5"></th>
            <th className="border-b-2 border-gray-200 p-2.5">rel</th>
            <th className="border-b-2 border-gray-200 p-2.5">Maße</th>
            <th className="border-b-2 border-gray-200 p-2.5">Typ</th>
            <th className="border-b-2 border-gray-200 p-2.5">Größe</th>
            <th className="border-b-2 border-gray-200 p-2.5">Status</th>
          </tr>
        </thead>
        <tbody>
          {icons.map((i, idx) => {
            const dims = i.imgType === "svg" ? "Vektor" : i.w && i.h ? `${i.w}×${i.h}` : "—";
            const type = i.imgType ? i.imgType.toUpperCase() : i.declaredType || "—";
            const size = i.bytes ? (i.bytes < 1024 ? `${i.bytes} B` : `${(i.bytes / 1024).toFixed(1)} KB`) : "—";
            const relExtra = i.source === "implicit" ? " (auto)" : i.source === "manifest" ? " (manifest)" : "";
            return (
              <tr key={idx}>
                <td className="border-b border-gray-100 p-2.5"><FavImg src={i.reachable ? i.href : null} alt={i.rel} className="h-8 w-8 rounded-md border border-gray-200 bg-white object-cover" /></td>
                <td className="border-b border-gray-100 p-2.5"><span className="font-mono text-xs text-gray-800">{i.rel}</span><br /><span className="text-[0.7rem] text-gray-400">{i.declaredSizes || relExtra}</span></td>
                <td className="border-b border-gray-100 p-2.5 text-gray-700">{dims}</td>
                <td className="border-b border-gray-100 p-2.5 text-gray-700">{type}</td>
                <td className="border-b border-gray-100 p-2.5 text-gray-700">{size}</td>
                <td className="border-b border-gray-100 p-2.5">
                  {i.reachable
                    ? <span className="inline-block rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-bold text-green-700">OK</span>
                    : <span className="inline-block rounded-full bg-red-100 px-2.5 py-0.5 text-xs font-bold text-red-700">404</span>}
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

function CodeBlock({ code, small }: { code: string; small?: boolean }) {
  const [copied, setCopied] = useState(false);
  return (
    <div className="relative">
      <pre className={`overflow-x-auto whitespace-pre-wrap break-all rounded-lg bg-slate-900 py-3 pl-3.5 pr-11 font-mono text-slate-100 ${small ? "text-xs" : "text-[0.8rem] leading-relaxed"}`}>{code}</pre>
      <button
        onClick={() => { navigator.clipboard.writeText(code); setCopied(true); setTimeout(() => setCopied(false), 1400); }}
        className="absolute right-2 top-2 flex h-8 w-8 items-center justify-center rounded-md bg-white/10 text-slate-100 transition-colors hover:bg-blue-600"
        title="Kopieren"
      >
        {copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
      </button>
    </div>
  );
}

/* ---------------------------------------------------------------- Previews */

function FavImg({ src, alt, className }: { src: string | null; alt: string; className: string }) {
  const [failed, setFailed] = useState(false);
  const letter = (alt?.trim()?.[0] || "?").toUpperCase();
  if (!src || failed) {
    return <div className={`${className} flex items-center justify-center bg-gradient-to-br from-emerald-500 to-cyan-600 font-black text-white`}>{letter}</div>;
  }
  return <img src={src} alt={alt} loading="lazy" onError={() => setFailed(true)} className={className} />;
}

function SurfaceCard({ title, icon, children }: { title: string; icon: React.ReactNode; children: React.ReactNode; }) {
  return (
    <div className="overflow-hidden rounded-lg border border-gray-200 bg-white">
      <h4 className="flex items-center gap-1.5 border-b border-gray-200 px-3.5 py-2 text-[0.7rem] font-bold uppercase tracking-wide text-gray-500">{icon}{title}</h4>
      <div className="flex min-h-[118px] items-center justify-center p-4">{children}</div>
    </div>
  );
}

function Surfaces({ d }: { d: PreviewData }) {
  const tab = d.tab, apple = d.apple ?? d.tab, android = d.android ?? d.apple ?? d.tab;
  return (
    <div className="grid gap-4 md:grid-cols-2">
      <SurfaceCard title="Browser-Tab · Hell" icon={<Sun className="h-3.5 w-3.5" />}>
        <div className="w-full rounded-t-md bg-[#e8eaed] px-2 pt-2">
          <div className="flex max-w-[240px] items-center gap-2 rounded-t-lg bg-white px-3 py-2 text-[0.78rem] text-gray-800">
            <FavImg src={tab} alt={d.appName} className="h-4 w-4 rounded-sm object-cover" /><span className="flex-1 truncate">{d.title}</span><span className="opacity-40">×</span>
          </div>
          <div className="p-2"><div className="flex items-center gap-2 rounded-md bg-white px-3 py-1.5 text-[0.72rem] text-gray-500"><FavImg src={tab} alt={d.appName} className="h-3.5 w-3.5 rounded-sm object-cover" /><span>{d.host}</span></div></div>
        </div>
      </SurfaceCard>

      <SurfaceCard title="Browser-Tab · Dunkel" icon={<Moon className="h-3.5 w-3.5" />}>
        <div className="w-full rounded-t-md bg-[#2b2f36] px-2 pt-2">
          <div className="flex max-w-[240px] items-center gap-2 rounded-t-lg bg-[#3a3f47] px-3 py-2 text-[0.78rem] text-gray-100">
            <FavImg src={tab} alt={d.appName} className="h-4 w-4 rounded-sm object-cover" /><span className="flex-1 truncate">{d.title}</span><span className="opacity-40">×</span>
          </div>
          <div className="p-2"><div className="flex items-center gap-2 rounded-md bg-[#20242b] px-3 py-1.5 text-[0.72rem] text-gray-400"><FavImg src={tab} alt={d.appName} className="h-3.5 w-3.5 rounded-sm object-cover" /><span>{d.host}</span></div></div>
        </div>
      </SurfaceCard>

      <SurfaceCard title="iPhone · Homescreen" icon={<ImageIcon className="h-3.5 w-3.5" />}>
        <div className="flex min-h-[130px] w-full flex-col items-center justify-center gap-2 rounded-xl p-5" style={{ background: "linear-gradient(150deg,#f0d9ff 0%,#c6e0ff 55%,#a5f3e0 100%)" }}>
          <FavImg src={apple} alt={d.appName} className="h-16 w-16 rounded-[22.4%] object-cover shadow-lg" />
          <div className="max-w-[110px] truncate text-[0.78rem] font-semibold text-slate-900">{d.appName}</div>
        </div>
      </SurfaceCard>

      <SurfaceCard title="Android · Homescreen" icon={<ImageIcon className="h-3.5 w-3.5" />}>
        <div className="flex min-h-[130px] w-full flex-col items-center justify-center gap-2 rounded-xl p-5" style={{ background: "linear-gradient(150deg,#0b1220 0%,#1e293b 100%)" }}>
          <div className="flex items-start gap-6">
            <div className="flex flex-col items-center gap-1.5"><FavImg src={android} alt={d.appName} className="h-16 w-16 rounded-full object-cover shadow-lg" /><span className="text-[0.6rem] font-bold uppercase text-slate-400">Kreis</span></div>
            <div className="flex flex-col items-center gap-1.5"><FavImg src={android} alt={d.appName} className="h-16 w-16 rounded-[30%] object-cover shadow-lg" /><span className="text-[0.6rem] font-bold uppercase text-slate-400">Squircle</span></div>
          </div>
          <div className="max-w-[130px] truncate text-[0.78rem] font-semibold text-white">{d.appName}</div>
        </div>
      </SurfaceCard>

      <div className="md:col-span-2">
        <SurfaceCard title="Google-Suchergebnis" icon={<Search className="h-3.5 w-3.5" />}>
          <div className="w-full px-1 font-[arial,sans-serif]">
            <div className="mb-1.5 flex items-center gap-3">
              <FavImg src={tab} alt={d.appName} className="h-[26px] w-[26px] rounded-full border border-gray-200 bg-white object-cover p-0.5" />
              <div className="leading-tight">
                <div className="text-[0.82rem] text-[#202124]">{d.appName}</div>
                <div className="text-[0.72rem] text-[#4d5156]">https://{d.host}</div>
              </div>
            </div>
            <p className="text-[1.15rem] leading-snug text-[#1a0dab]">{d.title}</p>
            <p className="mt-1 text-[0.82rem] leading-relaxed text-[#4d5156]">So erscheint deine Seite in der Google-Suche – das Favicon steht direkt neben dem Domainnamen und ist oft der erste Marken-Eindruck.</p>
          </div>
        </SurfaceCard>
      </div>
    </div>
  );
}

function tab(active: boolean) {
  return `rounded-full px-4 py-2 text-sm font-semibold transition-colors ${active ? "bg-blue-600 text-white" : "border border-gray-200 text-gray-600 hover:bg-gray-50"}`;
}
