"use client";

// AI 종합 점수 카드 — 토스 "투자자 분석" 비슷한 톤.
// chart payload (ohlcv + sentiment + trading_value) 에서 클라이언트가 직접 합성.
// 백엔드 호출 없음.
//
// 4개 서브 점수 (각 0~100, 50 = 중립):
//   - 모멘텀 : SMA5 vs SMA20 격차
//   - 수급   : 외국인+기관 5일 누적 net (vs |대각| 정규화)
//   - 감성   : 뉴스 weighted_score 7일 평균 (-1~+1 → 0~100)
//   - 추세   : 종가 20일 선형회귀 기울기 부호+강도
// 종합 = 평균. 50 미만 = 약세(파랑), 50 초과 = 강세(빨강).

import type { ChartPayload } from "../lib/api";
import { CardHeader } from "./CardHeader";

type Scores = {
  momentum: number | null;
  flow: number | null;
  sentiment: number | null;
  trend: number | null;
  composite: number | null;
};

function computeScores(chart: ChartPayload): Scores {
  // 모멘텀: SMA5 vs SMA20
  const closes = chart.ohlcv
    .map((p) => p.close)
    .filter((c): c is number => c != null);
  const sma = (arr: number[], n: number) => {
    if (arr.length < n) return null;
    const slice = arr.slice(-n);
    return slice.reduce((a, b) => a + b, 0) / n;
  };
  const sma5 = sma(closes, 5);
  const sma20 = sma(closes, 20);
  const momentum =
    sma5 != null && sma20 != null && sma20 > 0
      ? clamp01(((sma5 - sma20) / sma20) * 10) // ±10% → 0~1
      : null;

  // 수급: 외국인+기관 5일 net / 평균거래대금 (조잡한 정규화)
  const tv = chart.trading_value.slice(-5);
  const flowSum = tv.reduce(
    (a, r) => a + (r.foreign_net ?? 0) + (r.institution_net ?? 0),
    0,
  );
  const flowAbsMean =
    tv.reduce(
      (a, r) => a + Math.abs(r.foreign_net ?? 0) + Math.abs(r.institution_net ?? 0),
      0,
    ) / Math.max(1, tv.length);
  const flow =
    tv.length >= 3 && flowAbsMean > 0
      ? clamp01(flowSum / (flowAbsMean * 5))
      : null;

  // 감성: weighted_score 평균 (최근 7개 점 기준)
  const sents = chart.sentiment
    .slice(-7)
    .map((p) => p.weighted_score)
    .filter((v): v is number => v != null);
  const sentMean =
    sents.length > 0 ? sents.reduce((a, b) => a + b, 0) / sents.length : null;
  const sentiment = sentMean != null ? clamp01(sentMean) : null;

  // 추세: 최근 20 종가 선형회귀 기울기 / 평균값 (정규화)
  const last20 = closes.slice(-20);
  let trend: number | null = null;
  if (last20.length >= 10) {
    const n = last20.length;
    const xs = Array.from({ length: n }, (_, i) => i);
    const xMean = (n - 1) / 2;
    const yMean = last20.reduce((a, b) => a + b, 0) / n;
    let num = 0;
    let den = 0;
    for (let i = 0; i < n; i++) {
      num += (xs[i] - xMean) * (last20[i] - yMean);
      den += (xs[i] - xMean) ** 2;
    }
    const slope = den > 0 ? num / den : 0;
    // 하루당 yMean 의 0.5% 변동 → 점수 만점/최저
    const norm = yMean > 0 ? slope / (yMean * 0.005) : 0;
    trend = clamp01(norm);
  }

  const parts = [momentum, flow, sentiment, trend].filter(
    (v): v is number => v != null,
  );
  const composite =
    parts.length > 0 ? parts.reduce((a, b) => a + b, 0) / parts.length : null;

  return {
    momentum: pct(momentum),
    flow: pct(flow),
    sentiment: pct(sentiment),
    trend: pct(trend),
    composite: pct(composite),
  };
}

