"use client";

// 투자자별 누적 순매수 미니 차트.
//
// 토스 종목 상세의 "투자자별 매매" 탭에서 인상이 강한 위젯 — 외국인/기관/개인
// 각각의 N일 누적 순매수를 작은 라인으로 보여줘서 "누가 모으고 누가 분배하고 있는가"
// 를 한 눈에 잡게 한다.
//
// 데이터 소스는 ChartPayload.trading_value (이미 페이지에 있음) 그대로. 백엔드 호출 0.
// 단위: 원 → 억원(1e8) 환산.
//
// 색은 한국 컬러 — 누적 +면 빨강(매수 우위), -면 파랑(매도 우위). 라인 자체 색은
// 주체별로 고정해서 비교 가능하게 (외국인=amber, 기관=cyan, 개인=violet).

import { useMemo, useState } from "react";
import type { TradingValuePoint } from "../lib/api";

type Window = 20 | 60 | 120;

const WINDOW_OPTIONS: { v: Window; label: string }[] = [
  { v: 20, label: "20일" },
  { v: 60, label: "60일" },
  { v: 120, label: "120일" },
];

type Subject = "foreign" | "institution" | "individual";

const SUBJECTS: { key: Subject; label: string; color: string; field: keyof TradingValuePoint }[] = [
  { key: "foreign", label: "외국인", color: "#f59e0b", field: "foreign_net" },
  { key: "institution", label: "기관", color: "#22d3ee", field: "institution_net" },
  { key: "individual", label: "개인", color: "#a78bfa", field: "individual_net" },
];

export function InvestorCumulative({ data }: { data: TradingValuePoint[] }) {
  const [win, setWin] = useState<Window>(20);

  // 데이터가 충분치 않으면 window 를 줄여서라도 그릴 수 있게.
  const effectiveWin = Math.min(win, data?.length ?? 0);

  const series = useMemo(() => {
    if (!data || data.length === 0) return null;
    const slice = data.slice(-effectiveWin);
    // 각 주체별 누적 순매수 (원 단위), 0 부터 시작.
    const out: Record<Subject, number[]> = {
      foreign: [0],
      institution: [0],
      individual: [0],
    };
    for (const p of slice) {
      for (const s of SUBJECTS) {
        const v = (p[s.field] as number | null) ?? 0;
        const prev = out[s.key][out[s.key].length - 1];
        out[s.key].push(prev + v);
      }
    }
    return { slice, out };
  }, [data, effectiveWin]);

  if (!series) {
    return (
      <div className="rounded-md border border-zinc-800 bg-zinc-900/40 p-4 text-xs text-zinc-500">
        투자자별 누적 데이터 없음
      </div>
    );
  }

  return (
    <div className="rounded-md border border-zinc-800 bg-zinc-900/40 p-4">
      <div className="mb-3 flex items-baseline justify-between gap-2">
        <div className="text-sm font-medium text-zinc-200">투자자별 누적 순매수</div>
        <div className="flex items-center gap-1.5 text-[10px]">
          {WINDOW_OPTIONS.map((w) => {
            const on = win === w.v;
            return (
              <button
                key={w.v}
                type="button"
                onClick={() => setWin(w.v)}
                className={`rounded-full border px-2 py-0.5 transition ${
                  on
                    ? "border-zinc-600 bg-zinc-800/80 text-zinc-100"
                    : "border-zinc-800 bg-transparent text-zinc-500 hover:text-zinc-300"
                }`}
                aria-pressed={on}
              >
                {w.label}
              </button>
            );
          })}
        </div>
      </div>
      <div className="space-y-2.5">
        {SUBJECTS.map((s) => (
          <SubjectRow key={s.key} label={s.label} color={s.color} values={series.out[s.key]} />
        ))}
      </div>
      <div className="mt-3 text-[10px] text-zinc-500">
        단위: 억원 · 마지막 {effectiveWin}일 누적 (시작 0)
      </div>
    </div>
  );
}

// 한 주체에 대한 라벨 + 누적 라인 + 끝 값.
// values: 길이 N+1 (시작 0 포함). viewBox 좌표는 0..100 / 0..30.
function SubjectRow({
  label,
  color,
  values,
}: {
  label: string;
  color: string;
  values: number[];
}) {
  if (values.length < 2) {
    return (
      <div className="flex items-center gap-2 text-[11px] text-zinc-500">
        <span className="w-10 text-zinc-400">{label}</span>
        <span>—</span>
      </div>
    );
  }
  const lo = Math.min(...values);
  const hi = Math.max(...values);
  const span = hi - lo || 1;
  const w = 100;
  const h = 30;
  const n = values.length;
  const path = values
    .map((v, i) => {
      const x = (i / (n - 1)) * w;
      // 0 이 위로 가도록 y 뒤집기. 패딩 1px.
      const y = h - 1 - ((v - lo) / span) * (h - 2);
      return `${i === 0 ? "M" : "L"}${x.toFixed(2)},${y.toFixed(2)}`;
    })
    .join(" ");
  // 기준선 (시작 0) 위치.
  const baseY = h - 1 - ((0 - lo) / span) * (h - 2);
  const end = values[values.length - 1];
  const endEok = end / 1e8;
  const tone =
    endEok === 0
      ? "text-zinc-400"
      : endEok > 0
        ? "text-rose-300"
        : "text-sky-300";
  const sign = endEok > 0 ? "+" : "";

  return (
    <div className="flex items-center gap-2">
      <span className="w-10 shrink-0 text-[11px] text-zinc-400">{label}</span>
      <svg
        viewBox={`0 0 ${w} ${h}`}
        preserveAspectRatio="none"
        className="h-7 flex-1"
        aria-hidden
      >
        <line
          x1={0}
          y1={baseY}
          x2={w}
          y2={baseY}
          stroke="#3f3f46"
          strokeDasharray="2 2"
          strokeWidth={0.5}
        />
        <path d={path} fill="none" stroke={color} strokeWidth={1.2} strokeLinejoin="round" />
      </svg>
      <span className={`w-16 shrink-0 text-right text-[11px] tabular-nums ${tone}`}>
        {sign}
        {endEok.toLocaleString(undefined, { maximumFractionDigits: 0 })}억
      </span>
    </div>
  );
}
