// 에디터 하위 컴포넌트들 (window.EstEditor)
const { useState, useEffect, useMemo, useRef } = React;
const ecWon = window.EstCalc.won;

/* ---------- 공통 인풋 ---------- */
function Field({ label, value, onChange, ph, w, mono }) {
  return (
    <label style={{ display: 'flex', flexDirection: 'column', gap: 4, width: w || 'auto', flex: w ? 'none' : 1 }}>
      <span style={{ fontSize: 11, fontWeight: 600, color: 'var(--ink-3)', letterSpacing: '.02em' }}>{label}</span>
      <input value={value || ''} placeholder={ph} onChange={(e) => onChange(e.target.value)}
        className={mono ? 'mono' : ''}
        style={{
          padding: '8px 10px', border: '1px solid var(--line-strong)', borderRadius: 7,
          background: 'var(--surface)', outline: 'none', fontSize: 13.5,
        }}
        onFocus={(e) => e.target.style.borderColor = 'var(--accent)'}
        onBlur={(e) => e.target.style.borderColor = 'var(--line-strong)'} />
    </label>
  );
}

/* ---------- 품목 검색·추가 ---------- */
function ItemSearch({ onAdd }) {
  const [q, setQ] = useState('');
  const [open, setOpen] = useState(false);
  const boxRef = useRef(null);
  const results = useMemo(() => {
    const t = q.trim();
    if (!t) return [];
    const toks = t.split(/\s+/);
    return window.DICT
      .map((d) => {
        const hay = (d.gongjong + ' ' + d.name).toLowerCase();
        let score = 0;
        for (const tok of toks) { if (!hay.includes(tok.toLowerCase())) return null; }
        if (d.name.toLowerCase().startsWith(t.toLowerCase())) score += 100;
        score += d.count;
        return { d, score };
      })
      .filter(Boolean)
      .sort((a, b) => b.score - a.score)
      .slice(0, 40)
      .map((x) => x.d);
  }, [q]);

  useEffect(() => {
    const h = (e) => { if (boxRef.current && !boxRef.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', h);
    return () => document.removeEventListener('mousedown', h);
  }, []);

  const add = (d, basis) => {
    onAdd(d, basis);
    setQ(''); setOpen(false);
  };

  return (
    <div ref={boxRef} style={{ position: 'relative' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '0 12px', background: 'var(--surface)', border: '1.5px solid var(--accent)', borderRadius: 9, boxShadow: '0 0 0 4px var(--accent-soft)' }}>
        <span style={{ color: 'var(--accent)', fontSize: 16 }}>⌕</span>
        <input value={q} onChange={(e) => { setQ(e.target.value); setOpen(true); }} onFocus={() => setOpen(true)}
          placeholder="품목·공종으로 검색해 추가 (예: 도배, 포세린, 매립수전)"
          style={{ flex: 1, border: 'none', outline: 'none', padding: '12px 0', background: 'transparent', fontSize: 14 }} />
        {q && <button onClick={() => { setQ(''); }} style={chipBtn}>지우기</button>}
      </div>
      {open && results.length > 0 && (
        <div style={{ position: 'absolute', top: 'calc(100% + 6px)', left: 0, right: 0, zIndex: 30, background: 'var(--surface)', border: '1px solid var(--line-strong)', borderRadius: 10, boxShadow: 'var(--shadow-lg)', maxHeight: 380, overflowY: 'auto', padding: 6 }}>
          {results.map((d) => (
            <ResultRow key={d.id} d={d} onAdd={add} />
          ))}
        </div>
      )}
      {open && q.trim() && results.length === 0 && (
        <div style={{ position: 'absolute', top: 'calc(100% + 6px)', left: 0, right: 0, zIndex: 30, background: 'var(--surface)', border: '1px solid var(--line-strong)', borderRadius: 10, boxShadow: 'var(--shadow-lg)', padding: 16, fontSize: 13, color: 'var(--ink-3)' }}>
          “{q}” 사전에 없음 ·{' '}
          <button onClick={() => add({ gongjong: '기타공사', name: q.trim(), unit: 'EA', mat: null, lab: null, count: 0 }, 'recent')} style={{ ...chipBtn, color: 'var(--accent)', borderColor: 'var(--accent)' }}>직접 품목으로 추가 →</button>
        </div>
      )}
    </div>
  );
}

function ResultRow({ d, onAdd }) {
  const price = d.mat?.recent || d.lab?.recent || 0;
  const stat = d.mat || d.lab;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 10px', borderRadius: 7, cursor: 'pointer' }}
      onClick={() => onAdd(d, 'recent')}
      onMouseEnter={(e) => e.currentTarget.style.background = 'var(--surface-2)'}
      onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
      <span style={gBadge(d.gongjong)}>{d.gongjong.replace('공사', '')}</span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13.5, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{d.name}</div>
        <div style={{ fontSize: 11, color: 'var(--ink-3)' }} className="mono">
          {d.unit} · {d.mat ? '자재 ' + ecWon(d.mat.recent) : ''}{d.mat && d.lab ? ' / ' : ''}{d.lab ? '노무 ' + ecWon(d.lab.recent) : ''}
          {stat && stat.n > 1 ? <span style={{ color: 'var(--ink-3)' }}>　범위 {ecWon(stat.min)}~{ecWon(stat.max)}</span> : ''}
        </div>
      </div>
      {d.count > 0 && <span style={{ fontSize: 10.5, color: 'var(--ink-3)', background: 'var(--surface-2)', border: '1px solid var(--line)', padding: '2px 7px', borderRadius: 20, whiteSpace: 'nowrap' }} className="mono">{d.count}회</span>}
      <span style={{ color: 'var(--accent)', fontWeight: 700, fontSize: 18 }}>+</span>
    </div>
  );
}

/* ---------- 공종 섹션 ---------- */
function GroupSection({ group, calcGroup, onRow, onDelRow, onAddAll, onDelGroup }) {
  const [open, setOpen] = useState(true);
  return (
    <div style={{ border: '1px solid var(--line)', borderRadius: 12, marginBottom: 12, background: 'var(--surface)', overflow: 'hidden' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '11px 14px', background: 'var(--surface-2)', borderBottom: open ? '1px solid var(--line)' : 'none', cursor: 'pointer' }} onClick={() => setOpen(!open)}>
        <span style={{ color: 'var(--ink-3)', fontSize: 11, transform: open ? 'rotate(90deg)' : 'none', transition: '.15s' }}>▶</span>
        <span style={gBadge(group.gongjong)}>{group.gongjong.replace('공사', '')}</span>
        <span style={{ fontWeight: 700, fontSize: 14 }}>{group.gongjong}</span>
        <span style={{ fontSize: 12, color: 'var(--ink-3)' }}>{group.rows.length}개 품목</span>
        <span style={{ flex: 1 }} />
        <span className="mono" style={{ fontWeight: 700, fontSize: 14 }}>₩ {ecWon(calcGroup.total)}</span>
        <button className="no-print" onClick={(e) => { e.stopPropagation(); onDelGroup(); }} style={{ ...iconBtn, marginLeft: 4 }} title="공종 삭제">✕</button>
      </div>
      {open && (
        <div style={{ overflowX: 'auto' }}>
          <table style={{ width: '100%', minWidth: 680, borderCollapse: 'collapse' }}>
            <thead>
              <tr style={{ fontSize: 11, color: 'var(--ink-3)' }}>
                <th style={{ ...hCell('left'), width: 76 }}>구분</th>
                <th style={{ ...hCell('left'), width: 'auto', minWidth: 150 }}>상세내용</th>
                <th style={{ ...hCell('center'), width: 50 }}>단위</th>
                <th style={{ ...hCell('center'), width: 52 }}>수량</th>
                <th style={{ ...hCell('right'), width: 96 }}>자재단가</th>
                <th style={{ ...hCell('right'), width: 96 }}>노무단가</th>
                <th style={{ ...hCell('right'), width: 102 }}>합계</th>
                <th style={{ width: 28 }} className="no-print"></th>
              </tr>
            </thead>
            <tbody>
              {calcGroup.rows.map((r, i) => (
                <RowEdit key={i} r={r} onRow={(patch) => onRow(i, patch)} onDel={() => onDelRow(i)} />
              ))}
            </tbody>
          </table>
          {group.rows.length === 0 && (
            <div style={{ padding: '14px', textAlign: 'center' }}>
              <button onClick={onAddAll} style={{ ...chipBtn, color: 'var(--accent)', borderColor: 'var(--accent)' }}>＋ {group.gongjong} 자주 쓰는 품목 일괄 불러오기</button>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function RowEdit({ r, onRow, onDel }) {
  return (
    <tr style={{ borderTop: '1px solid var(--line)' }}>
      <td style={{ padding: '4px 4px 4px 14px', verticalAlign: 'top' }}>
        <input value={r.gubun || ''} onChange={(e) => onRow({ gubun: e.target.value })} placeholder="—" className="cell-input" style={{ ...cellInput('left'), fontSize: 11.5, color: 'var(--ink-2)' }} />
      </td>
      <td style={{ padding: '4px 6px', minWidth: 150 }}>
        <input value={r.name} onChange={(e) => onRow({ name: e.target.value })} className="cell-input" style={{ ...cellInput('left'), minWidth: 150 }} />
        {r.cands && r.cands.length > 1 && (
          <select value={r.name} title="다른 제품으로 교체 (단가 자동)"
            onChange={(e) => { const c = r.cands.find((x) => x.name === e.target.value); if (c) onRow({ name: c.name, unit: c.unit || r.unit, mat: c.mat, lab: c.lab }); }}
            style={{ minWidth: 150, width: '100%', marginTop: 2, padding: '3px 5px', border: '1px solid var(--accent-line)', borderRadius: 6, fontSize: 11, fontWeight: 600, color: 'var(--accent-ink)', background: 'var(--accent-soft)', outline: 'none' }}>
            {r.cands.map((c) => <option key={c.gongjong + c.name} value={c.name}>🔁 {c.name} ({c.mat ? ecWon(c.mat) : '-'}{c.lab ? ' / ' + ecWon(c.lab) : ''})</option>)}
          </select>
        )}
        <input value={r.note || ''} onChange={(e) => onRow({ note: e.target.value })} placeholder="비고" className="cell-input" style={{ ...cellInput('left'), minWidth: 150, fontSize: 11, color: 'var(--ink-3)', padding: '1px 4px' }} />
      </td>
      <td style={{ padding: '4px 4px' }}><input value={r.unit} onChange={(e) => onRow({ unit: e.target.value })} className="cell-input" style={cellInput('center')} /></td>
      <td style={{ padding: '4px 4px' }}><input value={r.qty} onChange={(e) => onRow({ qty: e.target.value })} className="mono cell-input" style={cellInput('right')} /></td>
      <td style={{ padding: '4px 4px' }}>
        <input value={fmtNum(r.mat)} onChange={(e) => onRow({ mat: e.target.value.replace(/[^\d.]/g, '') })} className="mono cell-input" style={cellInput('right')} placeholder="0" inputMode="numeric" />
      </td>
      <td style={{ padding: '4px 4px' }}>
        <input value={fmtNum(r.lab)} onChange={(e) => onRow({ lab: e.target.value.replace(/[^\d.]/g, '') })} className="mono cell-input" style={cellInput('right')} placeholder="0" inputMode="numeric" />
      </td>
      <td className="mono" style={{ textAlign: 'right', padding: '4px 10px', fontWeight: 700, fontSize: 13.5 }}>{ecWon(r.total)}</td>
      <td className="no-print" style={{ textAlign: 'center' }}><button onClick={onDel} style={iconBtn}>✕</button></td>
    </tr>
  );
}

/* ---------- 스타일 헬퍼 ---------- */
const chipBtn = { padding: '5px 10px', fontSize: 12, border: '1px solid var(--line-strong)', borderRadius: 7, background: 'var(--surface)', color: 'var(--ink-2)', fontWeight: 600 };
const iconBtn = { width: 22, height: 22, borderRadius: 6, border: '1px solid transparent', background: 'transparent', color: 'var(--ink-3)', fontSize: 11, lineHeight: 1 };
function hCell(align) { return { textAlign: align, fontWeight: 600, padding: '7px 10px', borderBottom: '1px solid var(--line)', fontSize: 11 }; }
const subAmt = { textAlign: 'right', fontSize: 10.5, color: 'var(--ink-3)', paddingRight: 6, height: 12 };
function cellInput(align) {
  // 테두리/배경은 .cell-input CSS(:hover/:focus)가 담당 — 클릭 가능함을 시각적으로 표시
  return { width: '100%', borderRadius: 6, padding: '5px 7px', textAlign: align, outline: 'none', fontSize: 13, fontWeight: align === 'left' ? 600 : 400 };
}
// 단가 표시용 천단위 콤마 (저장은 숫자 문자열, 표시만 콤마)
function fmtNum(v) {
  const s = String(v == null ? '' : v).replace(/,/g, '');
  if (s === '') return '';
  if (!/^-?\d*\.?\d*$/.test(s)) return String(v);
  const [i, dec] = s.split('.');
  const f = i.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  return dec != null ? f + '.' + dec : f;
}
function gBadge(g) {
  const map = { 공통공사: 250, 철거공사: 25, 목공사: 75, 욕실공사: 210, 전기공사: 90, 도장공사: 320, 도배공사: 290, 타일공사: 180, 가구공사: 145, 필름공사: 50, 바닥공사: 35, 기타공사: 260 };
  const h = map[g] || 260;
  return { fontSize: 10.5, fontWeight: 700, padding: '2px 7px', borderRadius: 6, whiteSpace: 'nowrap', color: `oklch(0.42 0.12 ${h})`, background: `oklch(0.95 0.04 ${h})` };
}

window.EstEditor = { Field, ItemSearch, GroupSection, gBadge, chipBtn };
