import type { Props } from "./schema";

const joinIds = (...parts: (string | number)[]) =>
  parts.map((part) => String(part).replace(/[_-]/g, (c) => `_${c.charCodeAt(0).toString(16)}_`)).join("-");

const fmt = (n: number) => `${n > 0 ? "+" : ""}${n.toFixed(3)}`;
const wrap = (text: string, width: number) => Array.from({ length: Math.ceil([...text].length / width) }, (_, i) => [...text].slice(i * width, (i + 1) * width).join(""));
function color(value: number) {
  const target = value < 0 ? [36, 85, 122] : [139, 52, 33];
  const t = Math.abs(value) * 0.9;
  const rgb = target.map(channel => Math.round(255 + (channel - 255) * t));
  return `#${rgb.map(channel => channel.toString(16).padStart(2, "0")).join("")}`;
}

export default function Template(d: Props) {
  const titleLines = wrap(d.title, 48);
  const subtitleLines = d.subtitle ? wrap(d.subtitle, 80) : [];
  const titleY = 44;
  const subtitleY = titleY + titleLines.length * 23 + 4;
  const gridY = subtitleY + subtitleLines.length * 18 + 58;
  const cell = Math.min(72, 432 / d.variables.length);
  const size = cell * d.variables.length;
  const gridX = (1280 - size) / 2;
  const labelX = gridX - 14;
  const coefficientByPair = new Map(d.pairs.map(pair => {
    const i = d.variables.indexOf(pair.row);
    const j = d.variables.indexOf(pair.column);
    return [`${i}:${j}`, pair.coefficient];
  }));
  const matrixValue = (row: number, column: number) => {
    if (row === column) return 1;
    const i = Math.min(row, column);
    const j = Math.max(row, column);
    return coefficientByPair.get(`${i}:${j}`)!;
  };
  const columnLabels = d.variables.map(name => wrap(name, 4));
  const variablePairs = d.pairs.map(pair => ({ ...pair, sign: pair.coefficient > 0 ? "positive" : pair.coefficient < 0 ? "negative" : "neutral" }));

  return <section className="asset correlation">
    <style>{`.correlation{font-family:var(--font-sans);color:var(--color-on-surface);background:var(--color-surface);max-width:var(--container-slide);margin:auto;padding:2rem;line-height:1.5;font-size:var(--text-body-sm)}.correlation *{box-sizing:border-box}.correlation h1{font-size:var(--text-h2);line-height:1.3;margin:0}.muted{color:var(--color-secondary)}.plot{display:block;width:100%;height:auto}.plot .svg-title,.plot .svg-subtitle{display:none}.pair-list{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.25rem;margin-top:1rem}.pair{min-width:0;overflow-wrap:anywhere;padding:.75rem;border-bottom:1px solid var(--color-outline);border-left:.25rem solid var(--color-secondary)}.pair.positive{border-left-color:#B04A35}.pair.negative{border-left-color:#346797}.pair strong{display:block}.pair span{font-variant-numeric:tabular-nums;font-family:var(--font-mono)}.note{margin-top:1rem;padding:1rem;background:var(--color-surface-subtle);color:var(--color-secondary)}@media(max-width:640px){.correlation{padding:1rem}.correlation h1{font-size:var(--text-h3)}.plot{display:none}.pair-list{grid-template-columns:minmax(0,1fr);gap:.25rem}.pair{min-width:0;overflow-wrap:anywhere}}`}</style>
    <header><p className="muted">CORRELATION MATRIX · 相関は因果を意味しない</p><h1>{titleLines.map((line, i) => <span key={i}>{line}{i + 1 < titleLines.length && <br />}</span>)}</h1>{d.subtitle && <p className="muted">{d.subtitle}</p>}</header>
    <svg className="plot" data-layout-still="true" xmlns="http://www.w3.org/2000/svg" width="1280" height="720" viewBox="0 0 1280 720" role="img" aria-label="指標間の相関係数を正負の色で示す対称行列">
      <rect width="1280" height="720" fill="var(--color-surface)" />
      {titleLines.map((line, i) => <text key={`title-${i}`} className="svg-title" x="64" y={titleY + i * 23} fontSize="20" fontWeight="700" fill="var(--color-on-surface)">{line}</text>)}
      {subtitleLines.map((line, i) => <text key={`subtitle-${i}`} className="svg-subtitle" x="64" y={subtitleY + i * 18} fontSize="14" fill="var(--color-secondary)">{line}</text>)}
      {columnLabels.map((lines, j) => lines.map((line, i) => <text key={`col-${j}-${i}`} x={gridX + j * cell + cell / 2} y={gridY - 43 + i * 15} textAnchor="middle" fontSize="11" fontWeight="700" fill="var(--color-on-surface)">{line}</text>))}
      {d.variables.map((name, i) => <text key={`row-${i}`} x={labelX} y={gridY + i * cell + cell / 2 + 4} textAnchor="end" fontSize="12" fill="var(--color-on-surface)">{name}</text>)}
      {d.variables.flatMap((row, i) => d.variables.map((column, j) => {
        const value = matrixValue(i, j);
        const x = gridX + j * cell;
        const y = gridY + i * cell;
        const fill = i === j ? "#E4E9EE" : color(value);
        return <g key={joinIds(row, column)} data-pair-cell={i < j ? "true" : undefined}>
          <rect x={x} y={y} width={cell} height={cell} fill={fill} stroke="var(--color-surface)" strokeWidth="2" />
          <text x={x + cell / 2} y={y + cell / 2 + 5} textAnchor="middle" fontSize={cell < 58 ? "11" : "15"} fontWeight="600" fill={i === j || Math.abs(value) < 0.85 ? "var(--color-on-surface)" : "#FFFFFF"}>{i === j ? "1.000" : fmt(value)}</text>
        </g>;
      }))}
      <text x="64" y="704" fontSize="13" fill="var(--color-secondary)">対角は自己相関1.00。濃さは相関の強さ、青と赤は負・正の方向を表す。相関から因果は分からない。</text>
    </svg>
    <div className="pair-list">{variablePairs.map(pair => <article key={joinIds(pair.row, pair.column)} className={`pair ${pair.sign}`} data-pair-row><strong>{pair.row} × {pair.column}</strong><span>{fmt(pair.coefficient)}</span></article>)}</div>
    <p className="note">相関係数は二指標の線形な関連を要約します。対象期間や集団が異なる値は比較せず、相関を因果として解釈しないでください。</p>
  </section>;
}
