// explain.jsx — 설명가능 AI(XAI) 레이어
// 각 신호·지표·용어의 "무슨 의미인지 + 어떤 근거인지 + 원문 링크"를 제공.
// 요약 텍스트 클릭 → 하단 시트로 근거 + 원문(REF_SOURCES) 링크 노출.
// 전역: window.UJExplain(id) 로 어디서든 열 수 있음.

// 근거 출처는 references.jsx 의 REF_SOURCES(원문 URL 포함)를 그대로 인용한다.
const EXPLAIN = {
  // ── 매수 신호 ──────────────────────────────────
  sig_buy: {
    tag: '신호', title: '강력매수',
    summary: 'AI 종합점수가 85점(S등급) 이상이면서 최근 1년 상승률이 과열 구간(10%) 미만일 때 부여됩니다. 추가 상승 여력이 충분하다고 판단되는 상태입니다.',
    basis: [
      ['종합점수 ≥ 85 — 12개 요인의 SHAP 가중합 상위', ['shap', 'lgbm']],
      ['1년 상승률 < 10% — 단기 과열이 아니어서 진입 여력이 남아있음', ['caseshiller']],
      ['실거래 모멘텀·공급 부족·교통 호재가 동시에 우호적일 때 강화', ['rtms', 'reb', 'kdi']],
    ],
    note: '강력매수는 매수 "권유"가 아니라 모델이 산출한 상대적 매력도 신호입니다.',
  },
  sig_acc: {
    tag: '신호', title: '매수',
    summary: '종합점수 78~84점 구간. 펀더멘털은 양호하나 강력매수 대비 상승 여력이나 신호 강도가 한 단계 낮은 상태입니다.',
    basis: [
      ['종합점수 78~84 — 상위권이나 최상위(S)는 아님', ['shap']],
      ['실거래·공급·금리 중 일부 요인이 중립이거나 약함', ['rtms', 'reb', 'ecos']],
    ],
    note: '분할 매수·시점 분산을 고려할 수 있는 구간입니다.',
  },
  sig_watch: {
    tag: '신호', title: '관망',
    summary: '종합점수 65~77점. 방향성이 뚜렷하지 않아 추가 데이터(거래량·금리·공급)를 더 확인할 필요가 있는 상태입니다.',
    basis: [
      ['종합점수 65~77 — 중립 구간', ['shap']],
      ['거래량·매물 추세가 혼조이거나 가격 모멘텀이 약함', ['rtms', 'reb']],
    ],
    note: '관심 등록 후 시그널 변화를 추적하는 것을 권장합니다.',
  },
  sig_hold: {
    tag: '신호', title: '보유',
    summary: '종합점수 55~64점. 신규 매수 매력은 낮지만 급격한 하락 위험도 제한적이어서, 이미 보유 중이라면 유지하는 편이 합리적인 구간입니다.',
    basis: [
      ['종합점수 55~64 — 중하위', ['shap']],
      ['하방을 지지하는 전세가율·소득 등 일부 요인 존재', ['kb', 'kosis']],
    ],
    note: '신규 진입보다 보유 관점의 신호입니다.',
  },
  sig_avoid: {
    tag: '신호', title: '회피',
    summary: '종합점수 55점 미만. 고평가(PIR)·공급 과잉·거래 위축 등 하방 요인이 우세해 신규 매수를 보류할 것을 권하는 신호입니다.',
    basis: [
      ['종합점수 < 55 — 하위', ['shap']],
      ['PIR 고점·입주 폭탄·거래량 급감 등 하방 요인 우세', ['kb', 'reb', 'rtms']],
    ],
    note: '회피는 "매도 권유"가 아니라 신규 진입 비권장 신호입니다.',
  },
  // ── 핵심 지표·용어 ─────────────────────────────
  grade: {
    tag: '용어', title: '등급 (S/A/B/C)',
    summary: 'AI 종합점수를 4단계로 구간화한 매력도 등급입니다. S(85↑) · A(72~84) · B(60~71) · C(60 미만).',
    basis: [
      ['12개 요인의 SHAP 기여도를 합산해 0~100 점수화', ['shap', 'lgbm']],
      ['점수 구간을 등급으로 매핑 — 단지 간 빠른 비교용', ['shap']],
    ],
  },
  pir: {
    tag: '지표', title: 'PIR (소득 대비 주택가격)',
    summary: '가구 중위소득 대비 주택 중위가격의 배율입니다. 높을수록 소득 대비 비싸며, 역사적 고점이면 추가 상승 여력이 제한됩니다.',
    basis: [
      ['지역 중위소득 대비 중위가격 배율로 산출', ['kb']],
      ['PIR·이자율 기반 적정가치 평가 프레임(거품 진단)', ['himmelberg']],
    ],
    note: '서울 28.4배는 역사적 고점권으로, 모델에서 하방 요인으로 반영됩니다.',
    factor: 'pir',
  },
  jeonse: {
    tag: '지표', title: '전세가율',
    summary: '매매가 대비 전세가의 비율입니다. 높을수록 매매-전세 갭이 작아 하방을 지지하고 투자 진입 부담이 줄어듭니다.',
    basis: [
      ['전세/매매 비율의 수준과 추세를 결합', ['kb', 'reb']],
    ],
    factor: 'jeonse',
  },
  dsr: {
    tag: '용어', title: 'DSR (총부채원리금상환비율)',
    summary: '연소득 대비 연간 대출 원리금 상환액의 비율입니다. 통상 40% 이내여야 대출이 가능하며, 규제 완화 시 매수 여력이 늘어납니다.',
    basis: [
      ['기준금리·대출 규제는 구매력을 직접 좌우', ['ecos']],
      ['이자율·대출 환경이 적정가치에 미치는 영향', ['himmelberg']],
    ],
    note: '본 시뮬레이터의 DSR은 단순화 가정값으로, 실제 심사 기준과 다를 수 있습니다.',
  },
  target: {
    tag: '지표', title: '적정 매수가',
    summary: '모델이 산출한 합리적 매수 가격입니다. 현재가가 적정가보다 낮으면 저평가, 높으면 고평가로 해석합니다.',
    basis: [
      ['헤도닉 특성가격 + 적정가치 평가 모형으로 추정', ['rosen', 'himmelberg']],
      ['12개 요인 기여도(SHAP)를 반영', ['shap']],
    ],
  },
  bestmonth: {
    tag: '지표', title: '매수 적기 (연.월)',
    summary: 'AI가 예측한 가장 유리한 매수 시점입니다. 가격 모멘텀·공급 일정·금리 경로를 결합해 산출합니다.',
    basis: [
      ['주택가격 모멘텀·자기상관 기반 단기 예측', ['caseshiller']],
      ['Gradient Boosting 예측 모델', ['lgbm']],
    ],
  },
  confidence: {
    tag: '지표', title: '모델 확신도',
    summary: '예측에 대한 모델의 신뢰 수준(0~100%)입니다. 데이터가 풍부하고 요인이 일관될수록 높아집니다.',
    basis: [
      ['예측 분산·요인 일관성으로 신뢰도 산출', ['lgbm', 'shap']],
    ],
  },
  risk: {
    tag: '용어', title: '리스크 (위험)',
    summary: '단지별 하방 요인입니다. 노후도·소단지(환금성)·단기 과열·고평가(PIR)·금리 변동 등이 포함됩니다.',
    basis: [
      ['건축연도·세대수·상승률·PIR 등 하방 요인 점검', ['kb', 'rtms']],
      ['공급탄력성 — 입주 물량 과잉 지역의 조정 위험', ['glaeser']],
    ],
  },
  boon: {
    tag: '용어', title: '호재',
    summary: '단지·지역의 상방 요인입니다. 교통(GTX·역세권)·학군·정비사업(재건축)·신축·수변 조망 등이 포함됩니다.',
    basis: [
      ['교통 인프라의 역세권 프리미엄', ['kdi', 'kticonf']],
      ['학군 프리미엄(헤도닉 가격모형)', ['rosen', 'jhs']],
    ],
  },
};

