// 요약 사이드바 · 미리보기 · 엑셀 내보내기 (window.EstSummary)
const sWon = window.EstCalc.won;
const sNum = window.EstCalc.num;

const tbBtn = { padding: '7px 13px', fontSize: 13, fontWeight: 700, border: '1px solid var(--line-strong)', borderRadius: 8, background: 'var(--surface)', color: 'var(--ink-2)' };
const toastS = { position: 'fixed', bottom: 26, left: '50%', transform: 'translateX(-50%)', zIndex: 100, background: 'var(--ink)', color: '#fff', padding: '10px 18px', borderRadius: 10, fontSize: 13, fontWeight: 600, boxShadow: 'var(--shadow-lg)' };

/* ---------------- 요약 사이드바 ---------------- */
function SummarySidebar({ est, calc, setEst, showSettings, setShowSettings }) {
  const setFormula = (patch) => setEst((e) => ({ ...e, formula: { ...e.formula, ...patch } }));
  const toggleExp = (key, on) => setFormula({ enabled: { ...est.formula.enabled, [key]: on } });
  const setRate = (key, v) => setFormula({ rate: { ...est.formula.rate, [key]: v } });

  return (
    <div style={{ width: 350, flex: 'none', position: 'sticky', top: 70, maxHeight: 'calc(100vh - 86px)', overflowY: 'auto', paddingRight: 2, paddingBottom: 8 }}>
      <div style={{ background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 14, boxShadow: 'var(--shadow)', overflow: 'hidden' }}>
        <div style={{ padding: '14px 16px 10px', borderBottom: '1px solid var(--line)' }}>
          <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--ink-3)', letterSpacing: '.03em' }}>실시간 견적</div>
        </div>

        {/* 공종별 미니 */}
        <div style={{ padding: '8px 16px', maxHeight: 220, overflowY: 'auto' }}>
          {calc.groups.filter((g) => g.rows.length).length === 0 && <div style={{ fontSize: 12.5, color: 'var(--ink-3)', padding: '10px 0' }}>아직 품목이 없습니다.</div>}
          {calc.groups.filter((g) => g.rows.length).map((g) => (
            <div key={g.gongjong} style={{ display: 'flex', justifyContent: 'space-between', padding: '4px 0', fontSize: 13 }}>
              <span style={{ color: 'var(--ink-2)' }}>{g.gongjong}</span>
              <span className="mono" style={{ fontWeight: 600 }}>{sWon(g.total)}</span>
            </div>
          ))}
        </div>

        <div style={{ borderTop: '1px solid var(--line)', padding: '12px 16px', background: 'var(--surface-2)' }}>
          <Line k="직접공사비" v={calc.direct} bold />
          <Line k="간접공사비 (보험·경비·설계)" v={calc.expenseTotal} sub onClick={() => setShowSettings(!showSettings)} />
          <Line k={`기업이윤 ${calc.profitRate}%`} v={calc.profit} />
          <Line k="합계" v={calc.hap} />
        </div>

        {/* 협의/절사 */}
        <div style={{ padding: '12px 16px', borderTop: '1px solid var(--line)' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>
            <span style={{ fontSize: 12, fontWeight: 700, color: 'var(--ink-3)' }}>공급가액 (절사·협의가)</span>
            {calc.nego ? <span className="mono" style={{ fontSize: 11.5, color: 'var(--danger)', fontWeight: 700 }}>{sWon(calc.nego)}</span> : null}
          </div>
          <input value={est.negotiated} onChange={(e) => setEst((x) => ({ ...x, negotiated: e.target.value }))} placeholder={sWon(Math.floor(calc.hap / 10000) * 10000)} className="mono"
            style={{ width: '100%', padding: '8px 10px', border: '1px solid var(--line-strong)', borderRadius: 8, textAlign: 'right', outline: 'none', fontSize: 14, fontWeight: 700 }} />
          <div style={{ display: 'flex', gap: 6, marginTop: 6 }}>
            <button onClick={() => setEst((x) => ({ ...x, negotiated: String(Math.floor(calc.hap / 10000) * 10000) }))} style={{ ...tbBtn, flex: 1, padding: '5px', fontSize: 11 }}>만원 절사</button>
            <button onClick={() => setEst((x) => ({ ...x, negotiated: String(Math.floor(calc.hap / 100000) * 100000) }))} style={{ ...tbBtn, flex: 1, padding: '5px', fontSize: 11 }}>십만원 절사</button>
            <button onClick={() => setEst((x) => ({ ...x, negotiated: '' }))} style={{ ...tbBtn, padding: '5px 8px', fontSize: 11 }}>초기화</button>
          </div>
        </div>

        <div style={{ padding: '14px 16px', background: 'var(--accent-soft)', borderTop: '1px solid var(--line)' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <span style={{ fontSize: 12, fontWeight: 700, color: 'var(--accent-ink)' }}>견적금액 (VAT별도)</span>
            <span style={{ fontSize: 11, color: 'var(--accent-ink)' }}>부가세 {sWon(calc.vat)}</span>
          </div>
          <div className="mono" style={{ fontSize: 26, fontWeight: 800, color: 'var(--accent-ink)', letterSpacing: '-0.01em' }}>₩ {sWon(calc.supply)}</div>
          <div style={{ fontSize: 12, color: 'var(--accent-ink)', marginTop: 2 }}>총금액(VAT포함) <b className="mono">₩ {sWon(calc.grand)}</b></div>
        </div>
      </div>

      {/* 경비 설정 */}
      <div style={{ marginTop: 12 }}>
        <button onClick={() => setShowSettings(!showSettings)} style={{ ...tbBtn, width: '100%', textAlign: 'left', display: 'flex', justifyContent: 'space-between' }}>
          <span>경비 · 부가세 · 마진 설정</span><span style={{ color: 'var(--ink-3)' }}>{showSettings ? '▲' : '▼'}</span>
        </button>
        {showSettings && (
          <div style={{ marginTop: 8, background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 12, padding: '12px 14px' }}>
            <div style={{ display: 'flex', gap: 10, marginBottom: 12 }}>
              <MiniNum label="기업이윤 %" value={est.formula.profitRate} onChange={(v) => setFormula({ profitRate: v })} />
              <MiniNum label="단가조정 %" value={est.formula.markup} onChange={(v) => setFormula({ markup: v })} />
              <MiniNum label="부가세 %" value={est.formula.vatRate} onChange={(v) => setFormula({ vatRate: v })} />
            </div>
            {calc.expenses.map((e) => (
              <div key={e.key} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '6px 0', borderTop: '1px solid var(--line)' }}>
                {e.optional
                  ? <input type="checkbox" checked={e.enabled} onChange={(ev) => toggleExp(e.key, ev.target.checked)} style={{ accentColor: 'var(--accent)', width: 15, height: 15, flex: 'none' }} />
                  : <span title="필수 항목" style={{ flex: 'none', width: 15, height: 15, borderRadius: 4, background: 'var(--accent-soft)', color: 'var(--accent-ink)', fontSize: 9, fontWeight: 800, display: 'grid', placeItems: 'center' }}>✓</span>}
                <span style={{ flex: 1, minWidth: 0, fontSize: 12.5, fontWeight: 600, color: e.enabled ? 'var(--ink)' : 'var(--ink-3)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{e.label}</span>
                <input value={e.rate} onChange={(ev) => setRate(e.key, ev.target.value)} className="mono"
                  style={{ width: 54, flex: 'none', padding: '4px 6px', border: '1px solid var(--line-strong)', borderRadius: 6, textAlign: 'right', fontSize: 12, outline: 'none' }} />
                <span style={{ fontSize: 11, color: 'var(--ink-3)', flex: 'none' }}>%</span>
              </div>
            ))}
            <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 8, lineHeight: 1.5 }}>✓ 표시는 항상 적용되는 필수 항목입니다. 체크박스 항목은 해제 시 제외(30일 미만 공사 등). 노인장기요양은 건강보험료 기준.</div>
          </div>
        )}
      </div>
    </div>
  );
}

function Line({ k, v, bold, sub, onClick }) {
  return (
    <div onClick={onClick} style={{ display: 'flex', justifyContent: 'space-between', padding: '3px 0', fontSize: bold ? 14 : 13, cursor: onClick ? 'pointer' : 'default' }}>
      <span style={{ color: bold ? 'var(--ink)' : 'var(--ink-2)', fontWeight: bold ? 700 : 500, textDecoration: sub ? 'underline dotted var(--line-strong)' : 'none' }}>{k}</span>
      <span className="mono" style={{ fontWeight: bold ? 800 : 600 }}>{sWon(v)}</span>
    </div>
  );
}
function MiniNum({ label, value, onChange }) {
  return (
    <label style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 3 }}>
      <span style={{ fontSize: 11, fontWeight: 600, color: 'var(--ink-3)', whiteSpace: 'nowrap' }}>{label}</span>
      <input value={value} onChange={(e) => onChange(e.target.value)} className="mono" style={{ width: '100%', padding: '6px 8px', border: '1px solid var(--line-strong)', borderRadius: 7, textAlign: 'right', outline: 'none', fontSize: 13 }} />
    </label>
  );
}

