// order-docs.jsx — 주문 문서함 (Order Document Archive)
// Order Document Archive v1 (Phase C, Spec 2026-05-06 §8 Q6).
// design family = 법인문서함 (cd-card / cd-detail / cd-reg-*) 재사용 — corp-docs.css import.
//
// Data source = window.__ORDER_DOCS_DATA__ (PageModel JSON inject).
// Phase 0: register modal 의 PDF 업로드 form action = T14 의 multipart endpoint
// (`/api/orders/{orderId}/documents`). T13 셸 자체는 form 만 emit, T14 가 endpoint 등록.

const { useState, useMemo, useEffect, useRef } = React;

const ORDER_DOCS_DATA = window.__ORDER_DOCS_DATA__ || {};
const ORDERS = ORDER_DOCS_DATA.orders || [];
const KINDS = ORDER_DOCS_DATA.kinds || [];
const SITE_TITLE = ORDER_DOCS_DATA.siteTitle || '결재일보';

const DOC_TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "dark": false,
  "showAmberOnly": false
}/*EDITMODE-END*/;

const SEVERITY_LABEL = {
  red: { label: '긴급', tone: 'negative' },
  amber: { label: '주의', tone: 'urgent' },
  ok: { label: '완료', tone: 'positive' },
};

function SeverityBadge({ severity }) {
  const cfg = SEVERITY_LABEL[severity] || SEVERITY_LABEL.amber;
  return <span className={`cd-badge cd-badge-${cfg.tone}`}>{cfg.label}</span>;
}

function OrderMasthead({ todayLabel }) {
  return (
    <header className="cd-masthead">
      <div className="cd-mast-top">
        <a href="/" className="cd-back">← {SITE_TITLE}</a>
        <span className="cd-mast-rule" />
        <span className="cd-mast-meta">附錄 · 注文</span>
        {todayLabel && <>
          <span className="cd-mast-rule" />
          <span className="cd-mast-meta">{todayLabel}</span>
        </>}
      </div>
      <div className="cd-title-row">
        <h1 className="cd-title">주&nbsp;&nbsp;문&nbsp;&nbsp;문&nbsp;&nbsp;서&nbsp;&nbsp;함</h1>
      </div>
      <div className="cd-mast-bot">
        <span>ORDERS · 證憑庫</span>
        <span className="cd-mast-motto">「주문별 5종 증빙. 누락은 즉시 보충.」</span>
        <span>paperless.kr 자동 첨부</span>
      </div>
    </header>
  );
}

function OrderCard({ order, onSelect, isSelected }) {
  const tone = order.severity === 'red' ? 'negative' : 'urgent';
  return (
    <article
      id={order.id}
      className={`cd-card ${isSelected ? 'is-selected' : ''} cd-card-${tone}`}
      onClick={() => onSelect(order.id)}
      role="button"
      tabIndex={0}
      onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onSelect(order.id); } }}
    >
      <div className="cd-card-head">
        <div className="cd-seal">注</div>
        <div className="cd-card-id">
          <div className="cd-code">ORDER · {order.externalOrderId}</div>
          <div className="cd-name">{order.missingDocs.length}건 증빙 누락</div>
          <div className="cd-name-en">{order.maxDaysOverdue}일 경과 · 최대 지연</div>
        </div>
        <SeverityBadge severity={order.severity} />
      </div>
      <dl className="cd-meta-list">
        {order.missingDocs.slice(0, 3).map((doc, i) => (
          <div key={i}>
            <dt>{doc.kindLabel}</dt>
            <dd className={doc.severity === 'red' ? 'cd-warn' : ''}>+{doc.daysOverdue}일</dd>
          </div>
        ))}
        {order.missingDocs.length > 3 && (
          <div>
            <dt>외</dt>
            <dd>{order.missingDocs.length - 3}건</dd>
          </div>
        )}
      </dl>
      <footer className="cd-card-foot">
        <span className="cd-pl is-off">
          <span className="cd-pl-dot" />
          미보충
        </span>
        <span className="cd-files">누락 {order.missingDocs.length}/5</span>
      </footer>
    </article>
  );
}

