// Zip Files — pack selected files into a .zip via fflate.

const FFLATE_URL = 'https://cdn.jsdelivr.net/npm/fflate@0.8.2/umd/index.js';

window.TOOL_HANDLERS['zip-files'] = function ZipFilesTool() {
  const [files, setFiles] = React.useState([]);
  const [name, setName] = React.useState('archive');
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState('');

  const addFiles = (picked) => {
    const list = Array.isArray(picked) ? picked : [picked];
    setFiles((prev) => [...prev, ...list]);
  };
  const removeAt = (i) => setFiles((prev) => prev.filter((_, idx) => idx !== i));

  const run = async () => {
    setBusy(true); setErr('');
    try {
      await window.loadScript(FFLATE_URL);
      const zip = {};
      for (const f of files) zip[f.name] = new Uint8Array(await f.arrayBuffer());
      window.fflate.zip(zip, { level: 6 }, (zerr, data) => {
        setBusy(false);
        if (zerr) return setErr(zerr.message);
        window.downloadBlob(new Blob([data], { type: 'application/zip' }), (name || 'archive') + '.zip');
      });
    } catch (e) { setErr(e.message); setBusy(false); }
  };

  const totalSize = files.reduce((sum, f) => sum + f.size, 0);

  if (files.length === 0) return <window.Dropzone onFile={addFiles} multiple title="Drop files here" hint="anything — we'll zip them up" />;

  return (
    <div className="mini-tool">
      <div className="mini-label">{files.length} file{files.length === 1 ? '' : 's'} · {window.fmtBytes(totalSize)}</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginTop: 10, maxHeight: 220, overflowY: 'auto' }}>
        {files.map((f, i) => (
          <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: 8, background: 'var(--id-surface-alt)', borderRadius: 8 }}>
            <window.Icon name="archive" size={14} />
            <div style={{ flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontSize: 13 }}>{f.name}</div>
            <span className="cmp-meta">{window.fmtBytes(f.size)}</span>
            <button className="icon-btn" onClick={() => removeAt(i)}><window.Icon name="x" size={12} /></button>
          </div>
        ))}
      </div>

      <label className="mini-label" style={{ marginTop: 14 }}>Archive name</label>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
        <input className="mini-input" value={name} onChange={(e) => setName(e.target.value)} />
        <span className="cmp-meta">.zip</span>
      </div>

      {err && <div style={{ color: '#c8321f', marginTop: 10 }}>{err}</div>}
      <div className="cmp-actions">
        <label className="btn btn-secondary">
          <window.Icon name="upload" size={16} /> Add more
          <input type="file" multiple hidden onChange={(e) => addFiles(Array.from(e.target.files))} />
        </label>
        <button className="btn btn-primary" onClick={run} disabled={busy}>
          <window.Icon name="archive" size={16} /> {busy ? 'Zipping…' : 'Download .zip'}
        </button>
      </div>
    </div>
  );
};
