import { create } from "zustand";
import { ARTISTS } from "./mock-data";
import type { Artist } from "@/types/artist";

/** 每日基础投票额度（与后端 ActivityConfig.dailyQuota 对齐） */
export const DAILY_VOTE_QUOTA = 10;

/** 派生类型：我支持的某位艺人 + 我为 ta 投出的票数 */
export interface MySupport {
  artist: Artist;
  votedCount: number;
}

interface VoteStore {
  /** 当前所有艺人（含动态票数 / 实时排名） */
  artists: Artist[];
  /** 我为每个艺人投出的票数（artistId → count，仅 > 0 的进入"我的应援"列表） */
  myVotesByArtist: Record<string, number>;
  /** 累计已投票数（= sum(myVotesByArtist)） */
  myTotalVotes: number;
  /** 今日已用票数（跨日自动重置） */
  usedToday: number;
  /** 今日额度日期标记（YYYY-M-D，按本地时区） */
  quotaDate: string;
  /**
   * 给艺人投票（本地模拟，会重新排名）。
   * 票数不足时返回 false，前端可据此提示。
   */
  vote: (artistId: string, count: number) => boolean;
  /** 重置（开发时用） */
  reset: () => void;
}

function todayKey(): string {
  const d = new Date();
  return `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`;
}

/** 票数倒序 + 编号升序兜底,确保 0 票时也有稳定排名 */
function rank(list: Artist[]): Artist[] {
  return [...list]
    .sort((a, b) => b.votes - a.votes || a.no.localeCompare(b.no))
    .map((a, i) => ({ ...a, rank: i + 1 }));
}

const INITIAL = rank(ARTISTS);

export const useVoteStore = create<VoteStore>((set) => ({
  artists: INITIAL,
  myVotesByArtist: {},
  myTotalVotes: 0,
  usedToday: 0,
  quotaDate: todayKey(),
  vote: (artistId, count) => {
    let success = false;
    set((state) => {
      const today = todayKey();
      const baseUsed = state.quotaDate === today ? state.usedToday : 0;
      const remaining = DAILY_VOTE_QUOTA - baseUsed;
      if (count <= 0 || count > remaining) {
        return state;
      }
      success = true;
      const updated = state.artists.map((a) =>
        a.id === artistId ? { ...a, votes: a.votes + count } : a,
      );
      return {
        artists: rank(updated),
        myVotesByArtist: {
          ...state.myVotesByArtist,
          [artistId]: (state.myVotesByArtist[artistId] ?? 0) + count,
        },
        myTotalVotes: state.myTotalVotes + count,
        usedToday: baseUsed + count,
        quotaDate: today,
      };
    });
    return success;
  },
  reset: () =>
    set({
      artists: INITIAL,
      myVotesByArtist: {},
      myTotalVotes: 0,
      usedToday: 0,
      quotaDate: todayKey(),
    }),
}));

/** 便捷选择器：按 ID 获取最新艺人 */
export function selectArtist(id: string) {
  return (s: VoteStore) => s.artists.find((a) => a.id === id);
}

/** 选择器：当前剩余票数（跨日自动重置） */
export function selectRemaining(s: VoteStore): number {
  // 必须按 quotaDate 判断是否还属于今日：跨过午夜后 usedToday 仍是昨日值，
  // 但 today 切换后基线应回到 0，余票回到满额。下次 vote() 才会真正落库重置。
  const today = todayKey();
  const baseUsed = s.quotaDate === today ? s.usedToday : 0;
  return Math.max(0, DAILY_VOTE_QUOTA - baseUsed);
}

/**
 * 派生函数："我的应援"列表 —— 凡是我投过票（>0）的艺人都进入，
 * 按我投出的票数降序，artist 字段使用 store 最新排名。
 *
 * ⚠️ 不要直接 `useVoteStore(selectMySupports)`：它每次都返回新数组，
 *    会触发 React 19 的 "getSnapshot should be cached" 报错。
 *    正确用法：分别订阅 `s.myVotesByArtist` 和 `s.artists`，在组件里 useMemo 派生。
 */
export function selectMySupports(s: VoteStore): MySupport[] {
  const list: MySupport[] = [];
  for (const [id, votedCount] of Object.entries(s.myVotesByArtist)) {
    if (votedCount <= 0) continue;
    const artist = s.artists.find((a) => a.id === id);
    if (artist) list.push({ artist, votedCount });
  }
  list.sort((a, b) => b.votedCount - a.votedCount);
  return list;
}

/** 选择器：我支持的艺人数（去重，仅计 > 0 票） */
export function selectMySupportingCount(s: VoteStore): number {
  let n = 0;
  for (const v of Object.values(s.myVotesByArtist)) if (v > 0) n++;
  return n;
}
