"use client";

import { use, useEffect, useRef, useState } from "react";
import Link from "next/link";
import {
  getMail,
  downloadMailAttachment,
  downloadMailRaw,
  exportMailPDF,
  getLabels,
  getMailLabelIds,
  type MailDetail,
  type MailAttachment,
  type MailLabel,
} from "@/lib/api";
import { useAuth } from "@/hooks/useAuth";
import { Navbar } from "@/components/navbar";
import { LabelPicker } from "@/components/LabelPicker";
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";

// ── 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;
  }
}

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>
          {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>
          )}
        </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 items-center justify-between gap-4 text-sm">
              <span>Externe Inhalte (Bilder, Tracker) sind blockiert.</span>
              <Button
                variant="outline"
                size="sm"
                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);

  // Labels state
  const [allLabels, setAllLabels] = useState<MailLabel[]>([]);
  const [assignedLabelIds, setAssignedLabelIds] = useState<number[]>([]);

  useEffect(() => {
    if (!user) return;
    getMail(id)
      .then(setMail)
      .catch((e) =>
        setError(e instanceof Error ? e.message : "Unbekannter Fehler")
      )
      .finally(() => setLoading(false));
    // Load labels
    getLabels().then(setAllLabels).catch(() => {});
    loadMailLabels();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [id, user]);

  function loadMailLabels() {
    getMailLabelIds(id).then(setAssignedLabelIds).catch(() => setAssignedLabelIds([]));
  }

  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);
    }
  }

  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 items-center gap-2">
              <Badge variant="outline" className="font-mono text-xs">
                {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>
            </div>
          )}
        </div>

        {/* 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>

            {/* Labels */}
            {allLabels.length > 0 && (
              <Card>
                <CardContent className="pt-4 pb-4">
                  <LabelPicker
                    emailId={id}
                    assignedLabelIds={assignedLabelIds}
                    allLabels={allLabels}
                    onUpdate={loadMailLabels}
                  />
                </CardContent>
              </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>
            )}
          </>
        )}
      </>)}
      </main>
    </div>
  );
}
