"use client";

// 토스증권 뉴스 카드 스타일을 흉내낸 리스트.
//
// 백엔드가 OG 썸네일은 아직 안 주므로 텍스트 카드 + 감성 칩 + 출처 배지만.
// 썸네일은 백엔드에 og_image 컬럼이 들어오면 추가.

import { useEffect, useState } from "react";
import { api, type NewsItem, type NewsResponse } from "../lib/api";
import { CardHeader } from "./CardHeader";

export function NewsList({ code }: { code: string }) {
  const [data, setData] = useState<NewsResponse | null>(null);
  const [err, setErr] = useState<string | null>(null);

  useEffect(() => {
    let alive = true;
    api
      .news(code, 20)
      .then((r) => {
        if (alive) setData(r);
      })
      .catch((e) => {
        if (alive) setErr(e instanceof Error ? e.message : String(e));
      });
    return () => {
      alive = false;
    };
  }, [code]);

  if (err) return <div className="text-xs text-red-400">뉴스 로딩 실패: {err}</div>;
  if (!data) return <div className="text-xs text-zinc-500">뉴스 로딩 중…</div>;
  if (!data.items.length)
    return <div className="text-xs text-zinc-500">최근 뉴스 없음</div>;

  return (
    <div className="rounded-md border border-zinc-800 bg-zinc-900/40 p-4">
      <CardHeader title="뉴스 · 공시" subtitle={`최근 ${data.items.length}건`} />
      <ul className="space-y-2">
        {data.items.map((n, i) => (
          <NewsCard key={i} n={n} />
        ))}
      </ul>
    </div>
  );
}

function NewsCard({ n }: { n: NewsItem }) {
  return (
    <li>
      <a
        href={n.url}
        target="_blank"
        rel="noopener noreferrer"
        className="block rounded-md border border-transparent p-2 transition hover:border-zinc-700 hover:bg-zinc-800/40"
      >
        <div className="text-sm leading-snug text-zinc-100 line-clamp-2">{n.title}</div>
        <div className="mt-1.5 flex flex-wrap items-center gap-1.5 text-[11px]">
          <SourceBadge source={n.source} />
          {n.published_at && (
            <span className="text-zinc-500">{formatRelative(n.published_at)}</span>
          )}
          {n.sentiment_label && (
            <SentimentChip label={n.sentiment_label} score={n.sentiment_score} />
          )}
        </div>
      </a>
    </li>
  );
}

function SourceBadge({ source }: { source: string }) {
  return (
    <span className="rounded-sm bg-zinc-800 px-1.5 py-0.5 text-zinc-300">{source}</span>
  );
}

function SentimentChip({
  label,
  score,
}: {
  label: string;
  score: number | null;
}) {
  // KR 관행: 긍정=빨강, 부정=파랑 (StockChart 와 톤 일치)
  const tone =
    label === "positive"
      ? "bg-rose-500/15 text-rose-300"
      : label === "negative"
      ? "bg-sky-500/15 text-sky-300"
      : "bg-zinc-700/40 text-zinc-400";
  const text =
    label === "positive" ? "긍정" : label === "negative" ? "부정" : "중립";
  return (
    <span className={`rounded-sm px-1.5 py-0.5 ${tone}`}>
      {text}
      {score != null && ` ${score >= 0 ? "+" : ""}${score.toFixed(2)}`}
    </span>
  );
}

function formatRelative(iso: string): string {
  try {
    const d = new Date(iso);
    const now = Date.now();
    const diffMin = Math.round((now - d.getTime()) / 60000);
    if (diffMin < 1) return "방금";
    if (diffMin < 60) return `${diffMin}분 전`;
    if (diffMin < 60 * 24) return `${Math.round(diffMin / 60)}시간 전`;
    if (diffMin < 60 * 24 * 7) return `${Math.round(diffMin / (60 * 24))}일 전`;
    return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
  } catch {
    return iso;
  }
}

function pad(n: number): string {
  return n < 10 ? `0${n}` : `${n}`;
}
