import { useState, useMemo, useEffect } from 'react';
import { useAppState, useAppDispatch, useSelPanelRows, useSelVars } from '../context/AppContext.jsx';
import Header from '../components/Header.jsx';
import { showWarnToast } from '../components/Toast.jsx';

export default function Step4Mapping({ onNext, onBack, onNav }) {
  const state = useAppState();
  const dispatch = useAppDispatch();
  const selPanelRows = useSelPanelRows();
  const selVars = useSelVars();
  const { panelMap, panelCSV, _rMap } = state;

  const [panelQ, setPanelQ] = useState('');
  const [varQ, setVarQ] = useState('');

  const labelCol = panelCSV?.headers[0] || 'Panel';
  const pHeaders = panelCSV?.headers || [];

  // Restore from past result
  useEffect(() => {
    if (!_rMap || !_rMap.length) return;
    const newMap = { ...panelMap };
    selPanelRows.forEach(pr => {
      const pk = String(pr.__id);
      if (!newMap[pk]) newMap[pk] = {};
      const matched = _rMap.find(rec =>
        Object.entries(rec.panelData).some(([col, val]) => {
          if (!val) return false;
          const rowKey = Object.keys(pr).find(rk => rk.toLowerCase() === col.toLowerCase()) || col;
          return (pr[rowKey] || '').trim().toLowerCase() === val.toLowerCase();
        })
      );
      if (matched) {
        selVars.forEach(v => { newMap[pk][v] = true; });
        matched.removedVars.forEach(v => { newMap[pk][v] = false; });
      } else {
        selVars.forEach(v => { if (newMap[pk][v] === undefined) newMap[pk][v] = true; });
      }
    });
    dispatch({ type: 'SET_PANEL_MAP', payload: newMap });
    dispatch({ type: 'SET_RESTORE_BUFFERS', payload: { _rMap: null } });
  }, []);

  // Init panelMap for any missing panels/vars
  useEffect(() => {
    const newMap = { ...panelMap };
    let changed = false;
    selPanelRows.forEach(pr => {
      const pk = String(pr.__id);
      if (!newMap[pk]) { newMap[pk] = {}; changed = true; }
      selVars.forEach(v => {
        if (newMap[pk][v] === undefined) { newMap[pk][v] = true; changed = true; }
      });
    });
    if (changed) dispatch({ type: 'SET_PANEL_MAP', payload: newMap });
  }, [selPanelRows.length, selVars.length]);

  const visRows = useMemo(() =>
    selPanelRows.filter(pr => !panelQ || String(pr[labelCol] || String(pr.__id)).toLowerCase().includes(panelQ.toLowerCase()))
      .map(pr => ({ ...pr, key: String(pr.__id) }))
  , [selPanelRows, panelQ, labelCol]);

  const visCols = useMemo(() =>
    selVars.filter(v => !varQ || v.toLowerCase().includes(varQ.toLowerCase()))
  , [selVars, varQ]);

  function setCell(pk, varName, val) {
    const newMap = { ...panelMap, [pk]: { ...(panelMap[pk] || {}), [varName]: val } };
    dispatch({ type: 'SET_PANEL_MAP', payload: newMap });
  }

  function toggleRow(pk) {
    const cur = panelMap[pk] || {};
    const allOn = visCols.every(v => cur[v] === true);
    const newPk = { ...cur };
    visCols.forEach(v => { newPk[v] = !allOn; });
    dispatch({ type: 'SET_PANEL_MAP', payload: { ...panelMap, [pk]: newPk } });
  }

  function toggleCol(varName) {
    const allOn = visRows.every(r => (panelMap[r.key] || {})[varName] === true);
    const newMap = { ...panelMap };
    visRows.forEach(r => {
      newMap[r.key] = { ...(newMap[r.key] || {}), [varName]: !allOn };
    });
    dispatch({ type: 'SET_PANEL_MAP', payload: newMap });
  }

  function clearAll() {
    const newMap = { ...panelMap };
    selPanelRows.forEach(pr => {
      const pk = String(pr.__id);
      newMap[pk] = {};
      selVars.forEach(v => { newMap[pk][v] = false; });
    });
    dispatch({ type: 'SET_PANEL_MAP', payload: newMap });
  }

  const mappedCount = useMemo(() => {
    let n = 0;
    Object.values(panelMap).forEach(row => Object.values(row).forEach(v => { if (v === true) n++; }));
    return n;
  }, [panelMap]);

  const anyMapped = mappedCount > 0;

  return (
    <div className="page">
      <Header step={4} onNav={onNav} sub="Panel Mapping" />

      <div className="toolbar">
        <div style={{ position: 'relative', display: 'flex', alignItems: 'center', gap: 5 }}>
          <span style={{ fontSize: 9, fontWeight: 700, color: 'var(--mt)', fontFamily: 'var(--fm)', whiteSpace: 'nowrap' }}>Panels:</span>
          <div style={{ position: 'relative' }}>
            <svg style={{ position: 'absolute', left: 7, top: '50%', transform: 'translateY(-50%)', width: 10, height: 10, color: 'var(--mt)', pointerEvents: 'none' }} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="6.5" cy="6.5" r="4.5"/><path d="M10.5 10.5l3 3"/></svg>
            <input className="inp" value={panelQ} onChange={e => setPanelQ(e.target.value)} placeholder="Search panels…" style={{ paddingLeft: 22, width: 150, fontSize: 11 }} />
          </div>
        </div>
        <div style={{ flex: 1 }} />
        <div style={{ position: 'relative', display: 'flex', alignItems: 'center', gap: 5 }}>
          <span style={{ fontSize: 9, fontWeight: 700, color: 'var(--mt)', fontFamily: 'var(--fm)', whiteSpace: 'nowrap' }}>Variables:</span>
          <div style={{ position: 'relative' }}>
            <svg style={{ position: 'absolute', left: 7, top: '50%', transform: 'translateY(-50%)', width: 10, height: 10, color: 'var(--mt)', pointerEvents: 'none' }} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="6.5" cy="6.5" r="4.5"/><path d="M10.5 10.5l3 3"/></svg>
            <input className="inp" value={varQ} onChange={e => setVarQ(e.target.value)} placeholder="Search variables…" style={{ paddingLeft: 22, width: 150, fontSize: 11 }} />
          </div>
        </div>
        <span className="page-note">Mapped: <strong style={{ color: 'var(--g)' }}>{mappedCount}</strong></span>
        <button className="btn btn-sm btn-sec" onClick={clearAll}>Clear All</button>
      </div>

      <div className="mx-body">
        {!visCols.length || !visRows.length ? (
          <div style={{ padding: 36, textAlign: 'center', fontSize: 11.5, color: 'var(--mt)' }}>
            {!selVars.length ? 'No variables selected — go back to Page 2.'
              : !selPanelRows.length ? 'No panels selected — go back to Page 1.'
              : 'No results match filters.'}
          </div>
        ) : (
          <table className="m-tbl" style={{ tableLayout: 'fixed' }}>
            <thead>
              <tr>
                {pHeaders.map(h => (
                  <th key={h} className="pcol">
                    <div className="pth-inner"><span className="pth-lbl">{h}</span></div>
                  </th>
                ))}
                <th style={{ minWidth: 80, background: 'var(--bgs)', padding: 0, position: 'sticky', top: 0, zIndex: 4 }}>
                  <div className="row-hdr"><span style={{ fontSize: 8, color: 'var(--mt)', fontFamily: 'var(--fm)' }}>Toggle</span></div>
                </th>
                {visCols.map(varName => {
                  const allOn = visRows.every(r => (panelMap[r.key] || {})[varName] === true);
                  return (
                    <th key={varName}>
                      <div className="col-hdr">
                        <span className="col-hdr-nm" title={varName}>{varName}</span>
                        <button className={`col-tog${allOn ? ' on' : ''}`} onClick={() => toggleCol(varName)}>
                          {allOn ? 'Deselect' : 'Select all'}
                        </button>
                      </div>
                    </th>
                  );
                })}
              </tr>
            </thead>
            <tbody>
              {visRows.map(row => {
                const pk = row.key;
                const cur = panelMap[pk] || {};
                const rowAllOn = visCols.every(v => cur[v] === true);
                return (
                  <tr key={pk} className={rowAllOn ? 'row-full' : ''}>
                    {pHeaders.map(h => <td key={h} className="pdc" title={row[h]}>{row[h]}</td>)}
                    <td style={{ padding: '3px 6px', textAlign: 'center', background: '#fff', border: '1px solid var(--bl)' }}>
                      <button className={`row-tog${rowAllOn ? ' on' : ''}`} onClick={() => toggleRow(pk)}>
                        {rowAllOn ? 'Deselect' : 'All vars'}
                      </button>
                    </td>
                    {visCols.map(varName => {
                      const checked = cur[varName] === true;
                      return (
                        <td key={varName}>
                          <div className="m-cell" onClick={() => setCell(pk, varName, !checked)}>
                            <input type="checkbox" className="m-cb" checked={checked} onChange={e => setCell(pk, varName, e.target.checked)} onClick={e => e.stopPropagation()} />
                          </div>
                        </td>
                      );
                    })}
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
      </div>

      <div className="nav-foot">
        <button className="btn btn-sec" onClick={onBack}><svg width="9" height="9" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="2.3" strokeLinecap="round"><path d="M10 6H2M5 2L1 6l4 4"/></svg> Back</button>
        <button className="btn btn-pri" disabled={!anyMapped}
          onClick={() => { if (!anyMapped) { showWarnToast('Map at least 1 variable first.'); } else onNext(); }}>
          Proceed to Fixed Variables
          <svg width="10" height="10" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="2.3" strokeLinecap="round"><path d="M2 7h10M8 3l4 4-4 4"/></svg>
        </button>
      </div>
    </div>
  );
}
