/* ============================================================
   바른셈 — 법정 산출물 (주휴·일할·연차·평균임금·퇴직금)
   Spec 02. 순수함수 커널(data.js)을 화면으로 노출. 계산은 단일 진입점 runFor만 경유(W0-1).
   ============================================================ */
function Statutory({ ctx }) {
  const B = window.BARUNSEM;
  const { clients, period } = ctx;
  const client = clients.find((c) => c.id === (ctx.params.clientId || clients[0].id)) || clients[0];
  const rs = ctx.rulesetFor(client.id);
  const asOf = period.payDate;                       // 산정 기준일 (귀속월 지급일)
  const hr = ctx.hrChangesOf(client.id);
  const [selId, setSelId] = useState(client.employees[0].id);
  const [sevFor, setSevFor] = useState(null);        // 퇴직금 모달 대상 근로자
  useEffect(() => { setSelId(client.employees[0].id); }, [client.id]);
  const e = client.employees.find((x) => x.id === selId) || client.employees[0];

  // 근로자 1인 파생값 — 통상시급·주휴는 커널 결과를 그대로 읽는다(화면단 재계산 금지, W0-1)
  const run = B.runFor(e, client, period.ym, rs);
  const oh = run.ordinaryHourly;
  const ten = B.tenure(e.joined, asOf);
  const fiscal = client.leave && client.leave.accrualBasis === "fiscal";
  const granted = B.annualLeaveDays(e.joined, asOf, { basis: (client.leave && client.leave.accrualBasis) || "hire", fiscalStart: client.leave && client.leave.fiscalStart });
  const remain = Math.max(0, granted - (e.leaveUsed || 0));
  const leaveAllow = B.annualLeaveAllowance(remain, oh, { promotionDone: client.leave && client.leave.promotionDone });
  const whp = run.weeklyHoliday ? run.weeklyHoliday.amount : 0;

  const flowIdx = window.BARUNSEM.FLOW.findIndex((f) => f.key === ctx.statusOf(client.id));
  const preCalc = flowIdx < 4;

  return (
    <div className="page page-wide rise">
      {preCalc && (
        <GateNotice icon="hourglass_top" title="계산 전 — 현재 입력 기준 산출입니다"
          body="주휴·일할·연차·퇴직금은 확정된 급여 결과 위에서 최종 확정됩니다. 검수·계산을 마치면 이 값이 고정됩니다."
          actionLabel="변동분 검수로" onAction={() => ctx.go("review", { clientId: client.id })} />
      )}
      <div className="page-head" style={{ marginBottom: 16 }}>
        <div className="page-title" style={{ fontSize: 19 }}>법정 산출물</div>
        <div className="page-desc">주휴·중도 일할·연차·평균임금·퇴직금 — 계산기·엑셀로 하던 반복 산출을 커널이 결정적으로 계산합니다. <b style={{ color: "var(--accent-ink)" }}>{period.label}</b> 기준일 {asOf}</div>
      </div>

      {/* 이번 달 중도 입·퇴사 일할 (고객사 단위) */}
      {hr.length > 0 && (
        <div className="card" style={{ marginBottom: 18 }}>
          <CardHead icon="event_repeat" title="이번 달 중도 입·퇴사 일할" sub={`분모 방식 · ${PRORATE_LABEL[client.prorateBasis] || "역일수"} (고객사 설정)`}
            right={<span className="tag tag-accent"><Ms name="settings" style={{ fontSize: 12 }} />{client.prorateBasis === "workdays" ? "소정근로일" : client.prorateBasis === "fixed30" ? "30일 고정" : "역일수"}</span>} />
          <table className="tbl tbl-cards">
            <thead><tr><th style={{ width: 80 }}>구분</th><th>근로자</th><th>일자</th><th className="r">재직일/분모</th><th className="r">월 급여</th><th className="r">일할 지급</th><th>4대보험</th></tr></thead>
            <tbody>
              {hr.map((x) => {
                const isJoin = x.kind === "join";
                const pro = B.prorate(x.base || 0, period.ym, isJoin ? x.date : null, isJoin ? null : x.date, client.prorateBasis);
                return (
                  <tr key={x.id}>
                    <td data-label="구분">{isJoin
                      ? <span className="pill pill-ok" style={{ height: 21 }}><Ms name="login" style={{ fontSize: 13 }} />입사</span>
                      : <span className="pill pill-warn" style={{ height: 21 }}><Ms name="logout" style={{ fontSize: 13 }} />퇴사</span>}</td>
                    <td data-label="근로자" style={{ fontWeight: 650 }}>{x.name}<div className="muted" style={{ fontSize: 11.5, fontWeight: 400 }}>{x.dept}{x.title ? " · " + x.title : ""}</div></td>
                    <td className="num" data-label="일자">{x.date}</td>
                    <td className="r num" data-label="재직일/분모">{pro.days} / {pro.denom}일</td>
                    <td className="r num" data-label="월 급여">{x.base ? KRW(x.base) : <span className="muted">—</span>}</td>
                    <td className="r num" data-label="일할 지급" style={{ fontWeight: 700 }}>{x.base ? KRW(pro.amount) : <span className="muted">기준액 미확정</span>}</td>
                    <td data-label="4대보험">{isJoin
                      ? <span className="tag tag-ok" style={{ height: 19 }}>취득월 부과</span>
                      : <span className="tag" style={{ height: 19 }}>상실월 미부과</span>}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      <div className="l-master" style={{ "--master": "264px" }}>
        {/* 근로자 리스트 */}
        <div className="card">
          <CardHead icon="groups" title="근로자" sub={`${client.employees.length}명`} />
          <div className="pick-list" style={{ maxHeight: 620, overflowY: "auto" }}>
            {client.employees.map((emp) => {
              const t2 = B.tenure(emp.joined, asOf);
              return (
                <button key={emp.id} onClick={() => setSelId(emp.id)} style={{
                  display: "flex", alignItems: "center", gap: 11, padding: "12px 16px", width: "100%", textAlign: "left", border: "none",
                  borderBottom: "1px solid var(--line)", background: emp.id === selId ? "var(--accent-soft)" : "transparent", cursor: "pointer",
                  borderLeft: emp.id === selId ? "3px solid var(--accent)" : "3px solid transparent",
                }}>
                  <div className="avatar" style={{ width: 32, height: 32, fontSize: 12, background: "var(--bg-sunken)", color: "var(--ink-2)" }}>{emp.name[0]}</div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontWeight: 650, fontSize: 13.5 }}>{emp.name}</div>
                    <div className="muted" style={{ fontSize: 11.5 }}>{emp.scheme} · 근속 {t2 ? t2.label : "—"}</div>
                  </div>
                  {emp.hourlyMode && <span className="tag" style={{ height: 18, fontSize: 10 }}>시급</span>}
                </button>
              );
            })}
          </div>
        </div>

        {/* 상세 */}
        <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
          {/* 헤더 */}
          <div className="card card-pad" style={{ display: "flex", alignItems: "center", gap: 14, flexWrap: "wrap" }}>
            <div className="avatar" style={{ width: 44, height: 44, fontSize: 16 }}>{e.name[0]}</div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontWeight: 700, fontSize: 16 }}>{e.name} <span className="muted" style={{ fontWeight: 500, fontSize: 13 }}>· {e.dept} · {e.title}</span></div>
              <div className="muted" style={{ fontSize: 12.5, marginTop: 2 }}>입사 {e.joined || "—"} · 근속 <b style={{ color: "var(--ink-2)" }}>{ten ? ten.label : "—"}</b> · 통상시급 {KRW(oh)}원</div>
            </div>
            <button className="btn btn-primary" onClick={() => setSevFor(e)}><Ms name="savings" />퇴직금 산출</button>
          </div>

          {/* 연차 */}
          <div className="card">
            <CardHead icon="beach_access" title="연차 휴가" sub="근기법 §60 · 근속 기반 자동 산정"
              right={<span className="tag tag-accent" title="부여방식 — 고객사 설정(RB-LEAVE)"><Ms name="event_available" style={{ fontSize: 12 }} />{fiscal ? "회계연도 기준" : "입사일 기준"}</span>} />
            <div className="card-pad" style={{ display: "flex", gap: 14, flexWrap: "wrap" }}>
              <StatBox label="발생 연차" value={granted + "일"} note={ten && ten.totalMonths < 12 ? "1년 미만 · 월 1일" : "15일 + 가산 " + Math.max(0, granted - 15) + "일"} accent />
              <Ms name="remove" style={{ color: "var(--ink-4)", alignSelf: "center" }} />
              <StatBox label="사용" value={(e.leaveUsed || 0) + "일"} note="당해 소진" />
              <Ms name="drag_handle" style={{ color: "var(--ink-4)", alignSelf: "center", transform: "rotate(90deg)" }} />
              <StatBox label="잔여" value={remain + "일"} note="미사용" />
              <Ms name="east" style={{ color: "var(--ink-4)", alignSelf: "center" }} />
              <StatBox label="연차미사용수당 (예상)" value={KRW(leaveAllow) + "원"} note={`잔여 ${remain}일 × 8h × 통상시급`} ok />
            </div>
            {fiscal && (
              <div style={{ margin: "0 22px 16px", display: "flex", gap: 8, alignItems: "center", padding: "9px 12px", background: "var(--warn-soft)", border: "1px solid var(--warn-line)", borderRadius: 8 }}>
                <Ms name="info" style={{ fontSize: 17, color: "color-mix(in oklab, var(--warn) 65%, black)" }} />
                <span style={{ fontSize: 12, color: "color-mix(in oklab, var(--warn) 50%, black)" }}>회계연도({client.leave.fiscalStart}) 부여 — 중도 입사자는 첫 해 <b>비례 부여</b> 후 다음 회계연도부터 정상. {client.leave.promotionDone ? "연차촉진 이행 → 미사용수당 소멸." : ""}</span>
              </div>
            )}
          </div>

          {/* 주휴수당 (시급제) */}
          {e.hourlyMode ? (
            <div className="card">
              <CardHead icon="weekend" title="주휴수당" sub="근기법 §55 · 주 15h 이상 + 개근" />
              <div className="card-pad" style={{ display: "flex", gap: 14, flexWrap: "wrap", alignItems: "center" }}>
                <StatBox label="주 소정근로" value={e.weeklyHours + "h"} note={e.weeklyHours < 15 ? "15h 미만 — 미발생" : "비례 " + (Math.min(e.weeklyHours, 40) / 40 * 8).toFixed(1) + "h"} />
                <Ms name="close" style={{ color: "var(--ink-4)", alignSelf: "center", fontSize: 16 }} />
                <StatBox label="통상시급" value={KRW(e.hourly) + "원"} />
                <Ms name="east" style={{ color: "var(--ink-4)", alignSelf: "center" }} />
                <StatBox label="월 주휴수당" value={KRW(whp) + "원"} note={whp ? "주휴 × 4.345주" : "개근·15h 미달"} accent={whp > 0} />
                {e.fullAttendance === false && <span className="tag tag-warn" style={{ alignSelf: "center" }}><Ms name="warning" style={{ fontSize: 12 }} />결근 — 주휴 0</span>}
              </div>
            </div>
          ) : (
            <div className="card card-pad" style={{ display: "flex", gap: 11, alignItems: "center", color: "var(--ink-3)" }}>
              <Ms name="weekend" style={{ fontSize: 19, color: "var(--ink-4)" }} />
              <span style={{ fontSize: 13 }}>월급·연봉제 — 월 소정근로 {rs.workHours}h에 <b>주휴 포함</b>. 별도 가산 없음.</span>
            </div>
          )}
        </div>
      </div>

      {sevFor && <SeveranceModal e={sevFor} client={client} ym={period.ym} rs={rs} asOf={asOf} leaveAllow={leaveAllow} onClose={() => setSevFor(null)} />}
    </div>
  );
}

const PRORATE_LABEL = { calendar: "역일수", workdays: "소정근로일", fixed30: "30일 고정" };

function StatBox({ label, value, note, accent, ok }) {
  return (
    <div style={{ background: accent ? "var(--accent)" : ok ? "var(--ok-soft)" : "var(--surface)", color: accent ? "#fff" : "var(--ink)", border: accent ? "none" : "1px solid " + (ok ? "var(--ok-line)" : "var(--line-2)"), borderRadius: 11, padding: "11px 16px", minWidth: 120, boxShadow: accent ? "var(--sh-1)" : "none" }}>
      <div style={{ fontSize: 11.5, fontWeight: 600, color: accent ? "rgba(255,255,255,.85)" : ok ? "color-mix(in oklab, var(--ok) 80%, black)" : "var(--ink-3)" }}>{label}</div>
      <div className="num" style={{ fontSize: 21, fontWeight: 750, letterSpacing: "-0.02em", marginTop: 2, color: ok ? "color-mix(in oklab, var(--ok) 82%, black)" : "inherit" }}>{value}</div>
      {note && <div style={{ fontSize: 10.5, opacity: .78, marginTop: 1 }}>{note}</div>}
    </div>
  );
}

/* 퇴직금 산출 모달 — 평균임금 vs 통상일급 → 퇴직금 (퇴직연금 유형 분기) */
function SeveranceModal({ e, client, ym, rs, asOf, leaveAllow, onClose }) {
  const B = window.BARUNSEM;
  const run = B.runFor(e, client, ym, rs);
  const oh = run.ordinaryHourly;
  const ten = B.tenure(e.joined, asOf);
  const periodDays = days3m(asOf);
  const last3mTotal = run.gross * 3;                          // 근사: 당월 × 3 (실데이터 없을 때)
  const aw = B.averageWage(last3mTotal, periodDays, leaveAllow, e.bonusAnnual, oh);
  const type = e.retirementType || "ira";
  const sev = B.severancePay(aw.value, e.joined, asOf, { weeklyHours: e.weeklyHours });
  const dc = B.dcContribution(run.gross * 12);
  const TYPE = { ira: "퇴직금 (사내)", dc: "퇴직연금 DC형", db: "퇴직연금 DB형" };

  return (
    <Modal title="퇴직금 산출" onClose={onClose} width={620}
      footer={<button className="btn btn-default" onClick={onClose}>닫기</button>}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 14, flexWrap: "wrap" }}>
        <b style={{ fontSize: 14 }}>{e.name}</b>
        <span className="muted" style={{ fontSize: 12.5 }}>입사 {e.joined} · 근속 {ten ? ten.label : "—"} · 사유발생일 {asOf}</span>
        <span className="pill pill-info" style={{ marginLeft: "auto" }}><Ms name="account_balance" style={{ fontSize: 13 }} />{TYPE[type]}</span>
      </div>

      {!sev.eligible && type !== "dc" ? (
        <div style={{ display: "flex", gap: 11, alignItems: "center", padding: "16px 18px", background: "var(--warn-soft)", border: "1px solid var(--warn-line)", borderRadius: 10 }}>
          <Ms name="block" style={{ fontSize: 22, color: "color-mix(in oklab, var(--warn) 65%, black)" }} />
          <div style={{ fontSize: 13, color: "color-mix(in oklab, var(--warn) 48%, black)" }}><b>퇴직금 대상 아님</b> — 계속근로 1년 미만(근속 {ten ? ten.label : "—"}). 1년 이상 + 주 15h 이상부터 발생합니다.</div>
        </div>
      ) : type === "dc" ? (
        <div>
          <div style={{ display: "flex", gap: 12, flexWrap: "wrap", marginBottom: 14 }}>
            <StatBox label="연간 임금총액 (근사)" value={KRW(run.gross * 12) + "원"} note="당월 × 12" />
            <Ms name="east" style={{ color: "var(--ink-4)", alignSelf: "center" }} />
            <StatBox label="DC 연간 부담금" value={KRW(dc) + "원"} note="연간임금총액 ÷ 12" accent />
          </div>
          <div className="muted" style={{ fontSize: 12, lineHeight: 1.6 }}>
            <b>DC형(확정기여)</b>은 매년 연간임금총액의 1/12를 사용자가 부담금으로 납입합니다. 퇴직 시점 평균임금 산정이 불필요하며, 운용 손익은 근로자에게 귀속됩니다. 위 금액은 이번 연도 납입 부담금 추정.
          </div>
        </div>
      ) : (
        <div>
          {/* 평균임금 vs 통상일급 */}
          <div style={{ fontSize: 11.5, fontWeight: 700, color: "var(--ink-3)", letterSpacing: ".03em", marginBottom: 8 }}>① 1일 평균임금 산정 (통상일급 하한 비교)</div>
          <table className="tbl tbl-cards" style={{ fontSize: 12.5, marginBottom: 16 }}>
            <tbody>
              <tr><td>사유발생일 이전 3개월 임금총액</td><td className="r num">{KRW(last3mTotal)}원</td></tr>
              <tr><td>+ 연차수당 3/12 · 상여 연액 3/12</td><td className="r num">{KRW(Math.round(leaveAllow * 3 / 12) + Math.round((e.bonusAnnual || 0) * 3 / 12))}원</td></tr>
              <tr><td>÷ 기간 총 역일수</td><td className="r num">{periodDays}일</td></tr>
              <tr style={{ background: "var(--surface-2)" }}><td style={{ fontWeight: 650 }}>1일 평균임금</td><td className="r num" style={{ fontWeight: 700 }}>{KRW(aw.avg)}원</td></tr>
              <tr><td>통상일급 (8h × 통상시급) <span className="muted">— 하한</span></td><td className="r num">{KRW(aw.ordinaryDaily)}원</td></tr>
              <tr style={{ background: "var(--accent-soft)" }}><td style={{ fontWeight: 700, color: "var(--accent-ink)" }}>적용 평균임금 {aw.floored && <span className="tag tag-warn" style={{ height: 18, fontSize: 10 }}>통상일급 하한 적용</span>}</td><td className="r num" style={{ fontWeight: 800, color: "var(--accent-ink)" }}>{KRW(aw.value)}원</td></tr>
            </tbody>
          </table>

          <div style={{ fontSize: 11.5, fontWeight: 700, color: "var(--ink-3)", letterSpacing: ".03em", marginBottom: 8 }}>② 퇴직금 = 평균임금 × 30 × (재직일수 ÷ 365)</div>
          <div style={{ display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap", marginBottom: 6 }}>
            <CalcChipMini label="평균임금" value={KRW(aw.value)} />
            <Ms name="close" style={{ color: "var(--ink-4)", fontSize: 15 }} />
            <CalcChipMini label="30일" value="30" />
            <Ms name="close" style={{ color: "var(--ink-4)", fontSize: 15 }} />
            <CalcChipMini label="재직일수 ÷ 365" value={sev.days + " / 365"} />
          </div>
          <div style={{ marginTop: 10, padding: "16px 20px", background: "var(--accent)", borderRadius: 12, display: "flex", alignItems: "center", justifyContent: "space-between", color: "#fff" }}>
            <div><div style={{ fontSize: 12.5, opacity: .85 }}>예상 퇴직금</div><div style={{ fontSize: 11.5, opacity: .7, marginTop: 1 }}>{type === "db" ? "DB형 — 퇴직금과 동일 산식" : "사내 적립"}</div></div>
            <div className="num" style={{ fontSize: 26, fontWeight: 800, letterSpacing: "-0.03em" }}>{KRW(sev.amount)}원</div>
          </div>
          <div className="muted" style={{ fontSize: 11, marginTop: 10, lineHeight: 1.55 }}>
            3개월 임금총액은 당월×3 근사입니다(실 산정 시 직전 3개월 확정 임금 사용). 평균임금이 통상일급보다 낮으면 통상일급으로 대체되어 저임금 월 직후 퇴직 시 과소산정을 방지합니다.
          </div>
        </div>
      )}
    </Modal>
  );
}

function CalcChipMini({ label, value }) {
  return (
    <div style={{ background: "var(--surface)", border: "1px solid var(--line-2)", borderRadius: 9, padding: "7px 13px", textAlign: "center" }}>
      <div style={{ fontSize: 10.5, color: "var(--ink-3)", fontWeight: 600 }}>{label}</div>
      <div className="num" style={{ fontSize: 15, fontWeight: 750 }}>{value}</div>
    </div>
  );
}

// 사유발생일 이전 3개월 총 역일수 (결정적)
function days3m(asOf) {
  const d = new Date(asOf); let total = 0;
  for (let i = 1; i <= 3; i++) { const last = new Date(d.getFullYear(), d.getMonth() - i + 1, 0); total += last.getDate(); }
  return total;
}

Object.assign(window, { Statutory });
