"use client";

import { useEffect, useState, useCallback } from "react";
import { createPortal } from "react-dom";
import { AnimatePresence, motion } from "framer-motion";
import { X, Heart, AlertCircle, Check } from "lucide-react";
import type { Artist } from "@/types/artist";
import { cn } from "@/lib/cn";
import { useVoteStore, selectHasVoted } from "@/lib/store";
import Button from "./ui/Button";
import ArtistPortrait from "./cards/ArtistPortrait";

interface VoteModalProps {
  /** 当前要投票的艺人,传 null 关闭弹窗 */
  artist: Artist | null;
  /** 剩余可投票数(终身 12 - 已投) */
  remaining: number;
  /** 总额度常量 12(用于文案 "X / 12") */
  totalQuota: number;
  /** 关闭弹窗 */
  onClose: () => void;
  /** 确认投票(无 count 参数,固定 1 票) */
  onConfirm: (artist: Artist) => void | Promise<void>;
}

export default function VoteModal({
  artist,
  remaining,
  totalQuota,
  onClose,
  onConfirm,
}: VoteModalProps) {
  const open = artist != null;
  const [loading, setLoading] = useState(false);
  const [mounted, setMounted] = useState(false);

  // 即时判断当前艺人是否已被投过(避免父组件忘传防护)
  const hasVotedSelector = artist ? selectHasVoted(artist.id) : () => false;
  const hasVoted = useVoteStore(hasVotedSelector);

  useEffect(() => setMounted(true), []);

  // 打开时重置 loading 态
  useEffect(() => {
    if (open) setLoading(false);
  }, [open]);

  // ESC 关闭 + body 锁滚
  useEffect(() => {
    if (!open) return;
    const handler = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
    };
    window.addEventListener("keydown", handler);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", handler);
      document.body.style.overflow = prev;
    };
  }, [open, onClose]);

  const exhausted = remaining <= 0;
  const canSubmit = !exhausted && !hasVoted && !loading;

  const handleConfirm = useCallback(async () => {
    if (!artist || !canSubmit) return;
    setLoading(true);
    try {
      await onConfirm(artist);
    } finally {
      setLoading(false);
    }
  }, [artist, canSubmit, onConfirm]);

  if (!mounted) return null;

  return createPortal(
    <AnimatePresence>
      {open && artist && (
        <motion.div
          key="vote-modal-root"
          className="fixed inset-0 z-[100] flex items-center justify-center px-4"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          transition={{ duration: 0.2 }}
        >
          {/* 遮罩 */}
          <button
            type="button"
            aria-label="关闭弹窗"
            onClick={onClose}
            className="absolute inset-0 bg-black/75 backdrop-blur-md cursor-default"
          />

          {/* 弹窗主体 */}
          <motion.div
            role="dialog"
            aria-modal="true"
            aria-labelledby="vote-modal-title"
            className="relative w-full max-w-sm bg-elevated border border-white/14 rounded-2xl p-7 shadow-[0_24px_80px_rgba(0,0,0,0.7),0_0_40px_rgba(139,92,246,0.12)]"
            initial={{ opacity: 0, scale: 0.94, y: 16 }}
            animate={{ opacity: 1, scale: 1, y: 0 }}
            exit={{ opacity: 0, scale: 0.96, y: 8 }}
            transition={{ duration: 0.28, ease: [0.22, 1, 0.36, 1] }}
          >
            {/* 关闭按钮 */}
            <button
              type="button"
              onClick={onClose}
              className="absolute top-3.5 right-4 w-7 h-7 flex items-center justify-center text-white/55 hover:text-white transition-colors"
              aria-label="关闭"
            >
              <X size={18} />
            </button>

            {/* 头像 */}
            <div className="w-20 h-20 mx-auto mb-3.5 rounded-full overflow-hidden border-2 border-purple-500 shadow-[0_0_16px_rgba(139,92,246,0.4)] relative">
              <ArtistPortrait
                artist={artist}
                rounded="rounded-full"
                className="w-full h-full"
              />
              {hasVoted && (
                <div className="absolute inset-0 bg-black/55 flex items-center justify-center">
                  <Check size={28} className="text-purple-300" strokeWidth={3} />
                </div>
              )}
            </div>

            {/* 标题 */}
            <div className="text-center mb-3.5">
              <div
                id="vote-modal-title"
                className="text-lg font-bold text-white mb-1"
              >
                {hasVoted
                  ? `已为 ${artist.name} 投过票`
                  : exhausted
                    ? "12 票已用完"
                    : `为 ${artist.name} 投票`}
              </div>
              <div className="font-label text-[11px] tracking-widest text-white/45 uppercase">
                No.{artist.no} · Current Rank #{artist.rank}
              </div>
            </div>

            {/* 剩余票数显示 */}
            <div
              className={cn(
                "flex items-center justify-between text-xs mb-4 px-3 py-2.5 rounded-lg border",
                exhausted
                  ? "border-pink-400/30 bg-pink-400/[0.05]"
                  : "border-purple-500/25 bg-purple-500/[0.06]",
              )}
            >
              <span className="text-white/65">你的剩余票数</span>
              <span
                className={cn(
                  "font-display tabular-nums text-base",
                  exhausted ? "text-pink-300" : "text-purple-300",
                )}
              >
                {remaining}{" "}
                <span className="text-white/40 text-xs">/ {totalQuota}</span>
              </span>
            </div>

            {/* 规则提示 · 不可撤销警示(仅在可投态显示) */}
            {!hasVoted && !exhausted && (
              <div className="flex items-start gap-2 mb-5 px-3 py-2.5 rounded-lg bg-white/[0.03] border border-white/[0.06]">
                <AlertCircle
                  size={14}
                  className="text-purple-300/80 mt-0.5 flex-shrink-0"
                />
                <p className="text-[11px] leading-relaxed text-white/65">
                  投出后不可撤销 · 每位艺人仅能投 1 票
                </p>
              </div>
            )}

            {/* 确认按钮 */}
            <Button
              variant="primary"
              className="w-full h-12 text-sm"
              onClick={hasVoted || exhausted ? onClose : handleConfirm}
              loading={loading}
              disabled={loading}
              leftIcon={
                hasVoted || exhausted ? undefined : <Heart size={14} />
              }
            >
              {hasVoted
                ? "好的"
                : exhausted
                  ? "感谢支持"
                  : "投出我的一票"}
            </Button>
          </motion.div>
        </motion.div>
      )}
    </AnimatePresence>,
    document.body,
  );
}