function OrderDetail({ order, onUploadClick }) {
  if (!order) {
    return (
      <aside className="cd-detail cd-detail-empty">
        <div className="cd-empty-mark">注</div>
        <p className="cd-empty-msg">좌측에서 주문을 선택하세요.</p>
        <p className="cd-empty-sub">미보충 주문 카드는 severity desc (긴급 → 주의) 로 정렬됩니다. 카드 진입 시 5종 증빙 누락/완료 매트릭스 + 1-click PDF 업로드.</p>
      </aside>
    );
  }
  const missingByKind = new Map(order.missingDocs.map((d) => [d.kind, d]));
  return (
    <aside className="cd-detail">
      <div className="cd-detail-head">
        <div className="cd-detail-kicker">ORDER · {order.externalOrderId}</div>
        <h2 className="cd-detail-title">증빙 매트릭스</h2>
        <div className="cd-detail-en">5종 / 누락 {order.missingDocs.length}건 · 최대 지연 {order.maxDaysOverdue}일</div>
      </div>

      <div className="cd-detail-section">
        <h3>5종 증빙 상태</h3>
        <dl className="cd-detail-grid">
          {KINDS.map((k) => {
            const miss = missingByKind.get(k.value);
            return (
              <div key={k.value}>
                <dt>{k.label}</dt>
                <dd>
                  {miss ? (
                    <span className={miss.severity === 'red' ? 'cd-warn' : ''}>
                      누락 · +{miss.daysOverdue}일
                    </span>
                  ) : (
                    <span className="cd-pl is-on">
                      <span className="cd-pl-dot" />
                      완료
                    </span>
                  )}
                </dd>
              </div>
            );
          })}
        </dl>
      </div>

      <div className="cd-detail-section">
        <h3>비고</h3>
        <p className="cd-note">
          누락 PDF 는 (A) 결재함 도켓 detail 의 1-click 인라인 또는
          (B) 본 페이지의 "새 PDF 등록" 버튼으로 보충할 수 있습니다.
          업로드 직후 paperless.kr 에 archive + Order.Documents 갱신.
        </p>
      </div>

      <div className="cd-detail-actions">
        <a className="cd-btn cd-btn-ghost" href={`/dockets/order/${order.id}`}>도켓 detail</a>
        <button className="cd-btn cd-btn-primary" onClick={() => onUploadClick(order)}>
          + 새 PDF 등록
        </button>
      </div>
    </aside>
  );
}

function RegisterPanel({ order, onClose }) {
  // Phase 0: native form submit (multipart) → T14 의 /api/orders/{id}/documents endpoint.
  // T13 단독 build 에서는 endpoint 가 아직 없으므로 운영자에게 안내.
  const initialKind = order?.missingDocs?.[0]?.kind || (KINDS[0] && KINDS[0].value) || 'forex';
  const [kind, setKind] = useState(initialKind);
  return (
    <div className="cd-reg-back" onClick={onClose}>
      <div className="cd-reg" onClick={(e) => e.stopPropagation()}>
        <header className="cd-reg-head">
          <div>
            <div className="cd-reg-kicker">登 · 錄</div>
            <h2 className="cd-reg-title">PDF 증빙 등록</h2>
          </div>
          <button className="cd-reg-x" onClick={onClose} aria-label="닫기">✕</button>
        </header>
        <form
          method="post"
          action={`/api/orders/${order.id}/documents`}
          encType="multipart/form-data"
        >
          <div className="cd-reg-body">
            <div className="cd-reg-field">
              <label>주문</label>
              <input type="text" value={`ORDER · ${order.externalOrderId}`} readOnly />
            </div>
            <div className="cd-reg-field">
              <label>증빙 종류</label>
              <select name="kind" value={kind} onChange={(e) => setKind(e.target.value)}>
                {KINDS.map((k) => {
                  const miss = order.missingDocs.find((d) => d.kind === k.value);
                  return (
                    <option key={k.value} value={k.value}>
                      {k.label}{miss ? ` (누락 · +${miss.daysOverdue}일)` : ''}
                    </option>
                  );
                })}
              </select>
            </div>
            <div className="cd-reg-drop">
              <div className="cd-reg-drop-mark">⇪</div>
              <div className="cd-reg-drop-text">
                <strong>PDF 파일 선택</strong>
                <span>application/pdf · 최대 20MB · paperless.kr 에 자동 archive</span>
                <input type="file" name="pdf" accept="application/pdf" required />
              </div>
            </div>
            <p className="cd-note">
              업로드 직후 Order.Documents 가 갱신되며, 결재일보 alert 에서 본 누락 항목이 사라집니다.
            </p>
          </div>
          <footer className="cd-reg-foot">
            <button type="button" className="cd-btn cd-btn-ghost" onClick={onClose}>취소</button>
            <button type="submit" className="cd-btn cd-btn-primary">📎 업로드</button>
          </footer>
        </form>
      </div>
    </div>
  );
}

