"use client";

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

type VoteOption = number | "ALL";

interface VoteModalProps {
  /** 当前要投票的艺人，传 null 关闭弹窗 */
  artist: Artist | null;
  /** 今日剩余票数（ALL 即投出该数值） */
  remaining: number;
  /** 每日总额度（用于副文案展示） */
  dailyQuota: number;
  /** 关闭弹窗 */
  onClose: () => void;
  /** 确认投票（count 为最终实际投票数，ALL 会被解析为 remaining） */
  onConfirm: (artist: Artist, count: number) => void | Promise<void>;
}

const VOTE_OPTIONS: VoteOption[] = [1, 3, 5, "ALL"];

function defaultOption(remaining: number): VoteOption {
  if (remaining >= 3) return 3;
  if (remaining >= 1) return remaining as VoteOption;
  return "ALL";
}

function resolveCount(opt: VoteOption, remaining: number): number {
  return opt === "ALL" ? remaining : opt;
}

export default function VoteModal({
  artist,
  remaining,
  dailyQuota,
  onClose,
  onConfirm,
}: VoteModalProps) {
  const open = artist != null;
  const [selected, setSelected] = useState<VoteOption>(defaultOption(remaining));
  const [loading, setLoading] = useState(false);
  const [mounted, setMounted] = useState(false);

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

  // 打开时重置默认选择
  useEffect(() => {
    if (open) {
      setSelected(defaultOption(remaining));
      setLoading(false);
    }
  }, [open, remaining]);

  // 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 actualCount = resolveCount(selected, remaining);
  const canSubmit = remaining > 0 && actualCount > 0 && actualCount <= remaining;

  const handleConfirm = useCallback(async () => {
    if (!artist || loading || !canSubmit) return;
    setLoading(true);
    try {
      await onConfirm(artist, actualCount);
    } finally {
      setLoading(false);
    }
  }, [artist, actualCount, canSubmit, loading, 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)]">
              <ArtistPortrait
                artist={artist}
                rounded="rounded-full"
                className="w-full h-full"
              />
            </div>

            {/* 标题 */}
            <div className="text-center mb-4">
              <div
                id="vote-modal-title"
                className="text-lg font-bold text-white mb-1"
              >
                为 {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="flex items-center justify-between text-xs mb-2.5">
              <span className="text-white/55">选择投票数：</span>
              <span className="text-purple-300 tabular-nums">
                今日剩余 {remaining} / {dailyQuota}
              </span>
            </div>

            {/* 票数选择 */}
            <div className="flex gap-2.5 justify-center mb-5">
              {VOTE_OPTIONS.map((opt) => {
                const active = selected === opt;
                const optValue = resolveCount(opt, remaining);
                const disabled =
                  remaining === 0 ||
                  optValue === 0 ||
                  optValue > remaining ||
                  (opt === "ALL" && remaining === 0);
                return (
                  <button
                    type="button"
                    key={String(opt)}
                    onClick={() => !disabled && setSelected(opt)}
                    disabled={disabled}
                    className={cn(
                      "rounded-lg font-display text-base flex items-center justify-center transition-all w-14 h-13 py-3.5 px-3",
                      disabled &&
                        "bg-surface/40 border border-white/8 text-white/25 cursor-not-allowed",
                      !disabled &&
                        !active &&
                        "bg-surface border border-white/14 text-white/65 hover:border-white/30",
                      !disabled &&
                        active &&
                        "bg-purple-500/12 border border-purple-500 text-purple-300 shadow-[0_0_16px_rgba(139,92,246,0.35)]",
                    )}
                  >
                    {opt}
                  </button>
                );
              })}
            </div>

            {/* 确认按钮 */}
            <Button
              variant="primary"
              className="w-full h-12 text-sm"
              onClick={handleConfirm}
              loading={loading}
              disabled={!canSubmit}
              leftIcon={<Heart size={14} />}
            >
              {remaining === 0
                ? "今日票数已用完"
                : `确认投出 ${actualCount} 票`}
            </Button>
          </motion.div>
        </motion.div>
      )}
    </AnimatePresence>,
    document.body,
  );
}
