/* synergy-panel.jsx — SA·GFA 통합 뷰 (ROADMAP Task 008)
 *  동일 페르소나(성·연령·디바이스) 축을 두 채널 제어로 동시 매핑해 애드 시너지를 제시.
 *   · SA  = 입찰 가중치 %(bid multiplier, EngineMath lift 기반) + 신뢰구간
 *   · GFA = 노출 ON/OFF + 예산 비중(budget share). ★"입찰"·% 개념 없음(CLAUDE.md 채널 규칙·DP-4)
 *  같은 측정 share에서 출발하되 제어 도출은 채널별로 다르다(한쪽 값을 다른 쪽에 복사 금지).
 *  무중단 가산 — 기존 뷰 미변경. 바이올렛(SA)·코랄(GFA) 오로라. 수치=DiagnoseMatrix(결정론·no_live_write).
 */
(function () {
  var useState = React.useState, useEffect = React.useEffect;
  var BP = function () { return window.BrandProfiles; };

  var AXIS_LABEL = { gender_age: '성별 × 연령', gender: '성별', age: '연령', device: '디바이스' };
  var SA_ACCENT = '#b79ae0';   // 바이올렛
  var GFA_ACCENT = '#e0916f';  // 코랄

  function Card(props) {
    return <div style={Object.assign({ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 9, padding: '15px 17px' }, props.style)}>{props.children}</div>;
  }
  function Tier(props) {
    var a = props.tier === 'A';
    return <span style={{ display: 'inline-block', padding: '1px 6px', borderRadius: 4, fontSize: 9.5, fontFamily: 'var(--font-mono)', fontWeight: 700,
      background: a ? '#13301f' : 'transparent', color: a ? '#5fcf94' : '#b79ae0',
      border: a ? '1px solid #2c5a3e' : '1px dashed #6a5a8e' }}>{a ? 'A 실측' : 'C 추정'}</span>;
  }

  function SynergyPanel(props) {
    var fixedBrand = props && props.fixedBrand;
    var bp = BP();
    var brands = (bp && bp.list && bp.list()) || [];
    var def = fixedBrand || brands[0] || '샥즈';
    var [brand, setBrand] = useState(def);
    var [input, setInput] = useState(def);
    var [hint, setHint] = useState('STANDARD');
    // ★2026-07-18: 로컬 window.DiagnoseMatrix.build() 직접실행 → 서버 배포본(api/sa-structure.mjs)
    // 원격호출로 전환(sa-structure-panel.jsx와 동일 이유 — 소스 하나·엔진 로컬중복 없음).
    var [out, setOut] = useState(null); // null = 조회 중(로딩), 그 외엔 항상 {error}|{category,sa_cells}

    useEffect(function () {
      var ignore = false;
      setOut(null);
      fetch('/api/sa-structure?brand_id=' + encodeURIComponent(brand) + '&seed_hint=' + encodeURIComponent(hint))
        .then(function (r) { return r.json(); })
        .then(function (data) { if (!ignore) setOut(data); })
        .catch(function (e) { if (!ignore) setOut({ error: String(e) }); });
      return function () { ignore = true; };
    }, [brand, hint]);

    var loading = out === null;
    var saCells = (out && out.sa_cells) || [];
    var category = (out && out.category) || '';

    // 축별 그룹 + GFA 예산비중(같은 축 내 share 정규화) 도출
    var groups = {};
    saCells.forEach(function (c) { (groups[c.axis] = groups[c.axis] || []).push(c); });
    var axes = Object.keys(groups);

    // ── 핵심 요약(결정론, LLM 미사용·DP-6) — 통합뷰는 raw 표 나열이 아니라
    //    "두 채널 분석의 핵심"을 요약 전달해야 한다는 요구사항 반영. SA=lift 기반 입찰,
    //    GFA=같은 축 내 share 정규화 예산비중 — 최우선 세그먼트를 뽑아 일치/괴리를 정직하게 알린다.
    var summaryBullets = [];
    if (axes.length > 0) {
      var allRows = [];
      axes.forEach(function (ax) {
        var rows = groups[ax];
        var sum = rows.reduce(function (s, c) { return s + (c.share || 0); }, 0) || 1;
        rows.forEach(function (c) { allRows.push({ axis: ax, cell: c.cell, bid: c.bid_weight_pct || 0, budgetPct: Math.round((c.share || 0) / sum * 100) }); });
      });
      var topSA = allRows.slice().sort(function (a, b) { return b.bid - a.bid; })[0];
      var topBudget = allRows.slice().sort(function (a, b) { return b.budgetPct - a.budgetPct; })[0];
      var agree = topSA.axis === topBudget.axis && topSA.cell === topBudget.cell;
      summaryBullets.push('SA 입찰 최우선 세그먼트: ' + (AXIS_LABEL[topSA.axis] || topSA.axis) + ' · ' + topSA.cell + ' (' + topSA.bid + '%)');
      summaryBullets.push('GFA 예산 집중 세그먼트: ' + (AXIS_LABEL[topBudget.axis] || topBudget.axis) + ' · ' + topBudget.cell + ' (' + topBudget.budgetPct + '%)');
      summaryBullets.push(agree
        ? '두 채널의 최우선 세그먼트가 일치합니다 — 같은 방향으로 SA 입찰·GFA 예산을 함께 강화해도 안전합니다.'
        : '두 채널의 최우선 세그먼트가 다릅니다 — SA(검색의도)와 GFA(노출확보)는 도출 방식이 달라 자연스러운 괴리일 수 있으나, 실 성과 데이터로 교차검증을 권장합니다.');
    }

    function run() { setBrand((input || '').trim() || def); }

    var HINTS = [
      { id: 'STANDARD', label: '표준', desc: '기본 50~150%' },
      { id: 'AGGRESSIVE', label: '공격', desc: '상한↑ 165%' },
      { id: 'COST_SAVING', label: '보수', desc: '하한↓·상한 제한' },
    ];

    return (
      <div style={{ padding: '18px 20px', maxWidth: 1120, margin: '0 auto' }}>
        {/* Header */}
        <Card style={{ marginBottom: 14 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
            <h3 style={{ margin: 0, fontSize: 16, fontWeight: 700, color: 'var(--ink-100)' }}>SA · GFA 통합 매트릭스</h3>
            <span style={{ fontSize: 11.5, color: 'var(--ink-400)' }}>동일 페르소나 축 · 두 채널 동시 매핑(애드 시너지)</span>
            <span style={{ marginLeft: 'auto', fontSize: 10.5, fontFamily: 'var(--font-mono)', color: 'var(--ink-400)' }}>no_live_write · 결정론</span>
          </div>
          {!fixedBrand && (
            <div style={{ display: 'flex', gap: 8, marginTop: 12, flexWrap: 'wrap', alignItems: 'center' }}>
              <input value={input} onChange={function (e) { setInput(e.target.value); }}
                onKeyDown={function (e) { if (e.key === 'Enter') run(); }} placeholder="브랜드명 (예: 샥즈)"
                style={{ flex: '1 1 220px', minWidth: 180, padding: '8px 11px', background: 'var(--bg)', border: '1px solid var(--border)', borderRadius: 6, color: 'var(--ink-100)', fontSize: 13 }} />
              <button onClick={run} style={{ padding: '8px 16px', background: SA_ACCENT, color: '#1a1426', border: 'none', borderRadius: 6, fontWeight: 700, fontSize: 13, cursor: 'pointer' }}>분석</button>
              {brands.length > 0 && <select value={brand} onChange={function (e) { setBrand(e.target.value); setInput(e.target.value); }}
                style={{ padding: '8px 10px', background: 'var(--bg)', border: '1px solid var(--border)', borderRadius: 6, color: 'var(--ink-300)', fontSize: 12 }}>
                {brands.map(function (b) { return <option key={b} value={b}>{b}</option>; })}
              </select>}
            </div>
          )}
          <div style={{ display: 'flex', gap: 6, marginTop: 10, alignItems: 'center', flexWrap: 'wrap' }}>
            <span style={{ fontSize: 11, color: 'var(--ink-400)' }}>집행 힌트:</span>
            {HINTS.map(function (h) {
              var on = hint === h.id;
              return <button key={h.id} title={h.desc} onClick={function () { setHint(h.id); }}
                style={{ padding: '4px 10px', borderRadius: 5, fontSize: 11, cursor: 'pointer', fontWeight: on ? 700 : 500,
                  background: on ? SA_ACCENT : 'transparent', color: on ? '#1a1426' : 'var(--ink-300)', border: '1px solid ' + (on ? SA_ACCENT : 'var(--border)') }}>{h.label}</button>;
            })}
            {category && <span style={{ marginLeft: 'auto', fontSize: 11, color: 'var(--ink-400)' }}>카테고리: <b style={{ color: 'var(--ink-200)' }}>{category}</b></span>}
          </div>
        </Card>

        {/* 채널 규칙 노트 */}
        <div style={{ display: 'flex', gap: 14, marginBottom: 14, flexWrap: 'wrap' }}>
          <span style={{ fontSize: 11, color: SA_ACCENT, fontWeight: 700 }}>● SA = 입찰 가중치 %</span>
          <span style={{ fontSize: 11, color: GFA_ACCENT, fontWeight: 700 }}>● GFA = 노출 ON · 예산 비중</span>
          <span style={{ fontSize: 10.5, color: 'var(--ink-400)' }}>같은 측정 share에서 출발하되 제어는 채널별로 다름 — 한쪽 값을 다른 쪽에 복사하지 않습니다(DP-4).</span>
        </div>

        {summaryBullets.length > 0 && (
          <Card style={{ marginBottom: 14, borderLeft: '2px solid ' + SA_ACCENT }}>
            <h4 style={{ margin: '0 0 8px', fontSize: 12, letterSpacing: '0.04em', color: 'var(--ink-300)', textTransform: 'uppercase', fontFamily: 'var(--font-mono)' }}>핵심 요약 · SA·GFA 통합 제안</h4>
            <ul style={{ margin: 0, paddingLeft: 18, display: 'flex', flexDirection: 'column', gap: 5 }}>
              {summaryBullets.map(function (b, i) { return <li key={i} style={{ fontSize: 12.5, color: 'var(--ink-200)', lineHeight: 1.5 }}>{b}</li>; })}
            </ul>
          </Card>
        )}

        {out && out.error && <Card style={{ borderColor: '#5a2c2c', color: '#e08a8a' }}>산출 오류: {out.error}</Card>}

        {loading && <Card style={{ color: 'var(--ink-400)', fontSize: 12.5 }}>조회 중…</Card>}

        {!loading && !axes.length && !(out && out.error) && (
          <Card style={{ color: 'var(--ink-400)', fontSize: 12.5, lineHeight: 1.6 }}>
            <b style={{ color: 'var(--ink-200)' }}>{brand}</b> — 성·연령·디바이스 <b>실측 미적재</b>이거나 미등록 브랜드라 SA 매트릭스를 산출하지 않습니다(거짓정밀 금지).
            1st-party 데이터 적재 시 통합 매트릭스가 채워집니다. (적재 양식: <code>docs/BRAND_INTAKE_FORM.md</code>)
          </Card>
        )}

        {/* 축별 통합 테이블 */}
        {axes.map(function (ax) {
          var rows = groups[ax];
          var sum = rows.reduce(function (s, c) { return s + (c.share || 0); }, 0) || 1;
          return (
            <Card key={ax} style={{ marginBottom: 12 }}>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginBottom: 10 }}>
                <h4 style={{ margin: 0, fontSize: 12, letterSpacing: '0.04em', color: 'var(--ink-300)', textTransform: 'uppercase', fontFamily: 'var(--font-mono)' }}>{AXIS_LABEL[ax] || ax}</h4>
                <span style={{ fontSize: 10.5, color: 'var(--ink-500, var(--ink-400))' }}>{rows.length}개 셀</span>
              </div>
              <div style={{ overflowX: 'auto' }}>
                <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
                  <thead>
                    <tr style={{ textAlign: 'left', color: 'var(--ink-400)', fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.03em' }}>
                      <th style={{ padding: '5px 8px', fontWeight: 600 }}>세그먼트</th>
                      <th style={{ padding: '5px 8px', fontWeight: 600, color: SA_ACCENT }}>SA 입찰 가중%</th>
                      <th style={{ padding: '5px 8px', fontWeight: 600, color: SA_ACCENT }}>신뢰구간</th>
                      <th style={{ padding: '5px 8px', fontWeight: 600, color: GFA_ACCENT }}>GFA 노출</th>
                      <th style={{ padding: '5px 8px', fontWeight: 600, color: GFA_ACCENT }}>GFA 예산비중</th>
                      <th style={{ padding: '5px 8px', fontWeight: 600 }}>tier</th>
                    </tr>
                  </thead>
                  <tbody>
                    {rows.slice().sort(function (a, b) { return (b.share || 0) - (a.share || 0); }).map(function (c, i) {
                      var budget = Math.round((c.share || 0) / sum * 100);
                      var ci = (c.ci && c.ci.length === 2 && c.ci[0] !== c.ci[1]) ? (c.ci[0] + '~' + c.ci[1] + '%') : '—';
                      var strong = c.bid_weight_pct >= 120;
                      return (
                        <tr key={i} style={{ borderTop: '1px solid var(--border)' }}>
                          <td style={{ padding: '7px 8px', color: 'var(--ink-100)', fontWeight: 600 }}>{c.cell}</td>
                          <td style={{ padding: '7px 8px', fontFamily: 'var(--font-mono)', color: SA_ACCENT, fontWeight: strong ? 700 : 500 }}>{c.bid_weight_pct}%</td>
                          <td style={{ padding: '7px 8px', fontFamily: 'var(--font-mono)', color: 'var(--ink-400)', fontSize: 11 }}>{ci}</td>
                          <td style={{ padding: '7px 8px', fontFamily: 'var(--font-mono)', color: GFA_ACCENT }}>ON</td>
                          <td style={{ padding: '7px 8px', fontFamily: 'var(--font-mono)', color: GFA_ACCENT }}>{budget}%</td>
                          <td style={{ padding: '7px 8px' }}><Tier tier={c.tier} /></td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            </Card>
          );
        })}

        {axes.length > 0 && (
          <p style={{ fontSize: 10.5, color: 'var(--ink-400)', lineHeight: 1.6, margin: '4px 6px' }}>
            SA 입찰%는 동일 측정 share의 <b>오버/언더인덱스(lift)</b> 기반(독립가정 대비), GFA 예산비중은 같은 축 내 <b>측정 share 정규화</b>.
            두 값은 같은 페르소나에서 도출되지만 제어 의미가 달라 그대로 복사하지 않습니다. 집행 힌트는 SA clip 경계만 이동(GFA 무영향).
          </p>
        )}
      </div>
    );
  }

  window.SynergyPanel = SynergyPanel;
})();
