// matrix-modal.jsx — Matrix Combiner (Launch Test) + CSV Import Modal
const { useState, useContext, useCallback } = React;

function MatrixModal({ onClose }) {
  const { state, dispatch } = useContext(window.AppCtx);
  const wsId = state.activeWorkspaceId;
  const comps = state.components.filter(c => c.workspaceId === wsId);
  const hooks = comps.filter(c => c.type === 'hook');
  const leads = comps.filter(c => c.type === 'lead');
  const bodies = comps.filter(c => c.type === 'body');

  const [selHooks, setSelHooks] = useState(new Set());
  const [selLeads, setSelLeads] = useState(new Set(['__none__']));
  const [selBodies, setSelBodies] = useState(new Set());
  const [preview, setPreview] = useState(null); // null = not generated yet
  const [startStatus, setStartStatus] = useState('Draft');
  const [step, setStep] = useState(1); // 1=select, 2=preview

  const toggle = (set, setFn, id) => setFn(s => {
    const n = new Set(s);
    n.has(id) ? n.delete(id) : n.add(id);
    return n;
  });

  const generate = () => {
    const hArr = [...selHooks];
    const lArr = [...selLeads];
    const bArr = [...selBodies];
    if (!hArr.length || !bArr.length) return;
    const items = [];
    for (const h of hArr) {
      for (const l of lArr) {
        for (const b of bArr) {
          const hId = h;
          const lId = l === '__none__' ? '' : l;
          const name = [hId, lId, b].filter(Boolean).join(' + ');
          items.push({ hookId: hId, leadId: lId, bodyId: b, name, status: startStatus, keep: true });
        }
      }
    }
    setPreview(items);
    setStep(2);
  };

  const commit = () => {
    const toAdd = preview.filter(p => p.keep).map(p => ({ hookId: p.hookId, leadId: p.leadId, bodyId: p.bodyId, name: p.name, status: startStatus }));
    if (!toAdd.length) return;
    dispatch({ type: 'ADD_COMBOS_BULK', combos: toAdd });
    onClose();
  };

  const CheckList = ({ items, selected, onToggle, noNoneOption }) => (
    <div className="matrix-list">
      {!noNoneOption && (
        <div className="matrix-item" onClick={() => onToggle('__none__')}>
          <input type="checkbox" readOnly checked={selected.has('__none__')} />
          <span style={{ fontStyle: 'italic', color: '#6a6a88', fontSize: 12 }}>No Lead</span>
        </div>
      )}
      {items.map(c => (
        <div key={c.id} className="matrix-item" onClick={() => onToggle(c.id)}>
          <input type="checkbox" readOnly checked={selected.has(c.id)} />
          <window.IdBadge id={c.id} />
          <span style={{ fontSize: 12, flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{c.description}</span>
          <window.StatusPill status={c.status} />
        </div>
      ))}
      {items.length === 0 && <div style={{ padding: '12px', color: '#3a3a58', fontSize: 12 }}>No items yet</div>}
    </div>
  );

  const totalCount = selHooks.size * selLeads.size * selBodies.size;

  return (
    <window.Modal
      title="⚡ Launch Test — Matrix Combiner"
      width={860}
      onClose={onClose}
      footer={
        step === 1 ? (
          <>
            <span style={{ color: '#4a4a68', fontSize: 12 }}>
              {totalCount > 0 ? `${selHooks.size} hooks × ${selLeads.size} leads × ${selBodies.size} bodies = ` : ''}
              {totalCount > 0 && <strong style={{ color: '#d4a839' }}>{totalCount} combos</strong>}
            </span>
            <div style={{ flex: 1 }} />
            <button className="btn btn-ghost btn-sm" onClick={onClose}>Cancel</button>
            <button className="btn btn-primary btn-sm" onClick={generate} disabled={!selHooks.size || !selBodies.size}>
              Generate Preview →
            </button>
          </>
        ) : (
          <>
            <span style={{ color: '#4a4a68', fontSize: 12 }}>{preview.filter(p => p.keep).length} combos selected</span>
            <div style={{ flex: 1 }} />
            <button className="btn btn-ghost btn-sm" onClick={() => setStep(1)}>← Back</button>
            <select className="filter-select" value={startStatus} onChange={e => setStartStatus(e.target.value)} style={{ marginRight: 4 }}>
              <option>Draft</option><option>Testing</option>
            </select>
            <button className="btn btn-primary btn-sm" onClick={commit} disabled={!preview.filter(p => p.keep).length}>
              Add {preview.filter(p => p.keep).length} to Kanban
            </button>
          </>
        )
      }
    >
      {step === 1 ? (
        <div className="matrix-cols">
          <div className="matrix-section">
            <h3>Hooks ({selHooks.size} selected)</h3>
            <CheckList items={hooks} selected={selHooks} onToggle={id => toggle(selHooks, setSelHooks, id)} noNoneOption />
          </div>
          <div className="matrix-section">
            <h3>Leads ({selLeads.size} selected)</h3>
            <CheckList items={leads} selected={selLeads} onToggle={id => toggle(selLeads, setSelLeads, id)} />
          </div>
          <div className="matrix-section">
            <h3>Bodies ({selBodies.size} selected)</h3>
            <CheckList items={bodies} selected={selBodies} onToggle={id => toggle(selBodies, setSelBodies, id)} noNoneOption />
          </div>
        </div>
      ) : (
        <div>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
            <span style={{ color: '#6a6a88', fontSize: 12 }}>Review generated combos. Uncheck any to exclude before committing.</span>
            <div style={{ display: 'flex', gap: 6 }}>
              <button className="btn btn-ghost btn-sm" onClick={() => setPreview(p => p.map(x => ({ ...x, keep: true })))}>Select All</button>
              <button className="btn btn-ghost btn-sm" onClick={() => setPreview(p => p.map(x => ({ ...x, keep: false })))}>Deselect All</button>
            </div>
          </div>
          <div className="matrix-preview">
            {preview.map((item, i) => (
              <div key={i} className="matrix-preview-item" style={{ opacity: item.keep ? 1 : .4 }}>
                <input type="checkbox" checked={item.keep} onChange={e => setPreview(p => p.map((x, j) => j === i ? { ...x, keep: e.target.checked } : x))} style={{ accentColor: 'var(--accent)', flexShrink: 0 }} />
                <div style={{ display: 'flex', gap: 4, flexShrink: 0 }}>
                  <window.IdBadge id={item.hookId} />
                  {item.leadId && <window.IdBadge id={item.leadId} />}
                  <window.IdBadge id={item.bodyId} />
                </div>
                <input
                  value={item.name}
                  onChange={e => setPreview(p => p.map((x, j) => j === i ? { ...x, name: e.target.value } : x))}
                  style={{ flex: 1, background: 'none', border: 'none', color: 'var(--tx)', fontSize: 12, outline: 'none' }}
                  onClick={e => e.stopPropagation()}
                />
                <button className="btn-icon" style={{ fontSize: 11 }} onClick={() => setPreview(p => p.filter((_, j) => j !== i))}>✕</button>
              </div>
            ))}
          </div>
        </div>
      )}
    </window.Modal>
  );
}

// ── CSV Import Modal ─────────────────────────────────────────────────────────

const COMP_FIELDS = ['description', 'script', 'videoLink', 'status', 'angle', 'notes', 'editingStatus'];
const COMBO_FIELDS = ['name', 'hookId', 'leadId', 'bodyId', 'status', 'launchDate', 'postId', 'notes'];

function CSVImportModal({ onClose }) {
  const { state, dispatch } = useContext(window.AppCtx);
  const [raw, setRaw] = useState('');
  const [parsed, setParsed] = useState(null); // { headers, rows }
  const [importType, setImportType] = useState('hook');
  const [mapping, setMapping] = useState({});
  const [step, setStep] = useState(1);

  const parseCSV = text => {
    const lines = text.trim().split('\n').filter(Boolean);
    if (lines.length < 2) return null;
    const parseRow = row => {
      const cells = []; let cur = ''; let inQ = false;
      for (let i = 0; i < row.length; i++) {
        const ch = row[i];
        if (ch === '"' && !inQ) { inQ = true; continue; }
        if (ch === '"' && inQ && row[i+1] === '"') { cur += '"'; i++; continue; }
        if (ch === '"' && inQ) { inQ = false; continue; }
        if (ch === ',' && !inQ) { cells.push(cur.trim()); cur = ''; continue; }
        cur += ch;
      }
      cells.push(cur.trim());
      return cells;
    };
    const headers = parseRow(lines[0]);
    const rows = lines.slice(1).map(l => {
      const cells = parseRow(l);
      const obj = {};
      headers.forEach((h, i) => obj[h] = cells[i] ?? '');
      return obj;
    });
    return { headers, rows };
  };

  const handleParse = () => {
    const result = parseCSV(raw);
    if (!result) return;
    setParsed(result);
    // Auto-map columns where header matches field name
    const auto = {};
    const fields = importType === 'hook' || importType === 'lead' || importType === 'body' ? COMP_FIELDS : COMBO_FIELDS;
    fields.forEach(f => {
      const match = result.headers.find(h => h.toLowerCase().replace(/[^a-z]/g,'') === f.toLowerCase());
      if (match) auto[f] = match;
    });
    setMapping(auto);
    setStep(2);
  };

  const commit = () => {
    if (!parsed) return;
    const fields = ['hook','lead','body'].includes(importType) ? COMP_FIELDS : COMBO_FIELDS;
    const rows = parsed.rows.map(r => {
      const obj = {};
      fields.forEach(f => { if (mapping[f]) obj[f] = r[mapping[f]] || ''; });
      return obj;
    }).filter(r => Object.values(r).some(v => v));

    if (['hook','lead','body'].includes(importType)) {
      rows.forEach(data => dispatch({ type: 'ADD_COMP', compType: importType, data }));
    } else {
      rows.forEach(data => dispatch({ type: 'ADD_COMBO', data }));
    }
    onClose();
  };

  const isComp = ['hook','lead','body'].includes(importType);
  const fields = isComp ? COMP_FIELDS : COMBO_FIELDS;

  return (
    <window.Modal
      title="Import from CSV"
      width={640}
      onClose={onClose}
      footer={
        step === 1 ? (
          <>
            <button className="btn btn-ghost btn-sm" onClick={onClose}>Cancel</button>
            <button className="btn btn-primary btn-sm" onClick={handleParse} disabled={!raw.trim()}>Parse →</button>
          </>
        ) : (
          <>
            <span style={{ color: '#4a4a68', fontSize: 12 }}>{parsed?.rows.length} rows detected</span>
            <div style={{ flex: 1 }} />
            <button className="btn btn-ghost btn-sm" onClick={() => setStep(1)}>← Back</button>
            <button className="btn btn-primary btn-sm" onClick={commit}>Import {parsed?.rows.length} rows</button>
          </>
        )
      }
    >
      {step === 1 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <window.Field label="Import as">
            <select className="fi" value={importType} onChange={e => setImportType(e.target.value)}>
              <option value="hook">Hooks</option>
              <option value="lead">Leads</option>
              <option value="body">Bodies</option>
              <option value="combo">Combos</option>
            </select>
          </window.Field>
          <window.Field label="Paste CSV data (include header row)">
            <textarea
              className="fi" value={raw} onChange={e => setRaw(e.target.value)}
              placeholder="description,status,angle,script&#10;Great opener,Testing,origin story,https://..." 
              style={{ minHeight: 180, fontFamily: 'var(--mono)', fontSize: 11 }}
              autoFocus
            />
          </window.Field>
        </div>
      )}
      {step === 2 && parsed && (
        <div>
          <p style={{ color: '#6a6a88', fontSize: 12, marginBottom: 16 }}>
            Map your CSV columns to fields. Columns not mapped will be ignored.
          </p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
            {fields.map(f => (
              <div key={f} className="import-map">
                <span style={{ fontSize: 12, fontWeight: 500, color: 'var(--tx)' }}>{f}</span>
                <span style={{ color: '#3a3a58', fontSize: 12 }}>←</span>
                <select className="filter-select" style={{ width: '100%' }} value={mapping[f] || ''}
                  onChange={e => setMapping(m => ({ ...m, [f]: e.target.value || undefined }))}>
                  <option value="">— ignore —</option>
                  {parsed.headers.map(h => <option key={h} value={h}>{h}</option>)}
                </select>
              </div>
            ))}
          </div>
          {parsed.rows.length > 0 && (
            <div style={{ marginTop: 16 }}>
              <div style={{ fontSize: 11, color: '#4a4a68', marginBottom: 6, textTransform: 'uppercase', letterSpacing: '.05em' }}>Preview (first 3 rows)</div>
              {parsed.rows.slice(0, 3).map((r, i) => (
                <div key={i} style={{ fontSize: 11, color: '#7070988', padding: '4px 0', borderBottom: '1px solid var(--bd)' }}>
                  {fields.filter(f => mapping[f]).map(f => `${f}: ${r[mapping[f]]}`).join('  ·  ')}
                </div>
              ))}
            </div>
          )}
        </div>
      )}
    </window.Modal>
  );
}

Object.assign(window, { MatrixModal, CSVImportModal });
