// ─── 차트/표 컴포넌트 (SVG 직접 구현) ───
const CHART_THEMES = {
  blue:  ['#1B5BD7', '#5B8DEF', '#9DBCF7', '#C9DAFB', '#7AA5F2', '#3D74E0'],
  navy:  ['#11295E', '#2C4A8F', '#5570AD', '#8398C7', '#B5C2DE', '#3D5A9E'],
  teal:  ['#0E7C7B', '#3FA7A6', '#7BC8C7', '#B7E2E1', '#26918F', '#58B5B4'],
  amber: ['#C97A0A', '#E09B3D', '#EDBC79', '#F7DDB7', '#D4882A', '#E8AB58'],
};
const tcol = (t, i) => (CHART_THEMES[t] || CHART_THEMES.blue)[i % 6];
const fmtNum = (n) => Math.round(n).toLocaleString('ko-KR');
const SUBJ = { ind: '개인', inst: '기관', frgn: '외국인' };

// 가로 막대
function BarChartH({ rows, theme }) {
  const max = Math.max(...rows.map((r) => Math.abs(r.value)), 1);
  return (
    <div className="chart-bars">
      {rows.map((r, i) => (
        <div className="chart-bar-row" key={i}>
          <div className="chart-bar-label" title={r.label}>{r.label}</div>
          <div className="chart-bar-track">
            <div className="chart-bar-fill" style={{ width: (Math.abs(r.value) / max) * 100 + '%', background: i === 0 ? tcol(theme, 0) : tcol(theme, 1) }}></div>
            <span className="chart-bar-value">{fmtNum(r.value)}</span>
          </div>
        </div>
      ))}
    </div>
  );
}

// 선차트(멀티시리즈)
function LineChart({ series, labels, theme }) {
  const W = 560, H = 240, PL = 48, PR = 16, PT = 14, PB = 26;
  const all = series.flatMap((s) => s.values);
  const max = Math.max(...all) * 1.08, min = 0;
  const x = (i) => PL + (i / (labels.length - 1)) * (W - PL - PR);
  const y = (v) => PT + (1 - (v - min) / (max - min)) * (H - PT - PB);
  const ticks = [0, 0.25, 0.5, 0.75, 1].map((t) => Math.round((min + (max - min) * t) / 100) * 100);
  return (
    <div className="chart-line-wrap">
      <svg viewBox={`0 0 ${W} ${H}`} className="chart-svg" preserveAspectRatio="xMidYMid meet">
        {ticks.map((tv) => (
          <g key={tv}>
            <line x1={PL} x2={W - PR} y1={y(tv)} y2={y(tv)} stroke="#E5EAF3"></line>
            <text x={PL - 8} y={y(tv) + 4} textAnchor="end" fontSize="10" fill="#8B95A9">{tv >= 1000 ? (tv / 1000).toFixed(0) + 'k' : tv}</text>
          </g>
        ))}
        {labels.map((l, i) => (<text key={l} x={x(i)} y={H - 8} textAnchor="middle" fontSize="10" fill="#8B95A9">{l}</text>))}
        {series.map((s, si) => (
          <g key={s.name}>
            <polyline points={s.values.map((v, i) => `${x(i)},${y(v)}`).join(' ')} fill="none" stroke={tcol(theme, si)} strokeWidth="2.2" strokeLinejoin="round"></polyline>
            {s.values.map((v, i) => (<circle key={i} cx={x(i)} cy={y(v)} r="3" fill="#fff" stroke={tcol(theme, si)} strokeWidth="2"></circle>))}
          </g>
        ))}
      </svg>
      <div className="chart-legend">
        {series.map((s, si) => (<span className="chart-legend-item" key={s.name}><i style={{ background: tcol(theme, si) }}></i>{s.name}</span>))}
      </div>
    </div>
  );
}

