// PDF to JPG — render each page via pdf.js, export individually or as a zip.

const PDFJS_URL = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.11.174/build/pdf.min.js';
const PDFJS_WORKER = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.11.174/build/pdf.worker.min.js';
const FFLATE_URL = 'https://cdn.jsdelivr.net/npm/fflate@0.8.2/umd/index.js';

window.TOOL_HANDLERS['pdf-to-jpg'] = function PdfToJpgTool() {
  const [file, setFile] = React.useState(null);
  const [pages, setPages] = React.useState([]);  // { num, dataUrl }
  const [scale, setScale] = React.useState(2);   // 1 = 72dpi, 2 ≈ 144dpi
  const [busy, setBusy] = React.useState(false);
  const [status, setStatus] = React.useState('');
  const [err, setErr] = React.useState('');

  const run = async (f, s) => {
    setBusy(true); setErr(''); setPages([]);
    try {
      setStatus('Loading pdf.js…');
      await window.loadScript(PDFJS_URL);
      window.pdfjsLib.GlobalWorkerOptions.workerSrc = PDFJS_WORKER;
      setStatus('Reading PDF…');
      const bytes = new Uint8Array(await f.arrayBuffer());
      const doc = await window.pdfjsLib.getDocument({ data: bytes }).promise;
      const out = [];
      for (let i = 1; i <= doc.numPages; i++) {
        setStatus(`Rendering page ${i} / ${doc.numPages}…`);
        const page = await doc.getPage(i);
        const viewport = page.getViewport({ scale: s });
        const canvas = document.createElement('canvas');
        canvas.width = viewport.width; canvas.height = viewport.height;
        await page.render({ canvasContext: canvas.getContext('2d'), viewport }).promise;
        out.push({ num: i, dataUrl: canvas.toDataURL('image/jpeg', 0.92) });
      }
      setPages(out); setStatus('');
    } catch (e) { setErr(e.message); setStatus(''); }
    finally { setBusy(false); }
  };

  const handleFile = (f) => { setFile(f); run(f, scale); };

  const downloadOne = (p) => {
    const base = file.name.replace(/\.pdf$/i, '');
    const a = document.createElement('a');
    a.href = p.dataUrl; a.download = `${base}-p${String(p.num).padStart(3, '0')}.jpg`; a.click();
  };

  const downloadAll = async () => {
    await window.loadScript(FFLATE_URL);
    const zip = {};
    const base = file.name.replace(/\.pdf$/i, '');
    for (const p of pages) {
      const bin = atob(p.dataUrl.split(',')[1]);
      const u8 = new Uint8Array(bin.length);
      for (let i = 0; i < bin.length; i++) u8[i] = bin.charCodeAt(i);
      zip[`${base}-p${String(p.num).padStart(3, '0')}.jpg`] = u8;
    }
    window.fflate.zip(zip, (err, data) => {
      if (err) return setErr(err.message);
      window.downloadBlob(new Blob([data], { type: 'application/zip' }), `${base}-pages.zip`);
    });
  };

  if (!file) return <window.Dropzone onFile={handleFile} title="Drop a PDF here" hint="each page → JPG" accept="application/pdf,.pdf" />;

  return (
    <div className="mini-tool">
      <div className="cmp-slider-row">
        <div className="cmp-label"><span>Quality (scale)</span><span className="val">{scale}×</span></div>
        <input type="range" min="1" max="3" step="0.5" value={scale}
               onChange={(e) => { setScale(+e.target.value); run(file, +e.target.value); }}
               className="cmp-slider" disabled={busy} />
      </div>
      {busy && <div className="cmp-meta" style={{ marginTop: 10 }}>{status}</div>}
      {err && <div style={{ color: '#c8321f', marginTop: 10 }}>{err}</div>}

      {pages.length > 0 && (
        <>
          <div className="mini-label" style={{ marginTop: 16 }}>{pages.length} page{pages.length === 1 ? '' : 's'}</div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))', gap: 10, marginTop: 8 }}>
            {pages.map((p) => (
              <button key={p.num} onClick={() => downloadOne(p)} title={`Page ${p.num}`}
                      style={{ padding: 0, border: '1px solid var(--id-border)', borderRadius: 10, overflow: 'hidden', cursor: 'pointer', background: 'var(--id-surface)' }}>
                <img src={p.dataUrl} alt="" style={{ width: '100%', height: 160, objectFit: 'cover', display: 'block' }} />
                <div style={{ padding: '6px 8px', fontSize: 12, display: 'flex', justifyContent: 'space-between' }}>
                  <span>Page {p.num}</span>
                  <window.Icon name="download" size={12} />
                </div>
              </button>
            ))}
          </div>
        </>
      )}

      <div className="cmp-actions">
        <button className="btn btn-secondary" onClick={() => { setFile(null); setPages([]); }}><window.Icon name="upload" size={16} /> Another PDF</button>
        <button className="btn btn-primary" onClick={downloadAll} disabled={pages.length === 0 || busy}>
          <window.Icon name="download" size={16} /> Download all as ZIP
        </button>
      </div>
    </div>
  );
};
