/**
 * AttachmentPreviewModal
 *
 * Composes the inline preview surface for an attachment:
 *   - application/pdf       → <iframe src={blobUrl}>
 *   - image/*               → <img src={blobUrl}>
 *   - everything else       → "Download to view" with a download button
 *
 * v1 deliberately skips `react-pdf` / `pdfjs-dist` — the native
 * <iframe> is enough for the "I just want to see this file" use
 * case the user asked for. Multi-page zoom / page nav can land in a
 * later release if a teacher complains.
 *
 * The component is responsible for:
 *   - opening the modal when `attachment` becomes non-null
 *   - calling `useAttachmentStore.preview(uid)` to fetch the blob
 *   - creating the object URL, passing it to the renderer
 *   - revoking the object URL on close / unmount / uid change
 *
 * The caller passes either:
 *   - an `Attachment` (we look up the row ourselves), or
 *   - the result of `useAttachmentStore.preview(uid)` via a pre-fetched
 *     `preview` object so the modal can render immediately while a
 *     background fetch is in flight (not used in PR 1).
 */

import { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { X, Download, FileText, Loader2, AlertCircle, Sparkles } from 'lucide-react';
import { useAttachmentStore, Attachment } from '../store/attachments';

interface AttachmentPreviewModalProps {
  attachment: Attachment | null;
  onClose: () => void;
}

interface PreviewState {
  url: string | null;
  mime: string;
  name: string;
  size: number;
  error: string | null;
  loading: boolean;
}

const initialState: PreviewState = {
  url: null,
  mime: '',
  name: '',
  size: 0,
  error: null,
  loading: false,
};

export function AttachmentPreviewModal({ attachment, onClose }: AttachmentPreviewModalProps) {
  const { preview, downloadUrl } = useAttachmentStore();
  const [state, setState] = useState<PreviewState>(initialState);

  // Fetch the blob + create the object URL when the modal opens
  // (or the underlying attachment changes). Revokes the previous URL
  // before allocating a new one so a sequence of opens doesn't leak.
  useEffect(() => {
    if (!attachment) {
      setState(initialState);
      return;
    }

    let cancelled = false;
    setState({ ...initialState, loading: true, name: attachment.original_filename, mime: attachment.mime_type, size: attachment.size_bytes });

    preview(attachment.uid)
      .then(res => {
        if (cancelled) {
          URL.revokeObjectURL(res.url);
          return;
        }
        setState({
          url: res.url,
          mime: res.mime,
          name: res.name,
          size: res.size,
          error: null,
          loading: false,
        });
      })
      .catch((err: any) => {
        if (cancelled) return;
        setState({
          url: null,
          mime: attachment.mime_type,
          name: attachment.original_filename,
          size: attachment.size_bytes,
          error: err?.response?.data?.error || err?.message || 'Failed to load preview',
          loading: false,
        });
      });

    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [attachment?.uid]);

  // Always revoke on unmount or when url changes
  useEffect(() => {
    return () => {
      if (state.url) URL.revokeObjectURL(state.url);
    };
  }, [state.url]);

  // Escape key + body scroll lock
  useEffect(() => {
    if (!attachment) return;

    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    document.addEventListener('keydown', onKey);

    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';

    return () => {
      document.removeEventListener('keydown', onKey);
      document.body.style.overflow = previousOverflow;
    };
  }, [attachment, onClose]);

  if (!attachment) return null;

  const handleDownload = () => {
    const url = downloadUrl(attachment.stored_filename);
    const a = document.createElement('a');
    a.href = url;
    a.download = attachment.original_filename;
    a.rel = 'noopener';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  };

  const onBackdropClick = (e: React.MouseEvent) => {
    if (e.target === e.currentTarget) onClose();
  };

  const isImage = state.mime.startsWith('image/');
  const isPdf = state.mime === 'application/pdf';
  const isPreviewable = isImage || isPdf;

  return createPortal(
    <div
      onClick={onBackdropClick}
      role="dialog"
      aria-modal="true"
      aria-label={`Preview ${attachment.original_filename}`}
      className="fixed inset-0 z-[200] flex items-center justify-center bg-slate-900/60 backdrop-blur-sm p-3 sm:p-6"
    >
      <div className="relative w-full max-w-5xl max-h-[95vh] bg-card border border-border rounded-[2.5rem] shadow-2xl flex flex-col overflow-hidden">
        {/* Header */}
        <div className="flex items-center gap-3 p-4 sm:p-5 border-b border-border shrink-0 relative">
          <div className="absolute right-[-20px] top-[-20px] opacity-[0.03] rotate-12 text-primary">
            <Sparkles size={180} />
          </div>
          <div className="shrink-0 w-9 h-9 rounded-xl bg-muted border border-border flex items-center justify-center text-text-muted">
            <FileText size={18} />
          </div>
          <div className="min-w-0 flex-1">
            <div className="font-semibold text-text truncate" title={attachment.original_filename}>
              {attachment.original_filename}
            </div>
            <div className="text-[0.7rem] text-text-muted font-medium">
              {state.mime || 'unknown type'}
            </div>
          </div>
          <button
            type="button"
            onClick={handleDownload}
            className="hidden sm:inline-flex items-center gap-2 px-3 py-2 rounded-xl bg-muted hover:bg-muted/70 text-text text-xs font-bold uppercase tracking-widest transition-colors"
            title="Download"
          >
            <Download size={14} />
            Download
          </button>
          <button
            type="button"
            onClick={onClose}
            className="p-2 rounded-xl text-text-muted hover:text-text hover:bg-muted transition-colors"
            title="Close"
            aria-label="Close preview"
          >
            <X size={18} />
          </button>
        </div>

        {/* Body */}
        <div className="flex-1 min-h-0 bg-slate-50/40 overflow-auto flex items-center justify-center p-3 sm:p-5">
          {state.loading ? (
            <div className="flex flex-col items-center gap-3 text-text-muted">
              <Loader2 size={32} className="animate-spin text-primary" />
              <p className="text-sm font-semibold">Loading preview…</p>
            </div>
          ) : state.error ? (
            <div className="flex flex-col items-center gap-3 text-rose-600 max-w-sm text-center">
              <AlertCircle size={32} />
              <p className="text-sm font-semibold">{state.error}</p>
              <button
                type="button"
                onClick={handleDownload}
                className="inline-flex items-center gap-2 px-4 py-2 rounded-xl bg-primary text-white text-xs font-black uppercase tracking-widest"
              >
                <Download size={14} />
                Download instead
              </button>
            </div>
          ) : state.url && isPdf ? (
            <iframe
              src={state.url}
              title={state.name}
              className="w-full h-[80vh] rounded-2xl border border-border bg-card"
            />
          ) : state.url && isImage ? (
            <img
              src={state.url}
              alt={state.name}
              className="max-w-full max-h-[80vh] object-contain rounded-2xl"
            />
          ) : (
            <div className="flex flex-col items-center gap-3 text-text-muted max-w-sm text-center">
              <FileText size={48} className="text-text-muted/40" />
              <p className="text-sm font-semibold text-text">
                Preview not available for this file type
              </p>
              <p className="text-xs text-text-muted">
                {state.mime || 'Unknown type'} — download to view in your default app.
              </p>
              <button
                type="button"
                onClick={handleDownload}
                className="inline-flex items-center gap-2 px-4 py-2 rounded-xl bg-primary text-white text-xs font-black uppercase tracking-widest"
              >
                <Download size={14} />
                Download to view
              </button>
            </div>
          )}
        </div>

        {/* Mobile download affordance */}
        {isPreviewable && (
          <div className="sm:hidden p-3 border-t border-border">
            <button
              type="button"
              onClick={handleDownload}
              className="w-full inline-flex items-center justify-center gap-2 px-4 py-3 rounded-xl bg-primary text-white text-xs font-black uppercase tracking-widest"
            >
              <Download size={14} />
              Download
            </button>
          </div>
        )}
      </div>
    </div>,
    document.body
  );
}

export default AttachmentPreviewModal;
