"use client";

import { useState, useCallback } from "react";
import { useSession } from "next-auth/react";
import toast from "react-hot-toast";
import {
  useVoteStore,
  selectRemaining,
  TOTAL_VOTE_QUOTA,
} from "@/lib/store";
import { useLoginModalStore } from "@/lib/login-modal-store";
import type { Artist } from "@/types/artist";

interface UseVoteActionResult {
  /** 当前投票目标艺人(null 时弹窗关闭) */
  target: Artist | null;
  /** 剩余可投票数(终身 12 票 - 已投艺人数) */
  remaining: number;
  /** 总额度常量 12(供 UI 文案展示) */
  totalQuota: number;
  /** 触发投票(自动检查登录态 / 已投态 / 额度) */
  openVote: (artist: Artist) => void;
  /** 关闭投票弹窗 */
  closeVote: () => void;
  /** 确认投票(已登录态下调用,固定投 1 票) */
  confirmVote: (artist: Artist) => Promise<void>;
}

/**
 * 投票交互统一入口。
 *
 * 新规则:
 *  - 每用户终身 12 票,每位艺人最多 1 票,不限时,不可撤销
 *  - 未登录 → toast 提示并跳登录弹窗
 *  - 已投过该艺人 → toast 提示,不打开弹窗
 *  - 12 票已用完 → toast 提示,不打开弹窗
 *  - 弹窗确认后:本地 store 立即记录 + 调用后端 API(fire-and-forget)
 */
export function useVoteAction(): UseVoteActionResult {
  const { status } = useSession();
  const recordVote = useVoteStore((s) => s.vote);
  const remaining = useVoteStore(selectRemaining);
  const votedArtists = useVoteStore((s) => s.votedArtists);
  const openLogin = useLoginModalStore((s) => s.show);
  const [target, setTarget] = useState<Artist | null>(null);

  const openVote = useCallback(
    (artist: Artist) => {
      if (status === "loading") return;
      if (status === "unauthenticated") {
        toast("请先登录后再为偶像投票");
        setTimeout(openLogin, 350);
        return;
      }
      if (votedArtists.includes(artist.id)) {
        toast(`你已为 ${artist.name} 投过票了`);
        return;
      }
      if (remaining <= 0) {
        toast("你的 12 票已用完,感谢支持");
        return;
      }
      setTarget(artist);
    },
    [status, openLogin, remaining, votedArtists],
  );

  const closeVote = useCallback(() => setTarget(null), []);

  const confirmVote = useCallback(
    async (artist: Artist) => {
      // 1. 本地 store 记录(包含已投/已满校验)
      const result = recordVote(artist.id);
      if (!result.ok) {
        if (result.reason === "already") {
          toast.error(`你已为 ${artist.name} 投过票了`);
        } else {
          toast.error("你的 12 票已用完,感谢支持");
        }
        setTarget(null);
        return;
      }

      // 投票成功:计算投票后状态,判断是否是最后一票
      const remainingAfter = remaining - 1;
      if (remainingAfter === 0) {
        toast.success(`完成!你的 12 票已全部投出 ✦`, { duration: 4000 });
      } else {
        toast.success(`已为 ${artist.name} 投票 · 剩余 ${remainingAfter} 票`);
      }
      setTarget(null);

      // 2. 后台 fire-and-forget 调用真实 API(5 秒超时,失败静默忽略)
      // 注意:旧 API 仍接收 count 参数,这里固定传 1。后端逻辑 unique 约束
      // 等后续提交单独迁移,现阶段前端 store 已保证不会重投。
      const ctrl = new AbortController();
      const timer = setTimeout(() => ctrl.abort(), 5000);
      fetch("/api/vote", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ artistId: artist.id, count: 1 }),
        signal: ctrl.signal,
      })
        .catch(() => {})
        .finally(() => clearTimeout(timer));
    },
    [recordVote, remaining],
  );

  return {
    target,
    remaining,
    totalQuota: TOTAL_VOTE_QUOTA,
    openVote,
    closeVote,
    confirmVote,
  };
}
