import { useEffect, useState } from "react";
import type { EvidenceItemMeta, ServerEvidenceKind } from "@/lib/applicationEvidenceApi";
import { applicationDraftEvidenceContentUrl } from "@/lib/applicationEvidenceApi";
import { imagePreviewSrc, isImageEvidence, isPdfEvidence, pdfIframeSrc } from "@/lib/evidencePreviewUtils";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { env } from "@/shared/config/env";
import { getAccessToken } from "@/shared/utils/token";
import { Loader2 } from "lucide-react";

export type ApplicationEvidenceFilePreviewProps = {
  meta: EvidenceItemMeta;
  /** When set, PDF/image preview uses the API stream (HTTPS same origin) instead of MinIO presign — avoids mixed-content on production. */
  contentProxy?: { caseId: string; kind: ServerEvidenceKind };
  /** e.g. "Minh chứng research" — iframe title / a11y */
  title?: string;
  className?: string;
  iframeClassName?: string;
};

/**
 * Inline preview for application evidence (2.1 / 2.2): PDF in iframe, images, or download fallback.
 * With `contentProxy`, loads via authenticated GET …/evidence/content (no http://MinIO iframe).
 */
export function ApplicationEvidenceFilePreview({
  meta,
  contentProxy,
  title,
  className,
  iframeClassName,
}: ApplicationEvidenceFilePreviewProps) {
  const [proxiedBlobUrl, setProxiedBlobUrl] = useState<string | null>(null);
  const [proxyLoading, setProxyLoading] = useState(false);
  const [proxyError, setProxyError] = useState<string | null>(null);

  useEffect(() => {
    if (!contentProxy) {
      setProxiedBlobUrl(null);
      setProxyLoading(false);
      setProxyError(null);
      return;
    }

    const embeddable = isPdfEvidence(meta) || isImageEvidence(meta);
    if (!embeddable) {
      setProxiedBlobUrl(null);
      setProxyLoading(false);
      setProxyError(null);
      return;
    }

    let cancelled = false;
    let objectUrl: string | null = null;

    async function load() {
      setProxyLoading(true);
      setProxyError(null);
      setProxiedBlobUrl(null);

      try {
        const url = applicationDraftEvidenceContentUrl(contentProxy.caseId, contentProxy.kind);
        const token = getAccessToken();
        const res = await fetch(url, {
          headers: token ? { Authorization: `Bearer ${token}` } : {},
          credentials: env.API_URL ? "omit" : "include",
        });
        if (!res.ok) {
          const detail = await res.text().catch(() => "");
          throw new Error(detail.trim() || `HTTP ${res.status}`);
        }
        const blob = await res.blob();
        if (cancelled) return;
        objectUrl = URL.createObjectURL(blob);
        setProxiedBlobUrl(objectUrl);
      } catch (e: unknown) {
        if (!cancelled) setProxyError(e instanceof Error ? e.message : "Không tải được tệp.");
      } finally {
        if (!cancelled) setProxyLoading(false);
      }
    }

    void load();

    return () => {
      cancelled = true;
      if (objectUrl) URL.revokeObjectURL(objectUrl);
    };
  }, [
    contentProxy?.caseId,
    contentProxy?.kind,
    meta.storageKey,
    meta.mimeType,
    meta.originalName,
  ]);

  const pdfSrcDirect = pdfIframeSrc(meta);

  const downloadViaProxy = async () => {
    if (!contentProxy) return;
    const url = applicationDraftEvidenceContentUrl(contentProxy.caseId, contentProxy.kind, {
      attachment: true,
    });
    const token = getAccessToken();
    const res = await fetch(url, {
      headers: token ? { Authorization: `Bearer ${token}` } : {},
      credentials: env.API_URL ? "omit" : "include",
    });
    if (!res.ok) throw new Error(await res.text().catch(() => `HTTP ${res.status}`));
    const blob = await res.blob();
    const objectUrl = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = objectUrl;
    a.download = meta.originalName || "minh-chung";
    a.rel = "noreferrer";
    a.click();
    URL.revokeObjectURL(objectUrl);
  };

  if (contentProxy && (isPdfEvidence(meta) || isImageEvidence(meta))) {
    if (proxyLoading) {
      return (
        <div
          className={cn(
            "flex min-h-[280px] flex-1 flex-col items-center justify-center gap-2 rounded-md border bg-muted/20 text-sm text-muted-foreground",
            className,
          )}
        >
          <Loader2 className="h-8 w-8 animate-spin" aria-hidden />
          Đang tải bản xem…
        </div>
      );
    }
    if (proxyError) {
      return (
        <div className={cn("space-y-3 rounded-md border border-destructive/30 bg-destructive/5 p-4", className)}>
          <p className="text-sm text-destructive">{proxyError}</p>
          <div className="flex flex-wrap gap-2">
            <Button type="button" variant="secondary" size="sm" onClick={() => void downloadViaProxy().catch(() => {})}>
              Tải xuống
            </Button>
          </div>
        </div>
      );
    }
    if (proxiedBlobUrl && isPdfEvidence(meta)) {
      return (
        <div className={cn("flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border bg-muted/20", className)}>
          <iframe
            key={proxiedBlobUrl}
            title={title || meta.originalName || "Minh chứng PDF"}
            src={proxiedBlobUrl}
            className={cn("h-full w-full min-h-[280px] flex-1 border-0", iframeClassName)}
          />
        </div>
      );
    }
    if (proxiedBlobUrl && isImageEvidence(meta)) {
      return (
        <div className={cn("flex min-h-0 flex-1 justify-center overflow-auto rounded-md border bg-background p-2", className)}>
          <img src={proxiedBlobUrl} alt={meta.originalName || "Minh chứng"} className="max-h-full w-auto object-contain" />
        </div>
      );
    }
  }

  if (pdfSrcDirect && isPdfEvidence(meta)) {
    return (
      <div className={cn("flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border bg-muted/20", className)}>
        <iframe
          key={pdfSrcDirect}
          title={title || meta.originalName || "Minh chứng PDF"}
          src={pdfSrcDirect}
          className={cn("h-full w-full min-h-[280px] flex-1 border-0", iframeClassName)}
        />
      </div>
    );
  }

  const imgSrc = imagePreviewSrc(meta);
  if (imgSrc && isImageEvidence(meta)) {
    return (
      <div className={cn("flex min-h-0 flex-1 justify-center overflow-auto rounded-md border bg-background p-2", className)}>
        <img src={imgSrc} alt={meta.originalName || "Minh chứng"} className="max-h-full w-auto object-contain" />
      </div>
    );
  }

  const fallbackPresign = meta.downloadUrl || meta.viewUrl;
  return (
    <div className={cn("space-y-3 rounded-md border bg-muted/10 p-4", className)}>
      <p className="text-sm text-muted-foreground">
        Tệp {meta.originalName || "đính kèm"} không xem trực tiếp trong trình duyệt. Tải về hoặc mở qua máy chủ ứng dụng.
      </p>
      {contentProxy ? (
        <Button type="button" onClick={() => void downloadViaProxy()}>
          Tải xuống
        </Button>
      ) : fallbackPresign ? (
        <Button asChild>
          <a href={fallbackPresign} target="_blank" rel="noreferrer">
            Mở / tải tệp
          </a>
        </Button>
      ) : null}
    </div>
  );
}