function refList(ids) {
  const RS = window.REF_SOURCES || {};
  return (ids || []).map(id => ({ id, ...(RS[id] || { label: id, org: id, url: '#', kind: '' }) }));
}

// 전역 트리거
function openExplain(id) {
  window.dispatchEvent(new CustomEvent('urijib:explain', { detail: { id } }));
  if (window.UJTrack) window.UJTrack.track('explain_open', { term: id });
}

// 클릭 가능한 설명 텍스트 (점선 밑줄 + ⓘ)
function ExplainLink({ id, children, style = {}, subtle = false }) {
  if (!EXPLAIN[id]) return <span style={style}>{children}</span>;
  return (
    <span role="button" tabIndex={0} data-track="explain_link" data-track-term={id}
      onClick={(e) => { e.preventDefault(); e.stopPropagation(); openExplain(id); }}
      onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openExplain(id); } }}
      style={{ cursor: 'pointer', borderBottom: subtle ? '1px dotted ' + T.fgMuted : '1px dotted ' + T.hot, display: 'inline-flex', alignItems: 'center', gap: 3, ...style }}>
      {children}
      <span style={{ color: T.hot, fontSize: '0.85em', fontWeight: 700 }}>ⓘ</span>
    </span>
  );
}

// 하단 시트 드로어 (요약 → 근거 → 원문 링크)
function ExplainDrawer() {
  const [id, setId] = useState(null);
  useEffect(() => {
    const h = (e) => setId(e.detail.id);
    window.addEventListener('urijib:explain', h);
    const esc = (e) => { if (e.key === 'Escape') setId(null); };
    window.addEventListener('keydown', esc);
    return () => { window.removeEventListener('urijib:explain', h); window.removeEventListener('keydown', esc); };
  }, []);

  if (!id || !EXPLAIN[id]) return null;
  const e = EXPLAIN[id];
  const KIND_COLOR = { '공시': T.up, '리포트': T.info, '논문': T.ai, '논문(해외)': T.hot };

  return (
    <div onClick={() => setId(null)} style={{ position: 'fixed', inset: 0, zIndex: 9998, background: 'rgba(4,8,16,0.6)', backdropFilter: 'blur(2px)', display: 'flex', alignItems: 'flex-end', justifyContent: 'center' }}>
      <div onClick={(ev) => ev.stopPropagation()} className="uj-scroll" style={{
        width: '100%', maxWidth: 560, maxHeight: '82vh', overflowY: 'auto',
        background: T.bgAlt, border: '1px solid ' + T.lineHi, borderBottom: 'none',
        borderRadius: '14px 14px 0 0', padding: 20,
        boxShadow: '0 -20px 60px rgba(0,0,0,0.6)', animation: 'ujsheet .22s ease',
      }}>
        <div style={{ width: 40, height: 4, borderRadius: 2, background: T.lineHi, margin: '0 auto 16px' }} />
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
          <span style={{ padding: '2px 8px', borderRadius: 3, background: T.hotBg, color: T.hot, fontFamily: T.mono, fontSize: 10, fontWeight: 700 }}>{e.tag}</span>
          <h3 style={{ margin: 0, fontSize: 18, fontWeight: 700, color: T.fg }}>{e.title}</h3>
          <button onClick={() => setId(null)} style={{ marginLeft: 'auto', background: 'transparent', border: 'none', color: T.fgMuted, cursor: 'pointer', display: 'flex' }}><Ico name="close" size={18} /></button>
        </div>

        <div style={{ fontSize: 14, color: T.fg, lineHeight: 1.7, marginBottom: 18 }}>{e.summary}</div>

        <div style={{ fontSize: 11, fontFamily: T.mono, color: T.hot, letterSpacing: 1, marginBottom: 10 }}>판단 근거</div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginBottom: 16 }}>
          {e.basis.map(([text, refs], i) => (
            <div key={i} style={{ padding: 12, background: T.card, border: '1px solid ' + T.line, borderRadius: 8 }}>
              <div style={{ fontSize: 13, color: T.fgDim, lineHeight: 1.55, marginBottom: 8 }}>{text}</div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                {refList(refs).map(r => (
                  <a key={r.id} href={r.url} target="_blank" rel="noopener noreferrer" data-track="explain_source" data-track-ref={r.id} data-track-term={id}
                    style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '4px 9px', borderRadius: 5, background: (KIND_COLOR[r.kind] || T.line) + '1f', border: '1px solid ' + (KIND_COLOR[r.kind] || T.line) + '55', color: KIND_COLOR[r.kind] || T.fgDim, fontSize: 11, textDecoration: 'none' }}>
                    {r.kind && <span style={{ fontFamily: T.mono, fontSize: 9, opacity: 0.85 }}>{r.kind}</span>}
                    {r.org}<Ico name="ext" size={11} />
                  </a>
                ))}
              </div>
            </div>
          ))}
        </div>

        {e.factor && (
          <a href={'#/app/factor/' + e.factor} onClick={() => setId(null)} data-track="explain_to_factor" data-track-factor={e.factor}
            style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '11px 12px', background: T.card, border: '1px solid ' + T.lineHi, borderRadius: 8, textDecoration: 'none', color: T.fg, fontSize: 13, marginBottom: 12 }}>
            <Ico name="chevron" size={15} color={T.hot} /> 이 지표 상세 분석 보기
          </a>
        )}

        {e.note && <div style={{ fontSize: 11, color: T.fgMuted, lineHeight: 1.6, fontFamily: T.mono, paddingTop: 12, borderTop: '1px solid ' + T.line }}>※ {e.note}</div>}
      </div>
      <style>{`@keyframes ujsheet{from{transform:translateY(40px);opacity:0}to{transform:translateY(0);opacity:1}}`}</style>
    </div>
  );
}

Object.assign(window, { EXPLAIN, ExplainLink, ExplainDrawer, openExplain, UJExplain: openExplain });
