'use client';

import { useEffect, useState } from 'react';
import { Download, Loader2, X } from 'lucide-react';
import { toast } from 'sonner';

import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { triggerBlobDownload } from '@/lib/utils/download';
import { resolvePortIdFromSlug } from '@/lib/api/client';

interface Props {
  open: boolean;
  onOpenChange: (next: boolean) => void;
  /** JSON body forwarded to /api/v1/reports/generate. */
  payload: unknown;
  /** Filename used when the rep clicks Download. */
  filename: string;
  /** Dialog header shown above the iframe. */
  title?: string;
}

/**
 * Preview-then-download flow for a generated PDF.
 *
 * The modal POSTs the supplied payload to `/api/v1/reports/generate`
 * on open, holds the resulting Blob in component state, and renders
 * it in an iframe via `URL.createObjectURL`. The Download button
 * reuses the cached Blob — no second network round-trip on commit.
 *
 * Lifecycle:
 *   - On open: fetch + revoke any previous URL
 *   - On payload change: re-fetch (the rep edited config in the
 *     parent dialog and re-opened preview)
 *   - On close: revoke the URL so the blob is GC'd
 */
export function PdfPreviewModal({
  open,
  onOpenChange,
  payload,
  filename,
  title = 'Preview report',
}: Props) {
  const [url, setUrl] = useState<string | null>(null);
  const [blob, setBlob] = useState<Blob | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Re-fetch the preview whenever the modal opens (or the payload
  // changes while open). Revoke the previous object URL inside the
  // same effect so we never leak.
  useEffect(() => {
    if (!open) return;
    let cancelled = false;
    let currentUrl: string | null = null;

    async function loadPreview() {
      setLoading(true);
      setError(null);
      try {
        const headers = new Headers({ 'Content-Type': 'application/json' });
        if (typeof window !== 'undefined') {
          const slug = window.location.pathname.split('/').filter(Boolean)[0];
          if (slug && slug !== 'login' && slug !== 'portal' && slug !== 'api') {
            const portId = await resolvePortIdFromSlug(slug);
            if (portId) headers.set('X-Port-Id', portId);
          }
        }
        const res = await fetch('/api/v1/reports/generate', {
          method: 'POST',
          headers,
          body: JSON.stringify(payload),
        });
        if (!res.ok) {
          const text = await res.text();
          throw new Error(text || `Preview failed (${res.status})`);
        }
        const b = await res.blob();
        if (cancelled) return;
        currentUrl = URL.createObjectURL(b);
        setBlob(b);
        setUrl(currentUrl);
      } catch (err) {
        if (cancelled) return;
        setError(err instanceof Error ? err.message : 'Preview failed');
      } finally {
        if (!cancelled) setLoading(false);
      }
    }

    void loadPreview();

    return () => {
      cancelled = true;
      if (currentUrl) URL.revokeObjectURL(currentUrl);
    };
  }, [open, payload]);

  // Belt-and-braces revoke on unmount in case the modal closes
  // mid-fetch and the effect's cleanup didn't capture the URL yet.
  useEffect(
    () => () => {
      if (url) URL.revokeObjectURL(url);
    },
    [url],
  );

  function handleDownload() {
    if (!blob) return;
    triggerBlobDownload(blob, filename);
    toast.success('Report downloaded');
    onOpenChange(false);
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-5xl w-[95vw] h-[90vh] flex flex-col">
        <DialogHeader>
          <DialogTitle>{title}</DialogTitle>
          <DialogDescription>
            Inline preview of the rendered PDF. Download to save the file or close to go back and
            tweak the configuration.
          </DialogDescription>
        </DialogHeader>

        <div className="flex-1 min-h-0 overflow-hidden rounded-md border bg-muted/20">
          {loading ? (
            <div className="flex h-full items-center justify-center gap-2 text-sm text-muted-foreground">
              <Loader2 className="h-4 w-4 animate-spin" aria-hidden />
              Rendering preview…
            </div>
          ) : error ? (
            <div className="flex h-full flex-col items-center justify-center gap-2 px-4 text-center">
              <div className="text-sm font-medium text-destructive">Preview failed</div>
              <div className="font-mono text-xs text-muted-foreground break-all">{error}</div>
            </div>
          ) : url ? (
            <iframe
              key={url}
              src={url}
              title="PDF preview"
              className="h-full w-full"
              // Sandbox keeps any embedded scripts in the PDF viewer
              // from reaching our cookies or LocalStorage. allow-
              // same-origin lets the iframe load the blob URL.
              sandbox="allow-same-origin"
            />
          ) : null}
        </div>

        <div className="flex items-center justify-end gap-2 pt-3">
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            <X className="mr-1.5 h-4 w-4" aria-hidden />
            Close
          </Button>
          <Button onClick={handleDownload} disabled={!blob || loading}>
            {loading ? (
              <Loader2 className="mr-1.5 h-4 w-4 animate-spin" aria-hidden />
            ) : (
              <Download className="mr-1.5 h-4 w-4" aria-hidden />
            )}
            Download
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
}
