"use client";

import { useState, useRef, useCallback, useEffect } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { X, Download, Share2, Loader2 } from "lucide-react";
import { useToast } from "@/hooks/useToast";
import { useShare } from "@/hooks/useShare";
import {
  loadImageAsDataUrl,
  generateImage,
  downloadDataUrl,
  dataUrlToFile,
} from "@/lib/shareImage";
import RestaurantShareCard, {
  type RestaurantShareData,
} from "@/components/RestaurantShareCard";
import BlindboxShareCard, {
  type BlindboxShareData,
} from "@/components/BlindboxShareCard";
import BlindboxPlanShareCard, {
  type PlanShareData,
} from "@/components/BlindboxPlanShareCard";

export type ShareCardData = RestaurantShareData | BlindboxShareData | PlanShareData;

interface ShareCardModalProps {
  open: boolean;
  onClose: () => void;
  data: ShareCardData;
}

export default function ShareCardModal({
  open,
  onClose,
  data,
}: ShareCardModalProps) {
  const toast = useToast();
  const cardRef = useRef<HTMLDivElement>(null);
  const backdropRef = useRef<HTMLDivElement>(null);
  const [generating, setGenerating] = useState(false);
  const [imageDataUrl, setImageDataUrl] = useState<string | null>(null);
  const [imageLoading, setImageLoading] = useState(false);

  const [bgDataUrl, setBgDataUrl] = useState<string | null>(null);

  const imageSrc = data.type === "restaurant" ? data.restaurant.images?.[0] : undefined;
  const bgSrc =
    data.type === "restaurant"
      ? "/share-bg-panic.png"
      : data.type === "blindbox" || data.type === "plan"
        ? "/share-bg-blindbox.png"
        : undefined;

  useEffect(() => {
    if (!open) {
      setImageDataUrl(null);
      setBgDataUrl(null);
      return;
    }

    const promises: Promise<void>[] = [];

    if (imageSrc) {
      promises.push(
        loadImageAsDataUrl(imageSrc).then(setImageDataUrl),
      );
    }
    if (bgSrc) {
      promises.push(
        loadImageAsDataUrl(bgSrc).then(setBgDataUrl),
      );
    }

    if (promises.length > 0) {
      setImageLoading(true);
      Promise.all(promises).finally(() => setImageLoading(false));
    }
  }, [open, imageSrc, bgSrc]);

  const handleGenerate = useCallback(async (): Promise<string | null> => {
    if (!cardRef.current) return null;
    setGenerating(true);
    try {
      return await generateImage(cardRef.current);
    } catch {
      try {
        setImageDataUrl(null);
        await new Promise((r) => setTimeout(r, 100));
        if (!cardRef.current) return null;
        return await generateImage(cardRef.current);
      } catch {
        return null;
      }
    } finally {
      setGenerating(false);
    }
  }, []);

  const handleSave = useCallback(async () => {
    const png = await handleGenerate();
    if (!png) {
      toast.show("生成图片失败，请重试");
      return;
    }
    const name =
      data.type === "restaurant"
        ? `NoWhatever_${data.restaurant.name}.png`
        : `NoWhatever_周末契约.png`;
    downloadDataUrl(png, name);
    toast.show("图片已保存");
  }, [handleGenerate, toast, data]);

  const { share: nativeShare } = useShare();

  const handleShare = useCallback(async () => {
    const png = await handleGenerate();
    if (!png) {
      toast.show("生成图片失败，请重试");
      return;
    }

    const file = dataUrlToFile(png, "NoWhatever.png");
    const shared = await nativeShare({ files: [file] });
    if (!shared) {
      downloadDataUrl(png, "NoWhatever.png");
      toast.show("图片已保存，快去分享吧！");
    }
  }, [handleGenerate, toast, nativeShare]);

  const handleBackdropClick = (e: React.MouseEvent) => {
    if (e.target === backdropRef.current) onClose();
  };

  return (
    <AnimatePresence>
      {open && (
        <motion.div
          ref={backdropRef}
          className="fixed inset-0 z-70 overflow-y-auto overflow-x-hidden bg-black/80 backdrop-blur-sm scrollbar-none"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          transition={{ duration: 0.2 }}
          onClick={handleBackdropClick}
        >
          <motion.div
            className="flex min-h-dvh flex-col items-center justify-center px-5 py-6"
            initial={{ opacity: 0, scale: 0.92 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.92 }}
            transition={{ duration: 0.25, ease: "easeOut" }}
          >
            {/* Card + close button wrapper */}
            <div className="relative flex shrink-0 justify-center">
              <button
                onClick={onClose}
                aria-label="关闭"
                className="absolute right-3 top-3 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-black/40 text-white/70 transition-colors active:bg-black/60"
              >
                <X size={16} />
              </button>
              {imageLoading ? (
                <div
                  style={{ width: 340, height: 400 }}
                  className="flex items-center justify-center rounded-2xl bg-[#111113]"
                >
                  <Loader2
                    size={24}
                    className="animate-spin text-gray-500"
                  />
                </div>
              ) : data.type === "restaurant" ? (
                <RestaurantShareCard
                  data={data}
                  cardRef={cardRef}
                  imageDataUrl={imageDataUrl}
                  bgDataUrl={bgDataUrl}
                />
              ) : data.type === "plan" ? (
                <BlindboxPlanShareCard data={data} cardRef={cardRef} bgDataUrl={bgDataUrl} />
              ) : (
                <BlindboxShareCard data={data} cardRef={cardRef} bgDataUrl={bgDataUrl} />
              )}
            </div>

            {/* Action buttons */}
            <div className="mt-5 flex w-full max-w-[340px] shrink-0 gap-3">
              <button
                onClick={handleSave}
                disabled={generating}
                className="flex h-12 flex-1 items-center justify-center gap-2 rounded-2xl bg-white/10 text-sm font-semibold text-gray-200 transition-colors active:bg-white/15 disabled:opacity-50"
              >
                {generating ? (
                  <Loader2 size={16} className="animate-spin" />
                ) : (
                  <Download size={16} />
                )}
                保存图片
              </button>
              <button
                onClick={handleShare}
                disabled={generating}
                className={`flex h-12 flex-1 items-center justify-center gap-2 rounded-2xl text-sm font-bold text-white shadow-lg transition-colors disabled:opacity-50 ${
                  data.type === "blindbox" || data.type === "plan"
                    ? "bg-purple-600 shadow-purple-900/30 active:bg-purple-500"
                    : "bg-emerald-600 shadow-emerald-900/30 active:bg-emerald-500"
                }`}
              >
                {generating ? (
                  <Loader2 size={16} className="animate-spin" />
                ) : (
                  <Share2 size={16} />
                )}
                分享给好友
              </button>
            </div>

            <p className="mt-3 shrink-0 text-center text-[10px] text-gray-500">
              长按图片也可以保存到相册
            </p>
          </motion.div>
        </motion.div>
      )}
    </AnimatePresence>
  );
}