function OrderDocs() {
  const [tweaks, setTweak] = useTweaks(DOC_TWEAK_DEFAULTS);
  const [selected, setSelected] = useState(ORDERS.length > 0 ? ORDERS[0].id : null);
  const [registerOrder, setRegisterOrder] = useState(null);
  const cardRefs = useRef({});

  useEffect(() => {
    document.body.dataset.theme = tweaks.dark ? 'dark' : 'light';
    document.body.classList.add('gazette-body');
    return () => document.body.classList.remove('gazette-body');
  }, [tweaks.dark]);

  // Hash anchor scroll-into-view + flash highlight (결재일보 alert click → /order-docs#{guid}).
  useEffect(() => {
    const handleHash = () => {
      const hash = (window.location.hash || '').replace(/^#/, '');
      if (!hash) return;
      const target = ORDERS.find((o) => o.id === hash);
      if (!target) return;
      setSelected(hash);
      // 다음 paint 후 scrollIntoView (DOM 가 mount 된 상태 보장).
      requestAnimationFrame(() => {
        const el = document.getElementById(hash);
        if (!el) return;
        el.scrollIntoView({ behavior: 'smooth', block: 'center' });
        // 신규 CSS 0 가이드 — inline style 로 2s flash. corp-docs.css 미수정.
        const prevBox = el.style.boxShadow;
        const prevTrans = el.style.transition;
        el.style.transition = 'box-shadow 0.4s ease-out';
        el.style.boxShadow = '0 0 0 4px rgba(255, 200, 0, 0.55)';
        setTimeout(() => {
          el.style.boxShadow = prevBox;
          setTimeout(() => { el.style.transition = prevTrans; }, 500);
        }, 2000);
      });
    };
    handleHash();
    window.addEventListener('hashchange', handleHash);
    return () => window.removeEventListener('hashchange', handleHash);
  }, []);

  const filtered = useMemo(() => {
    if (tweaks.showAmberOnly) return ORDERS.filter((o) => o.severity === 'amber');
    return ORDERS;
  }, [tweaks.showAmberOnly]);

  const order = ORDERS.find((o) => o.id === selected);

  const counts = {
    all: ORDERS.length,
    red: ORDERS.filter((o) => o.severity === 'red').length,
    amber: ORDERS.filter((o) => o.severity === 'amber').length,
  };

  return (
    <div className="gazette">
      <div className="gazette-page cd-page">
        <OrderMasthead />

        <section className="cd-toolbar">
          <div className="cd-tabs">
            <button className="cd-tab is-active" type="button">
              미보충 <span className="cd-tab-count">{counts.all}</span>
            </button>
            <span className="cd-tab" aria-disabled="true">
              긴급 <span className="cd-tab-count cd-tab-warn">{counts.red}</span>
            </span>
            <span className="cd-tab" aria-disabled="true">
              주의 <span className="cd-tab-count">{counts.amber}</span>
            </span>
          </div>
        </section>

        <section className="cd-layout">
          <div className="cd-list">
            {filtered.map((o) => (
              <OrderCard
                key={o.id}
                order={o}
                onSelect={setSelected}
                isSelected={selected === o.id}
              />
            ))}
            {filtered.length === 0 && (
              <div className="cd-empty-list">
                {ORDERS.length === 0
                  ? '미보충 주문이 없습니다. 모든 주문이 5종 증빙을 완료했습니다.'
                  : '필터 조건에 해당하는 주문이 없습니다.'}
              </div>
            )}
          </div>
          <OrderDetail order={order} onUploadClick={setRegisterOrder} />
        </section>

        <footer className="cd-foot">
          <div className="cd-foot-line" />
          <div className="cd-foot-row">
            <span>PurchaseAgent · 주문 문서함</span>
            <span>주문별 5종 증빙은 OrderDocumentArchiveJob (cron */15m) 가 paperless.kr 와 자동 동기화합니다.</span>
            <span>발행 · 사장실 · 비매품</span>
          </div>
        </footer>
      </div>

      {registerOrder && (
        <RegisterPanel order={registerOrder} onClose={() => setRegisterOrder(null)} />
      )}

      <TweaksPanel>
        <TweakSection label="테마" />
        <TweakToggle label="다크 모드" value={tweaks.dark} onChange={(v) => setTweak('dark', v)} />
        <TweakSection label="필터" />
        <TweakToggle
          label="주의(amber) 만"
          value={tweaks.showAmberOnly}
          onChange={(v) => setTweak('showAmberOnly', v)}
        />
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<OrderDocs />);