// 도넛
function PieChart({ rows, theme, unit }) {
  const total = rows.reduce((a, r) => a + r.value, 0);
  const R = 78, CX = 100, CY = 100, SW = 34;
  let acc = 0;
  const arcs = rows.map((r, i) => {
    const a0 = (acc / total) * Math.PI * 2 - Math.PI / 2; acc += r.value;
    const a1 = (acc / total) * Math.PI * 2 - Math.PI / 2;
    const large = a1 - a0 > Math.PI ? 1 : 0;
    const p0 = [CX + R * Math.cos(a0), CY + R * Math.sin(a0)];
    const p1 = [CX + R * Math.cos(a1), CY + R * Math.sin(a1)];
    return { d: `M ${p0[0]} ${p0[1]} A ${R} ${R} 0 ${large} 1 ${p1[0]} ${p1[1]}`, color: tcol(theme, i) };
  });
  return (
    <div className="chart-pie-wrap">
      <svg viewBox="0 0 200 200" className="chart-pie-svg">
        {arcs.map((a, i) => (<path key={i} d={a.d} fill="none" stroke={a.color} strokeWidth={SW}></path>))}
        <text x={CX} y={CY - 4} textAnchor="middle" fontSize="22" fontWeight="700" fill="#11295E">{rows[0].value}{unit}</text>
        <text x={CX} y={CY + 16} textAnchor="middle" fontSize="10.5" fill="#8B95A9">{rows[0].label}</text>
      </svg>
      <div className="chart-pie-legend">
        {rows.map((r, i) => (
          <div className="chart-pie-legend-row" key={r.label}>
            <i style={{ background: tcol(theme, i) }}></i><span className="lbl">{r.label}</span><span className="val">{r.value}{unit}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// 표
function DataTable({ columns, rows, compact }) {
  return (
    <div className={'data-table-wrap' + (compact ? ' compact' : '')}>
      <table className="data-table">
        <thead><tr>{columns.map((c) => <th key={c.key} className={c.num ? 'num' : ''}>{c.label}</th>)}</tr></thead>
        <tbody>
          {rows.map((r, i) => (
            <tr key={i}>{columns.map((c) => <td key={c.key} className={(c.num ? 'num ' : '') + (c.strong ? 'strong ' : '') + (r['_cls_' + c.key] || '')}>{c.num ? fmtNum(r[c.key]) : r[c.key]}</td>)}</tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

// result spec + config → 뷰 데이터
function buildResultData(result, config) {
  const topN = (config && config.topN) || 10;
  const { MGR_SHARE, MONTHS } = window.BI;
  if (result.kind === 'share') {
    const items = MGR_SHARE.slice(0, topN);
    return {
      pie: items.map((m) => ({ label: m.mgr, value: m.share })),
      unit: '%',
      tableCols: [{ key: 'mgr', label: '운용사' }, { key: 'share', label: '점유율(%)', num: true }, { key: 'aum', label: 'AUM(억원)', num: true }, { key: 'momTxt', label: '전월 대비' }],
      tableRows: items.map((m) => ({ ...m, momTxt: (m.mom > 0 ? '+' : '') + m.mom.toFixed(1) + '%p', ['_cls_momTxt']: m.mom >= 0 ? 'pos' : 'neg' })),
    };
  }
  if (result.kind === 'flow') {
    const rows = window.BI.FLOW_ROWS;
    return {
      bars: rows.map((r) => ({ label: r.date, value: r.net })),
      series: [
        { name: '설정액', values: rows.map((r) => r.in) },
        { name: '환매액', values: rows.map((r) => r.out) },
      ],
      labels: rows.map((r) => r.date),
      pie: rows.slice(-5).map((r) => ({ label: r.date, value: Math.max(r.net, 0) })),
      unit: '',
      tableCols: [
        { key: 'date', label: '기준일' }, { key: 'in', label: '설정액', num: true },
        { key: 'out', label: '환매액', num: true }, { key: 'net', label: '순유입', num: true },
      ],
      tableRows: rows.map((r) => ({ ...r, ['_cls_net']: r.net >= 0 ? 'pos' : 'neg' })),
    };
  }
  if (result.kind === 'trend') {
    const rows = window.BI.topRows('ind', Math.min(topN, 5));
    return {
      series: rows.map((r) => ({ name: r.name, values: r.monthly })),
      labels: MONTHS.map((m) => m.slice(5) + '월'),
      bars: MONTHS.map((m, i) => ({ label: m.slice(5) + '월', value: rows.reduce((s, r) => s + r.monthly[i], 0) })),
      tableCols: [{ key: 'month', label: '월' }, { key: 'total', label: '개인 순매수(억원)', num: true }],
      tableRows: MONTHS.map((m, i) => ({ month: m.slice(5) + '월', total: rows.reduce((s, r) => s + r.monthly[i], 0) })),
    };
  }
  // topN (subject)
  const subject = result.subject || 'ind';
  const rows = window.BI.topRows(subject, topN);
  return {
    bars: rows.map((r) => ({ label: r.name, value: r[subject] })),
    line: { series: rows.slice(0, 5).map((r) => ({ name: r.name, values: r.monthly })), labels: MONTHS.map((m) => m.slice(5) + '월') },
    pie: rows.map((r) => ({ label: r.name, value: +((r[subject] / rows.reduce((s, x) => s + x[subject], 0)) * 100).toFixed(1) })),
    unit: '%',
    tableCols: [
      { key: 'code', label: 'CODE' }, { key: 'name', label: '종목명', strong: true }, { key: 'mgr', label: '운용사' },
      { key: 'cls1', label: '1차분류' }, { key: 'ind', label: '개인', num: true }, { key: 'inst', label: '기관', num: true }, { key: 'frgn', label: '외국인', num: true },
    ],
    tableRows: rows,
    subject,
  };
}

// 통합 뷰 렌더러 (대시보드 카드 & 챗 결과 공용)
function ComponentView({ comp }) {
  const data = buildResultData(comp.result || comp, comp.config);
  const theme = (comp.config && comp.config.theme) || 'blue';
  const view = comp.view;
  if (view === 'pie') return <PieChart rows={data.pie} theme={theme} unit={data.unit} />;
  if (view === 'line') {
    if (data.series) return <LineChart series={data.series} labels={data.labels} theme={theme} />;
    return <LineChart series={data.line.series} labels={data.line.labels} theme={theme} />;
  }
  if (view === 'table') return <DataTable columns={data.tableCols} rows={data.tableRows} compact />;
  // bar (default)
  if (data.bars) return <BarChartH rows={data.bars} theme={theme} />;
  if (data.pie) return <PieChart rows={data.pie} theme={theme} unit={data.unit} />;
  return <BarChartH rows={data.bars || []} theme={theme} />;
}

Object.assign(window, { BarChartH, LineChart, PieChart, DataTable, buildResultData, ComponentView, fmtNum, SUBJ, tcol, CHART_THEMES });
