'use client';

import { useEffect, useRef, useState } from 'react';
import { Loader2 } from 'lucide-react';

/**
 * In-app .docx viewer.
 *
 * Renders Word OOXML (.docx) client-side via `docx-preview` (lazy-loaded
 * so the ~library cost only lands on routes that actually preview a docx).
 * We fetch the bytes from our own storage URL and render them in-browser —
 * deliberately NOT delegating to Microsoft's hosted Office viewer, which
 * requires a publicly-reachable URL and so can't render documents stored
 * in our private object store.
 *
 * Legacy .doc / .xls / .xlsx are not handled here (docx-preview is OOXML-
 * Word only); the preview dialog routes those to a download CTA instead.
 */
export function DocxViewer({ url, fileName }: { url: string; fileName?: string }) {
  // Key-based remount on url change keeps render state (loading/error +
  // the imperatively-populated container) re-initialised from scratch,
  // mirroring PdfViewer.
  return <DocxViewerBody key={url} url={url} fileName={fileName} />;
}

function DocxViewerBody({ url, fileName }: { url: string; fileName?: string }) {
  const containerRef = useRef<HTMLDivElement>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    async function render() {
      try {
        const res = await fetch(url);
        if (!res.ok) throw new Error(`Failed to load document (${res.status})`);
        const blob = await res.blob();
        if (cancelled) return;
        const { renderAsync } = await import('docx-preview');
        const container = containerRef.current;
        if (!container) return;
        container.innerHTML = '';
        await renderAsync(blob, container, undefined, {
          className: 'docx',
          inWrapper: true,
          // Let the document flow to the container width rather than
          // forcing fixed A4 page metrics that overflow the dialog.
          ignoreWidth: true,
          ignoreHeight: true,
          breakPages: true,
        });
        if (!cancelled) setError(null);
      } catch (err) {
        if (!cancelled) {
          setError(err instanceof Error ? err.message : 'Failed to render document');
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    void render();
    return () => {
      cancelled = true;
    };
  }, [url]);

  return (
    <div className="relative h-full overflow-auto bg-muted/30 p-4">
      {loading && (
        <div className="absolute inset-0 flex items-center justify-center gap-2 text-sm text-muted-foreground">
          <Loader2 className="h-4 w-4 animate-spin" aria-hidden />
          Rendering document…
        </div>
      )}
      {error && !loading && (
        <div className="flex h-full items-center justify-center px-6 text-center text-sm text-destructive">
          {error}
        </div>
      )}
      <div
        ref={containerRef}
        aria-label={fileName ?? 'Document preview'}
        className="mx-auto max-w-3xl [&_.docx-wrapper]:bg-transparent [&_.docx-wrapper]:p-0 [&_.docx-wrapper>section.docx]:mx-auto [&_.docx-wrapper>section.docx]:mb-4 [&_.docx-wrapper>section.docx]:bg-white [&_.docx-wrapper>section.docx]:shadow-sm"
      />
    </div>
  );
}
