"use client";

import { use, useEffect, useRef, useState } from "react";
import Link from "next/link";
import {
  getMail,
  getThread,
  downloadMailAttachment,
  downloadMailRaw,
  downloadMailOCRText,
  exportMailPDF,
  type MailDetail,
  type MailAttachment,
  type ThreadMail,
} from "@/lib/api";
import { useAuth } from "@/hooks/useAuth";
import { Navbar } from "@/components/navbar";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import { Skeleton } from "@/components/ui/skeleton";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { OcrBadge } from "@/components/ocr-badge";
import { FileText } from "lucide-react";

// ── Helpers ────────────────────────────────────────────────────────────────

function formatBytes(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

function formatDate(iso: string): string {
  try {
    return new Date(iso).toLocaleString("de-DE", {
      day: "2-digit",
      month: "2-digit",
      year: "numeric",
      hour: "2-digit",
      minute: "2-digit",
    });
  } catch {
    return iso;
  }
}

// PROJ-51: human-readable label for the retain_until_source marker.
function retentionSourceLabel(source: string): string {
  if (source.startsWith("rule:")) {
    return `Archivierungsregel #${source.slice(5)}`;
  }
  switch (source) {
    case "tenant_default":
      return "Mandanten-Standard";
    case "global_default":
      return "Globaler Standard";
    case "min_retention":
      return "Globale Mindestfrist";
    default:
      return source;
  }
}

function triggerDownload(blob: Blob, filename: string) {
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  a.click();
  URL.revokeObjectURL(url);
}

function blockExternalSrcs(html: string): string {
  // Replace src= in img/video/audio tags with data-src= to block loading
  return html
    .replace(/<(img|video|audio|source)(\s[^>]*?\s)src(\s*=\s*["']https?:)/gi,
      "<$1$2data-src$3")
    .replace(/<(img|video|audio|source)(\s)src(\s*=\s*["']https?:)/gi,
      "<$1$2data-src$3");
}

// ── Sub-components ─────────────────────────────────────────────────────────

function MailHeaderGrid({ mail }: { mail: MailDetail }) {
  const [showRaw, setShowRaw] = useState(false);

  return (
    <div className="space-y-3">
      <div className="grid grid-cols-[6rem_1fr] gap-x-4 gap-y-1.5 text-sm">
        <span className="font-medium text-muted-foreground">Von:</span>
        <span className="break-all">{mail.from || "–"}</span>
        <span className="font-medium text-muted-foreground">An:</span>
        <span className="break-all">{mail.to || "–"}</span>
        {mail.cc && (
          <>
            <span className="font-medium text-muted-foreground">CC:</span>
            <span className="break-all">{mail.cc}</span>
          </>
        )}
        <span className="font-medium text-muted-foreground">Datum:</span>
        <span>{formatDate(mail.date)}</span>
        <span className="font-medium text-muted-foreground">Betreff:</span>
        <span className="font-semibold">{mail.subject || "(kein Betreff)"}</span>
        <span className="font-medium text-muted-foreground">Größe:</span>
        <span>{formatBytes(mail.size)}</span>
        {/* Verification status */}
        <span className="font-medium text-muted-foreground">Integrität:</span>
        <span className="flex flex-wrap items-center gap-2">
          {mail.verify_ok === true ? (
            <span className="inline-flex items-center gap-1 text-green-600 text-sm font-medium">
              <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
              </svg>
              Verifiziert
            </span>
          ) : mail.verify_ok === false ? (
            <span className="inline-flex items-center gap-1 text-red-600 text-sm font-medium">
              <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
              </svg>
              Manipuliert!
            </span>
          ) : (
            <span className="inline-flex items-center gap-1 text-muted-foreground text-sm">
              <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
              </svg>
              Noch nicht geprüft
            </span>
          )}
          <OcrBadge status={mail.ocr_status} />
        </span>
        {/* PROJ-51: retention lock + source for auditor traceability */}
        {mail.retain_until && (
          <>
            <span className="font-medium text-muted-foreground">Aufbewahrung:</span>
            <span className="flex flex-wrap items-center gap-2 text-sm">
              <span>bis {formatDate(mail.retain_until)}</span>
              {mail.retain_until_source && (
                <Badge variant="secondary">
                  {retentionSourceLabel(mail.retain_until_source)}
                </Badge>
              )}
            </span>
          </>
        )}
      </div>

      <button
        onClick={() => setShowRaw((v) => !v)}
        className="text-xs text-muted-foreground hover:text-foreground underline underline-offset-2"
      >
        {showRaw ? "Header ausblenden" : "Original-Header anzeigen"}
      </button>

      {showRaw && (
        <pre className="mt-2 max-h-60 overflow-auto rounded-md bg-muted p-3 text-xs leading-relaxed whitespace-pre-wrap break-all">
          {mail.raw_headers}
        </pre>
      )}
    </div>
  );
}

function MailBodyView({ mail }: { mail: MailDetail }) {
  const iframeRef = useRef<HTMLIFrameElement>(null);
  const [showExternal, setShowExternal] = useState(false);

  const html = mail.body_html ?? null;
  const plain = mail.body_plain ?? null;

  // Adjust iframe height to content
  function handleIframeLoad() {
    const iframe = iframeRef.current;
    if (!iframe) return;
    try {
      const body = iframe.contentDocument?.body;
      if (body) {
        iframe.style.height = `${body.scrollHeight + 32}px`;
      }
    } catch {
      iframe.style.height = "600px";
    }
  }

  if (!html && !plain) {
    return (
      <div className="rounded-md border border-dashed p-8 text-center text-sm text-muted-foreground">
        Kein Inhalt vorhanden.
      </div>
    );
  }

  if (html) {
    const srcdoc = showExternal ? html : blockExternalSrcs(html);
    return (
      <div className="space-y-2">
        {!showExternal && (
          <Alert>
            <AlertDescription className="flex flex-col items-start gap-2 text-sm sm:flex-row sm:items-center sm:justify-between sm:gap-4">
              <span>Externe Inhalte (Bilder, Tracker) sind blockiert.</span>
              <Button
                variant="outline"
                size="sm"
                className="w-full sm:w-auto"
                onClick={() => setShowExternal(true)}
              >
                Externe Inhalte laden
              </Button>
            </AlertDescription>
          </Alert>
        )}
        <div className="overflow-hidden rounded-md border">
          <iframe
            ref={iframeRef}
            srcDoc={srcdoc}
            sandbox="allow-same-origin"
            title="E-Mail-Inhalt"
            className="w-full"
            style={{ minHeight: "200px", height: "600px", border: "none" }}
            onLoad={handleIframeLoad}
          />
        </div>
      </div>
    );
  }

  // Plain-text fallback
  return (
    <pre className="max-h-[600px] overflow-auto rounded-md border bg-muted p-4 text-sm whitespace-pre-wrap break-words leading-relaxed">
      {plain}
    </pre>
  );
}

function AttachmentRow({
  mailId,
  attachment,
}: {
  mailId: string;
  attachment: MailAttachment;
}) {
  const [downloading, setDownloading] = useState(false);

  async function handleDownload() {
    setDownloading(true);
    try {
      const { blob, filename } = await downloadMailAttachment(
        mailId,
        attachment.index
      );
      triggerDownload(blob, filename || attachment.filename);
    } catch (e) {
      alert(`Download fehlgeschlagen: ${e instanceof Error ? e.message : e}`);
    } finally {
      setDownloading(false);
    }
  }

  return (
    <div className="flex items-center justify-between gap-4 rounded-md border px-4 py-2.5 text-sm">
      <div className="min-w-0 flex-1">
        <span className="block truncate font-medium">{attachment.filename}</span>
        <span className="text-xs text-muted-foreground">
          {attachment.content_type} · {formatBytes(attachment.size)}
        </span>
      </div>
      <Button
        variant="outline"
        size="sm"
        onClick={handleDownload}
        disabled={downloading}
      >
        {downloading ? "..." : "Herunterladen"}
      </Button>
    </div>
  );
}

// ── Page ───────────────────────────────────────────────────────────────────

export default function MailViewPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = use(params);
  const { user, loading: authLoading } = useAuth();
  const [mail, setMail] = useState<MailDetail | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [downloading, setDownloading] = useState(false);
  const [pdfLoading, setPdfLoading] = useState(false);
  const [ocrLoading, setOcrLoading] = useState(false);
  const [ocrInfo, setOcrInfo] = useState<string | null>(null);
  const [thread, setThread] = useState<ThreadMail[] | null>(null);
  const [threadOpen, setThreadOpen] = useState(false);

  useEffect(() => {
    if (!user) return;
    getMail(id)
      .then((m) => {
        setMail(m);
        if (m.thread_id) {
          getThread(m.thread_id).then((t) => {
            if (t.total > 1) setThread(t.mails);
          }).catch(() => {});
        }
      })
      .catch((e) =>
        setError(e instanceof Error ? e.message : "Unbekannter Fehler")
      )
      .finally(() => setLoading(false));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [id, user]);

  async function handleEmlDownload() {
    setDownloading(true);
    try {
      const { blob, filename } = await downloadMailRaw(id);
      triggerDownload(blob, filename);
    } catch (e) {
      alert(`Download fehlgeschlagen: ${e instanceof Error ? e.message : e}`);
    } finally {
      setDownloading(false);
    }
  }

  async function handlePdfDownload() {
    setPdfLoading(true);
    try {
      const { blob, filename } = await exportMailPDF(id);
      triggerDownload(blob, filename);
    } catch (e) {
      alert(`PDF-Export fehlgeschlagen: ${e instanceof Error ? e.message : e}`);
    } finally {
      setPdfLoading(false);
    }
  }

  async function handleOCRDownload() {
    setOcrLoading(true);
    setOcrInfo(null);
    try {
      const result = await downloadMailOCRText(id);
      if (result.kind === "ok") {
        triggerDownload(result.blob, result.filename);
      } else if (result.kind === "pending") {
        setOcrInfo("OCR läuft noch, bitte gleich nochmal versuchen.");
      } else {
        setOcrInfo("Kein OCR-Text verfügbar.");
      }
    } catch (e) {
      alert(`OCR-Download fehlgeschlagen: ${e instanceof Error ? e.message : e}`);
    } finally {
      setOcrLoading(false);
    }
  }

  return (
    <div className="min-h-screen">
      <Navbar username={user?.username ?? ""} role={user?.role ?? ""} />
      <main className="mx-auto max-w-4xl px-4 py-6 space-y-4">
        {(authLoading || !user) ? (
          <div className="space-y-4">
            <Skeleton className="h-8 w-48" />
            <Skeleton className="h-4 w-2/3" />
            <Skeleton className="h-64 w-full" />
          </div>
        ) : (<>

        {/* Back + Actions */}
        <div className="flex flex-wrap items-center justify-between gap-3">
          <Button variant="outline" size="sm" asChild>
            <Link href="/search">← Zurück zur Suche</Link>
          </Button>

          {mail && (
            <div className="flex w-full flex-wrap items-center gap-2 sm:w-auto">
              <Badge variant="outline" className="max-w-[40vw] truncate font-mono text-xs sm:max-w-none">
                {id}
              </Badge>
              <Button
                variant="outline"
                size="sm"
                onClick={handleEmlDownload}
                disabled={downloading}
              >
                {downloading ? "..." : "Als .eml herunterladen"}
              </Button>
              <Button
                variant="outline"
                size="sm"
                onClick={handlePdfDownload}
                disabled={pdfLoading}
              >
                {pdfLoading ? "..." : "Als PDF exportieren"}
              </Button>
              {mail.ocr_status === "done" && (mail.ocr_chars ?? 0) > 0 && (
                <Button
                  variant="outline"
                  size="sm"
                  onClick={handleOCRDownload}
                  disabled={ocrLoading}
                  title={`${(mail.ocr_chars ?? 0).toLocaleString("de-DE")} Zeichen erkannt`}
                >
                  <FileText className="mr-1.5 h-4 w-4" />
                  {ocrLoading ? "..." : "OCR-Text"}
                </Button>
              )}
            </div>
          )}
        </div>
        {ocrInfo && (
          <Alert>
            <AlertDescription>{ocrInfo}</AlertDescription>
          </Alert>
        )}

        {/* Loading */}
        {loading && (
          <Card>
            <CardHeader className="space-y-2">
              <Skeleton className="h-4 w-3/4" />
              <Skeleton className="h-4 w-1/2" />
              <Skeleton className="h-4 w-2/3" />
            </CardHeader>
            <CardContent>
              <Skeleton className="h-48 w-full" />
            </CardContent>
          </Card>
        )}

        {/* Error */}
        {error && (
          <Alert variant="destructive">
            <AlertDescription>{error}</AlertDescription>
          </Alert>
        )}

        {/* Mail content */}
        {mail && (
          <>
            {/* Header */}
            <Card>
              <CardHeader>
                <MailHeaderGrid mail={mail} />
              </CardHeader>
            </Card>

            {/* Body */}
            <Card>
              <CardContent className="pt-6">
                <MailBodyView mail={mail} />
              </CardContent>
            </Card>

            {/* Attachments */}
            {mail.attachments && mail.attachments.length > 0 && (
              <Card>
                <CardHeader className="pb-3">
                  <span className="text-sm font-medium">
                    Anhänge ({mail.attachments.length})
                  </span>
                </CardHeader>
                <Separator />
                <CardContent className="pt-4 space-y-2">
                  {mail.attachments.map((att) => (
                    <AttachmentRow
                      key={att.index}
                      mailId={id}
                      attachment={att}
                    />
                  ))}
                </CardContent>
              </Card>
            )}

            {/* Thread panel */}
            {thread && thread.length > 1 && (
              <Card>
                <CardHeader className="pb-3">
                  <button
                    onClick={() => setThreadOpen((v) => !v)}
                    className="flex items-center gap-2 text-sm font-medium hover:text-foreground text-muted-foreground"
                  >
                    <svg className={`w-4 h-4 transition-transform ${threadOpen ? "rotate-90" : ""}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
                    </svg>
                    Konversation ({thread.length} Mails)
                  </button>
                </CardHeader>
                {threadOpen && (
                  <>
                    <Separator />
                    <CardContent className="pt-3 space-y-1">
                      {thread.map((m) => (
                        <Link
                          key={m.id}
                          href={`/mail/${m.id}`}
                          className={`flex items-center justify-between gap-3 rounded-md px-3 py-2 text-sm hover:bg-muted transition-colors ${m.id === id ? "bg-muted font-medium" : ""}`}
                        >
                          <span className="min-w-0 flex-1 truncate">
                            {m.subject || "(kein Betreff)"}
                          </span>
                          <span className="shrink-0 text-xs text-muted-foreground">
                            {m.date ? new Date(m.date).toLocaleDateString("de-DE") : "–"}
                          </span>
                        </Link>
                      ))}
                    </CardContent>
                  </>
                )}
              </Card>
            )}
          </>
        )}
      </>)}
      </main>
    </div>
  );
}