// -1~+1 입력 → 0~1 출력 (중립 0.5).
function clamp01(x: number): number {
  return Math.max(0, Math.min(1, 0.5 + x / 2));
}

function pct(v: number | null): number | null {
  return v == null ? null : Math.round(v * 100);
}

export function CompositeScoreCard({ chart }: { chart: ChartPayload }) {
  const s = computeScores(chart);
  return (
    <div className="rounded-md border border-zinc-800 bg-zinc-900/40 p-4">
      <CardHeader title="종합 점수 (AI)" subtitle="모멘텀·수급·감성·추세 평균" />
      <div className="grid grid-cols-[auto_1fr] items-center gap-5">
        <ScoreDial value={s.composite} />
        <div className="grid grid-cols-2 gap-2">
          <SubScore label="모멘텀" value={s.momentum} hint="SMA5 vs SMA20" />
          <SubScore label="수급" value={s.flow} hint="외국인+기관 5일" />
          <SubScore label="감성" value={s.sentiment} hint="뉴스 7일 가중" />
          <SubScore label="추세" value={s.trend} hint="20일 회귀 기울기" />
        </div>
      </div>
      <div className="mt-3 text-[11px] text-zinc-500">
        점수는 보조지표일 뿐 매매 추천이 아닙니다. 50 = 중립, 100 = 매우 강세.
      </div>
    </div>
  );
}

function ScoreDial({ value }: { value: number | null }) {
  // CSS conic-gradient 반원 게이지. 0~100 → 0~180°.
  const v = value ?? 50;
  const angle = (v / 100) * 180;
  const tone =
    value == null
      ? "text-zinc-400"
      : value >= 65
      ? "text-rose-400"
      : value <= 35
      ? "text-sky-400"
      : "text-amber-300";
  const ringColor =
    value == null
      ? "#52525b"
      : value >= 65
      ? "#ef4444"
      : value <= 35
      ? "#3b82f6"
      : "#f59e0b";
  return (
    <div className="relative h-24 w-24">
      <div
        className="absolute inset-0 rounded-full"
        style={{
          background: `conic-gradient(from 270deg, ${ringColor} 0deg, ${ringColor} ${angle}deg, #27272a ${angle}deg, #27272a 180deg, transparent 180deg)`,
          mask: "radial-gradient(circle, transparent 38px, #000 39px)",
          WebkitMask:
            "radial-gradient(circle, transparent 38px, #000 39px)",
        }}
      />
      <div className="absolute inset-0 flex flex-col items-center justify-center pt-2">
        <div className={`text-xl font-bold tabular-nums ${tone}`}>
          {value == null ? "—" : value}
        </div>
        <div className="text-[10px] text-zinc-500">/ 100</div>
      </div>
    </div>
  );
}

function SubScore({
  label,
  value,
  hint,
}: {
  label: string;
  value: number | null;
  hint: string;
}) {
  const tone =
    value == null
      ? "text-zinc-400"
      : value >= 65
      ? "text-rose-400"
      : value <= 35
      ? "text-sky-400"
      : "text-zinc-200";
  const barColor =
    value == null
      ? "bg-zinc-700"
      : value >= 65
      ? "bg-rose-500/70"
      : value <= 35
      ? "bg-sky-500/70"
      : "bg-amber-500/60";
  return (
    <div className="rounded-md border border-zinc-800 bg-zinc-900/30 px-2 py-1.5">
      <div className="flex items-baseline justify-between">
        <span className="text-[11px] text-zinc-400">{label}</span>
        <span className={`text-sm font-medium tabular-nums ${tone}`}>
          {value == null ? "—" : value}
        </span>
      </div>
      <div className="mt-1 h-1 w-full overflow-hidden rounded-full bg-zinc-800">
        <div
          className={`h-full ${barColor}`}
          style={{ width: `${value ?? 0}%` }}
        />
      </div>
      <div className="mt-0.5 text-[10px] text-zinc-600">{hint}</div>
    </div>
  );
}