/* ---------------- 미리보기 ---------------- */
function PreviewArea({ est, calc }) {
  return (
    <div className="preview-wrap" style={{ background: 'var(--bg)', padding: '26px 0 80px' }}>
      <CoverPage est={est} c={calc} />
      <SummaryPage est={est} c={calc} />
      <DetailPage est={est} c={calc} />
    </div>
  );
}

/* ---------------- 엑셀 내보내기 (진짜 .xlsx, SheetJS) ---------------- */
window.exportExcel = function (est, calc) {
  if (!window.XLSX) { alert('엑셀 모듈을 불러오는 중입니다. 잠시 후 다시 시도해주세요.'); return; }
  const N = (n) => Math.round(n || 0);
  const aoa = [];
  aoa.push([`상세 견적서 - ${est.site.name || ''}`]);
  aoa.push([`${est.site.client || ''} 님 · ${est.site.py || ''}PY · ${est.site.date || ''}`]);
  aoa.push([]);
  aoa.push(['공종', '구분', '상세내용', '단위', '수량', '자재단가', '자재금액', '노무단가', '노무금액', '소계']);
  calc.groups.filter((g) => g.rows.length).forEach((g) => {
    g.rows.forEach((r) => {
      aoa.push([g.gongjong, r.gubun || '', r.name, r.unit, Number(r.qty) || 0, N(r.mat), N(r.matAmt), N(r.lab), N(r.labAmt), N(r.total)]);
    });
    aoa.push([`${g.gongjong} 소계`, '', '', '', '', '', N(g.matSum), '', N(g.labSum), N(g.total)]);
  });
  aoa.push([]);
  aoa.push(['직접공사비 소계', '', '', '', '', '', '', '', '', N(calc.direct)]);
  calc.expenses.forEach((e) => aoa.push([`${e.label} (${e.note})`, '', '', '', '', '', '', '', '', e.enabled ? N(e.amt) : 0]));
  aoa.push(['간접공사비 합계', '', '', '', '', '', '', '', '', N(calc.expenseTotal)]);
  aoa.push(['공사비계 (공통+직접+간접)', '', '', '', '', '', '', '', '', N(calc.gongsabikye)]);
  aoa.push([`기업이윤 (직접공사비 ${calc.profitRate}%)`, '', '', '', '', '', '', '', '', N(calc.profit)]);
  aoa.push(['합계', '', '', '', '', '', '', '', '', N(calc.hap)]);
  aoa.push(['공급가액 (만원절사/NEGO)', '', '', '', '', '', '', '', '', N(calc.supply)]);
  aoa.push([`부가세 ${est.formula.vatRate}%`, '', '', '', '', '', '', '', '', N(calc.vat)]);
  aoa.push(['총금액 (부가세 포함)', '', '', '', '', '', '', '', '', N(calc.grand)]);

  const ws = XLSX.utils.aoa_to_sheet(aoa);
  ws['!cols'] = [{ wch: 10 }, { wch: 8 }, { wch: 30 }, { wch: 6 }, { wch: 6 }, { wch: 12 }, { wch: 12 }, { wch: 12 }, { wch: 12 }, { wch: 13 }];
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, '견적서');
  XLSX.writeFile(wb, `가견적_${(est.site.name || '무제').slice(0, 20)}_${est.site.date}.xlsx`);
};

window.EstSummary = { SummarySidebar, PreviewArea, tbBtn, toastS };
