"use client";

import { useMemo } from "react";
import Top3Podium from "@/components/ranking/Top3Podium";
import RankingRow from "@/components/ranking/RankingRow";
import DebutLineDivider from "@/components/ranking/DebutLineDivider";
import VoteModal from "@/components/VoteModal";
import LiveBadge from "@/components/LiveBadge";
import { sortArtists } from "@/lib/mock-data";
import { useVoteStore } from "@/lib/store";
import { useVoteAction } from "@/hooks/useVoteAction";
import { useRanking } from "@/hooks/useRanking";
import type { Artist } from "@/types/artist";

export default function RankingPage() {
  const storeArtists = useVoteStore((s) => s.artists);
  const { target, remaining, dailyQuota, openVote, closeVote, confirmVote } =
    useVoteAction();

  const live = useRanking({ pollInterval: 30_000 });

  // 数据同步：本地乐观投票 + 服务端最新票数取 max（避免 API 落后覆盖本地新票，
  // 也避免本地缺其他用户的票数）。合并后按 votes desc + no asc 重新排序并赋 rank。
  const sorted = useMemo<Artist[]>(() => {
    const apiVotes = new Map<string, number>();
    if (live.data?.list) {
      for (const row of live.data.list) apiVotes.set(row.id, row.voteCount);
    }
    const merged = storeArtists.map((a) => {
      const apiV = apiVotes.get(a.id) ?? 0;
      return apiV > a.votes ? { ...a, votes: apiV } : a;
    });
    const ranked = sortArtists(merged, "votes");
    // 重新按合并后的排名赋 rank（store 自带的 rank 仅来自本地 vote 后的 rank()）
    return ranked.map((a, i) => ({ ...a, rank: i + 1 }));
  }, [storeArtists, live.data]);

  // 仅有票的人能"进榜单"，0 票不参与排名兜底
  const ranked = sorted.filter((a) => a.votes > 0);
  const zeros = sorted.filter((a) => a.votes === 0);
  // 只要有 1 人有票就显示领奖台（#2/#3 缺位会自动以"虚位以待"占位）；
  // 至少 12 人有票才有"出道线 / 复活位"概念
  const podiumReady = ranked.length >= 1;
  const debutReady = ranked.length >= 12;

  const top3 = podiumReady ? ranked.slice(0, 3) : [];

  // 出道线上方（top3 之后到出道线之间）
  // - Top12 满员：经典 9 位（rank 4-12）
  // - 已有领奖台但 Top12 未满：podium 之后的所有有票
  // - 连领奖台都没满：所有有票的人都从这里开始
  const aboveLine = debutReady
    ? ranked.slice(3, 12)
    : podiumReady
      ? ranked.slice(3)
      : ranked;

  // 出道线下方
  // - Top12 满员：ranked[12..] + 全部 0 票
  // - 否则：仅 0 票
  const belowLine = debutReady ? [...ranked.slice(12), ...zeros] : zeros;

  const debutCutoff = debutReady ? ranked[11].votes : 0;

  return (
    <>
      <div className="max-w-[1500px] mx-auto px-4 sm:px-6 lg:px-8 py-8 sm:py-10">
        {/* Top 3 领奖台 */}
        <Top3Podium top3={top3} />

        {/* 实时刷新标识 */}
        <div className="flex justify-end mt-4 mb-2">
          <LiveBadge updatedAt={live.lastUpdated} paused={!!live.error} />
        </div>

        {/* 列表头部 */}
        <div className="mt-6 rounded-2xl border border-white/[0.06] bg-base/60 backdrop-blur-sm overflow-hidden">
          <div className="hidden sm:grid grid-cols-[72px_56px_1fr_96px_120px_88px] gap-4 px-4 py-3 text-[10px] tracking-widest uppercase text-white/45 font-label border-b border-white/[0.06]">
            <span className="text-center">排名</span>
            <span>头像</span>
            <span>艺人</span>
            <span className="text-right">票数</span>
            <span className="text-right">距上一名</span>
            <span className="text-center">操作</span>
          </div>

          <div>
            {aboveLine.map((a, idx) => {
              const prev =
                idx === 0
                  ? podiumReady
                    ? top3[2]
                    : undefined
                  : aboveLine[idx - 1];
              const gap = prev ? prev.votes - a.votes : undefined;
              return (
                <RankingRow
                  key={a.id}
                  artist={a}
                  gapAbove={gap}
                  onVote={openVote}
                />
              );
            })}
          </div>

          {/* 仅 Top12 满员才显示"出道线"分隔 */}
          {debutReady && <DebutLineDivider />}

          <div>
            {belowLine.map((a, idx) => {
              const prev =
                idx === 0 ? aboveLine[aboveLine.length - 1] : belowLine[idx - 1];
              const gap = prev ? prev.votes - a.votes : undefined;
              // 仅 Top12 满员时第一位才是"复活位"
              const isRescue = debutReady && idx === 0;
              const gapToDebut = isRescue ? debutCutoff - a.votes + 1 : undefined;
              return (
                <RankingRow
                  key={a.id}
                  artist={a}
                  gapAbove={gap}
                  gapToDebut={gapToDebut}
                  isRescue={isRescue}
                  onVote={openVote}
                />
              );
            })}
          </div>
        </div>

      </div>

      <VoteModal
        artist={target}
        remaining={remaining}
        dailyQuota={dailyQuota}
        onClose={closeVote}
        onConfirm={confirmVote}
      />
    </>
  );
}
