'use client';

import { useEffect, useState } from 'react';
import MarkdownContent from './MarkdownContent';

const TEXT_LIKE = new Set(['md', 'txt', 'log', 'json', 'yaml', 'yml', 'csv', 'html']);
const IMAGE_LIKE = new Set(['png', 'jpg', 'jpeg', 'gif', 'svg']);
const EMBED_LIKE = new Set(['pdf']);

/** Cap inline text rendering. Anything larger falls back to a download
 *  prompt — react-markdown on multi-MB strings locks the tab. */
const MAX_INLINE_BYTES = 2 * 1024 * 1024;

function extOf(p: string): string {
  const m = p.match(/\.([^./]+)$/);
  return m ? m[1].toLowerCase() : '';
}

export default function ScratchViewer({
  path,
  apiBase = '/api/scratch',
  topLabel = 'scratch',
}: {
  path: string;
  /** API route prefix. /api/scratch resolves under <dataDir>/scratch/;
   *  /api/files resolves dataDir-wide. Default scratch for back-compat. */
  apiBase?: string;
  /** Tiny header tag shown next to the file path (e.g. "scratch", "file"). */
  topLabel?: string;
}) {
  const decoded = (() => {
    try {
      return decodeURIComponent(path);
    } catch {
      return path;
    }
  })();
  const ext = extOf(decoded);
  const rawUrl = `${apiBase}/${path}`;
  const downloadUrl = `${rawUrl}?download=1`;

  const [text, setText] = useState<string | null>(null);
  const [err, setErr] = useState<string>('');
  const [tooLarge, setTooLarge] = useState(false);

  useEffect(() => {
    if (!TEXT_LIKE.has(ext)) return;
    let cancelled = false;
    (async () => {
      try {
        const r = await fetch(rawUrl);
        if (!r.ok) {
          if (!cancelled) setErr(`${r.status} ${r.statusText}`);
          return;
        }
        const len = Number(r.headers.get('content-length') || '0');
        if (len > MAX_INLINE_BYTES) {
          if (!cancelled) setTooLarge(true);
          return;
        }
        const body = await r.text();
        if (cancelled) return;
        if (body.length > MAX_INLINE_BYTES) {
          setTooLarge(true);
          return;
        }
        setText(body);
      } catch (e) {
        if (!cancelled) setErr((e as Error).message);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [rawUrl, ext]);

  return (
    <div className="min-h-screen bg-[var(--bg-primary)] text-[var(--text-primary)]">
      <header className="sticky top-0 z-10 flex items-center justify-between gap-2 px-4 py-2 border-b border-[var(--border)] bg-[var(--bg-secondary)]">
        <div className="flex items-center gap-2 min-w-0">
          <span className="text-[10px] uppercase tracking-wide text-[var(--text-secondary)]">{topLabel}</span>
          <span className="text-xs font-mono truncate" title={decoded}>
            {decoded}
          </span>
        </div>
        <div className="flex items-center gap-2 flex-shrink-0">
          <a
            href={rawUrl}
            className="text-xs px-2 py-1 rounded border border-[var(--border)] hover:bg-[var(--bg-tertiary)]"
            target="_blank"
            rel="noopener"
          >
            Open raw
          </a>
          <a
            href={downloadUrl}
            className="text-xs px-2 py-1 rounded bg-[var(--accent)] text-white hover:opacity-90"
          >
            Download
          </a>
        </div>
      </header>

      <main className="px-4 py-3 max-w-4xl mx-auto">
        {err && (
          <div className="text-xs text-red-400 border border-red-400/40 rounded p-2 bg-red-400/5">
            Failed to load: {err}
          </div>
        )}

        {tooLarge && (
          <div className="text-xs text-[var(--text-secondary)] border border-[var(--border)] rounded p-3">
            File is larger than {Math.round(MAX_INLINE_BYTES / 1024 / 1024)} MB — inline preview skipped. Use Download or Open raw.
          </div>
        )}

        {!err && !tooLarge && IMAGE_LIKE.has(ext) && (
          <img src={rawUrl} alt={decoded} className="max-w-full rounded border border-[var(--border)]" />
        )}

        {!err && !tooLarge && EMBED_LIKE.has(ext) && (
          <embed src={rawUrl} type="application/pdf" className="w-full h-[calc(100vh-60px)]" />
        )}

        {!err && !tooLarge && TEXT_LIKE.has(ext) && text != null && (
          ext === 'md' ? (
            <MarkdownContent content={text} />
          ) : ext === 'html' ? (
            // Wrap in iframe srcdoc so any embedded scripts can't reach Forge's
            // origin or steal session cookies. sandbox blocks everything.
            <iframe
              srcDoc={text}
              sandbox=""
              className="w-full h-[calc(100vh-60px)] bg-white rounded border border-[var(--border)]"
              title={decoded}
            />
          ) : (
            <pre className="text-[12px] font-mono text-[var(--text-primary)] bg-[var(--bg-tertiary)] border border-[var(--border)] rounded p-3 overflow-auto whitespace-pre-wrap break-words" style={{ fontFamily: 'Menlo, Monaco, "Courier New", monospace' }}>
              {text}
            </pre>
          )
        )}

        {!err && !tooLarge && !TEXT_LIKE.has(ext) && !IMAGE_LIKE.has(ext) && !EMBED_LIKE.has(ext) && (
          <div className="text-xs text-[var(--text-secondary)] border border-[var(--border)] rounded p-3">
            No inline preview for <code className="font-mono">.{ext || '?'}</code> files. Use Download.
          </div>
        )}
      </main>
    </div>
  );
}
