"use client";

// 글로벌 가격 알람 폴러 + 인페이지 토스트.
//
// 동작:
//   1) alerts 구독 + 60s 인터벌마다 미발사(triggered=false) 알람 코드 set 수집
//   2) 각 코드별 /api/chart?days=2&interval=1d → 마지막 종가만 사용
//   3) 조건 (gte: close >= target, lte: close <= target) 만족 시 markTriggered + 토스트
//
// 알람이 0건이면 폴링 자체를 하지 않음 (네트워크 정숙).
// 토스트는 우측 하단에 쌓이며 6초 후 자동 dismiss.
//
// 브라우저 Notification 은 사용자가 허용한 경우에만 발송.

import { useEffect, useRef, useState } from "react";
import Link from "next/link";
import { api } from "../lib/api";
import { alerts, type Alert } from "../lib/alerts";

type Toast = {
  id: string;
  code: string;
  name?: string;
  op: Alert["op"];
  target: number;
  price: number;
};

const POLL_MS = 60_000;
const TOAST_TTL_MS = 6_000;

export function AlertsToaster() {
  const [active, setActive] = useState<Alert[]>([]);
  const [toasts, setToasts] = useState<Toast[]>([]);
  const tickingRef = useRef(false);

  useEffect(() => {
    const refresh = () => setActive(alerts.list().filter((a) => !a.triggered));
    refresh();
    return alerts.subscribe(refresh);
  }, []);

  // 폴링.
  useEffect(() => {
    if (active.length === 0) return;
    let alive = true;

    const codes = Array.from(new Set(active.map((a) => a.code)));

    const tick = async () => {
      if (tickingRef.current) return;
      tickingRef.current = true;
      try {
        // 종목별 마지막 종가 (직전 2 거래일만 받음 — 가볍게).
        const prices = new Map<string, number | null>();
        await Promise.allSettled(
          codes.map(async (code) => {
            const c = await api.getChart(code, 2, "1d");
            const valid = c.ohlcv.filter((p) => p.close != null);
            const last = valid[valid.length - 1] ?? null;
            prices.set(code, last?.close ?? null);
          }),
        );
        if (!alive) return;

        // 알람 평가 — 최신 스냅샷(read)으로 재조회 (구독 사이 추가/삭제 반영).
        const fresh = alerts.list().filter((a) => !a.triggered);
        const newToasts: Toast[] = [];
        for (const a of fresh) {
          const p = prices.get(a.code);
          if (p == null) continue;
          const hit =
            (a.op === "gte" && p >= a.target) ||
            (a.op === "lte" && p <= a.target);
          if (!hit) continue;
          alerts.markTriggered(a.id);
          newToasts.push({
            id: a.id,
            code: a.code,
            name: a.name,
            op: a.op,
            target: a.target,
            price: p,
          });
          // 브라우저 알림 (권한 허용 시).
          if (
            typeof window !== "undefined" &&
            "Notification" in window &&
            Notification.permission === "granted"
          ) {
            try {
              new Notification(`${a.name ?? a.code} 알람`, {
                body: `${a.op === "gte" ? "≥" : "≤"} ${a.target.toLocaleString()} · 현재 ${p.toLocaleString()}`,
              });
            } catch {
              // 무시
            }
          }
        }
        if (newToasts.length) {
          setToasts((cur) => [...cur, ...newToasts]);
          for (const t of newToasts) {
            window.setTimeout(() => {
              setToasts((cur) => cur.filter((x) => x.id !== t.id));
            }, TOAST_TTL_MS);
          }
        }
      } finally {
        tickingRef.current = false;
      }
    };

    tick();
    const h = window.setInterval(tick, POLL_MS);
    return () => {
      alive = false;
      window.clearInterval(h);
    };
  }, [active]);

  if (toasts.length === 0) return null;

  return (
    <div className="pointer-events-none fixed bottom-4 right-4 z-50 flex flex-col items-end gap-2">
      {toasts.map((t) => (
        <Link
          key={t.id}
          href={`/${t.code}`}
          className="pointer-events-auto block w-72 rounded-md border border-amber-500/40 bg-zinc-950/95 p-3 shadow-xl backdrop-blur"
        >
          <div className="flex items-center justify-between gap-2">
            <span className="text-xs font-medium text-amber-300">🔔 가격 알람</span>
            <span className="text-[10px] text-zinc-500">{t.code}</span>
          </div>
          <div className="mt-1 text-sm font-semibold text-zinc-100">
            {t.name ?? t.code}
          </div>
          <div className="mt-1 text-[11px] text-zinc-400">
            {t.op === "gte" ? "≥" : "≤"} {t.target.toLocaleString()} 도달 ·
            현재 <span className="tabular-nums text-zinc-100">{t.price.toLocaleString()}</span>
          </div>
        </Link>
      ))}
    </div>
  );
}
