"use client";
import { CheckIcon, ExclamationIcon } from "@/assets/icons";
import { cn } from "@/lib/utils";
import { useIsMutating } from "@tanstack/react-query";
import gsap from "gsap";
import React, {
  useEffect,
  useLayoutEffect,
  useRef,
  useState,
} from "react";
import { createPortal } from "react-dom";
import { z } from "zod";

const ConfirmationModalPropsSchema = z.object({
  isOpen: z.boolean(),
  title: z.string().min(1, "Title is required"),
  message: z.string().min(1, "Message is required"),
  confirmText: z.string().optional().default("Confirm"),
  cancelText: z.string().optional().default("Cancel"),
  onConfirm: z.function(),
  onCancel: z.function(),
  variant: z
    .enum(["default", "danger", "warning"])
    .optional()
    .default("default"),
  size: z.enum(["sm", "md", "lg"]).optional().default("md"),
});

export type ConfirmationModalProps = z.infer<
  typeof ConfirmationModalPropsSchema
>;

type Variant = "default" | "danger" | "warning";

const variantStyles: Record<
  Variant,
  {
    accent: string;
    iconWrap: string;
    iconGlow: string;
    iconColor: string;
    confirmBtn: string;
    focusRing: string;
    Icon: React.ComponentType<React.SVGProps<SVGSVGElement>>;
  }
> = {
  default: {
    accent:
      "bg-gradient-to-r from-primary via-[#6B63F3] to-primary",
    iconWrap:
      "bg-gradient-to-br from-primary/15 via-primary/10 to-primary/5 ring-1 ring-inset ring-primary/20",
    iconGlow: "bg-primary/30",
    iconColor: "text-primary",
    confirmBtn:
      "bg-gradient-to-br from-primary to-[#4C46C9] hover:from-primary hover:to-primary text-white shadow-[0_6px_18px_-4px_rgba(87,80,241,0.55)]",
    focusRing: "focus-visible:ring-primary/40",
    Icon: CheckIcon,
  },
  danger: {
    accent:
      "bg-gradient-to-r from-error via-error-light to-error",
    iconWrap:
      "bg-gradient-to-br from-error/15 via-error/10 to-error/5 ring-1 ring-inset ring-error/20",
    iconGlow: "bg-error/35",
    iconColor: "text-error",
    confirmBtn:
      "bg-gradient-to-br from-error to-error-dark hover:from-error hover:to-error text-white shadow-[0_6px_18px_-4px_rgba(242,48,48,0.55)]",
    focusRing: "focus-visible:ring-error/40",
    Icon: ExclamationIcon,
  },
  warning: {
    accent:
      "bg-gradient-to-r from-yellow-dark via-yellow-light to-yellow-dark",
    iconWrap:
      "bg-gradient-to-br from-yellow-light/40 via-yellow-light/25 to-yellow-light/10 ring-1 ring-inset ring-yellow-dark/20",
    iconGlow: "bg-yellow-dark/30",
    iconColor: "text-yellow-dark-2",
    confirmBtn:
      "bg-gradient-to-br from-yellow-dark to-yellow-dark-2 hover:from-yellow-dark hover:to-yellow-dark text-white shadow-[0_6px_18px_-4px_rgba(217,119,6,0.5)]",
    focusRing: "focus-visible:ring-yellow-dark/40",
    Icon: ExclamationIcon,
  },
};

const sizeStyles: Record<"sm" | "md" | "lg", string> = {
  sm: "max-w-sm",
  md: "max-w-md",
  lg: "max-w-lg",
};

const ConfirmationModal: React.FC<ConfirmationModalProps> = (props) => {
  const isMutating = useIsMutating();
  const validatedProps = ConfirmationModalPropsSchema.parse(props);
  const {
    isOpen,
    title,
    message,
    confirmText,
    cancelText,
    onConfirm,
    onCancel,
    variant,
    size,
  } = validatedProps;

  const [mounted, setMounted] = useState(false);
  const [shouldRender, setShouldRender] = useState(isOpen);

  const overlayRef = useRef<HTMLDivElement>(null);
  const panelRef = useRef<HTMLDivElement>(null);
  const iconRef = useRef<HTMLDivElement>(null);
  const iconGlowRef = useRef<HTMLDivElement>(null);
  const activeTween = useRef<gsap.core.Timeline | null>(null);

  useEffect(() => {
    setMounted(true);
    return () => setMounted(false);
  }, []);

  // Mount/unmount gating so exit animation can play before unmount.
  useEffect(() => {
    if (isOpen) {
      setShouldRender(true);
    }
  }, [isOpen]);

  // Escape + body scroll lock
  useEffect(() => {
    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === "Escape" && isOpen) {
        onCancel();
      }
    };

    if (isOpen) {
      document?.addEventListener("keydown", handleEscape);
      if (document) document.body.style.overflow = "hidden";
    }

    return () => {
      document?.removeEventListener("keydown", handleEscape);
      if (document) document.body.style.overflow = "unset";
    };
  }, [isOpen, onCancel]);

  // Drive entrance/exit animations
  useLayoutEffect(() => {
    if (!shouldRender) return;
    if (!overlayRef.current || !panelRef.current) return;

    activeTween.current?.kill();

    if (isOpen) {
      gsap.set(overlayRef.current, { autoAlpha: 0 });
      gsap.set(panelRef.current, {
        autoAlpha: 0,
        scale: 0.9,
        y: 24,
      });
      if (iconRef.current) {
        gsap.set(iconRef.current, { scale: 0, rotation: -90 });
      }
      if (iconGlowRef.current) {
        gsap.set(iconGlowRef.current, { autoAlpha: 0, scale: 0.4 });
      }

      const tl = gsap.timeline();
      tl.to(overlayRef.current, {
        autoAlpha: 1,
        duration: 0.28,
        ease: "power2.out",
      })
        .to(
          panelRef.current,
          {
            autoAlpha: 1,
            scale: 1,
            y: 0,
            duration: 0.55,
            ease: "back.out(1.5)",
          },
          "-=0.18",
        )
        .to(
          iconRef.current,
          {
            scale: 1,
            rotation: 0,
            duration: 0.55,
            ease: "back.out(2.4)",
          },
          "-=0.32",
        )
        .fromTo(
          iconGlowRef.current,
          { autoAlpha: 0.7, scale: 0.5 },
          {
            autoAlpha: 0,
            scale: 1.8,
            duration: 0.9,
            ease: "power2.out",
          },
          "-=0.4",
        );
      activeTween.current = tl;
    } else {
      const tl = gsap.timeline({
        onComplete: () => setShouldRender(false),
      });
      tl.to(panelRef.current, {
        autoAlpha: 0,
        scale: 0.94,
        y: 12,
        duration: 0.22,
        ease: "power2.in",
      }).to(
        overlayRef.current,
        {
          autoAlpha: 0,
          duration: 0.22,
          ease: "power2.in",
        },
        "-=0.18",
      );
      activeTween.current = tl;
    }

    return () => {
      activeTween.current?.kill();
    };
  }, [isOpen, shouldRender]);

  if (!mounted || !shouldRender) return null;

  const v = variantStyles[variant];
  const VariantIcon = v.Icon;
  const currentSize = sizeStyles[size];
  const isBusy = isMutating > 0;

  return createPortal(
    <div
      className="fixed inset-0 z-[999999] overflow-y-auto"
      aria-labelledby="modal-title"
      role="dialog"
      aria-modal="true"
      data-cy="confirmation-modal"
    >
      <div
        ref={overlayRef}
        aria-hidden
        className="pointer-events-none fixed inset-0 bg-gradient-to-br from-dark/80 via-dark/70 to-black/85 backdrop-blur-md"
        data-cy="confirmation-modal-overlay"
      />

      <div
        className="relative flex min-h-full items-end justify-center p-4 sm:items-center sm:p-0"
        onClick={(e) => {
          if (e.target === e.currentTarget) onCancel();
        }}
        data-cy="confirmation-modal-outside"
      >
        <div
          ref={panelRef}
          className={cn(
            "relative w-full overflow-hidden rounded-2xl bg-white text-left shadow-2xl ring-1 ring-stroke/40 sm:my-8 dark:bg-dark-2 dark:ring-stroke-dark/60",
            currentSize,
          )}
          style={{ willChange: "transform, opacity" }}
        >
          {/* Top accent strip */}
          <div className={cn("h-1 w-full", v.accent)} />

          {/* Soft decorative glow blob */}
          <div
            aria-hidden
            className={cn(
              "pointer-events-none absolute -right-16 -top-16 h-40 w-40 rounded-full opacity-20 blur-3xl",
              v.iconGlow,
            )}
          />

          <div className="px-6 pb-5 pt-7 sm:px-7">
            <div className="flex flex-col items-center text-center sm:flex-row sm:items-start sm:gap-5 sm:text-left">
              {/* Icon with glow burst */}
              <div className="relative">
                <div
                  ref={iconGlowRef}
                  aria-hidden
                  className={cn(
                    "pointer-events-none absolute inset-0 rounded-full blur-md",
                    v.iconGlow,
                  )}
                />
                <div
                  ref={iconRef}
                  className={cn(
                    "relative flex h-14 w-14 shrink-0 items-center justify-center rounded-full shadow-inner",
                    v.iconWrap,
                  )}
                >
                  <VariantIcon
                    className={cn("h-6 w-6", v.iconColor)}
                  />
                </div>
              </div>

              <div className="mt-4 sm:mt-1">
                <h3
                  id="modal-title"
                  className="text-lg font-semibold leading-7 tracking-tight text-dark dark:text-white"
                >
                  {title}
                </h3>
                <p className="mt-1.5 text-sm leading-relaxed text-dark-5 dark:text-dark-6">
                  {message}
                </p>
              </div>
            </div>
          </div>

          {/* Divider */}
          <div className="h-px w-full bg-gradient-to-r from-transparent via-stroke to-transparent dark:via-stroke-dark" />

          {/* Actions */}
          <div className="flex flex-col-reverse gap-2.5 bg-gray-1/60 px-6 py-4 backdrop-blur-sm dark:bg-dark/30 sm:flex-row sm:justify-end sm:gap-3 sm:px-7">
            <button
              type="button"
              className="inline-flex w-full items-center justify-center rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-dark shadow-sm ring-1 ring-inset ring-stroke transition-all duration-200 hover:-translate-y-0.5 hover:bg-gray-1 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-dark-5/40 active:translate-y-0 dark:bg-dark-3 dark:text-white dark:ring-stroke-dark dark:hover:bg-dark-4 sm:w-auto"
              onClick={onCancel}
              data-cy="confirmation-modal-cancel"
            >
              {cancelText}
            </button>
            <button
              type="button"
              disabled={isBusy}
              onClick={onConfirm}
              data-cy="confirmation-modal-confirm"
              className={cn(
                "group inline-flex w-full items-center justify-center gap-2 overflow-hidden rounded-lg px-4 py-2.5 text-sm font-semibold transition-all duration-200 hover:-translate-y-0.5 hover:brightness-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 active:translate-y-0 disabled:cursor-not-allowed disabled:opacity-70 disabled:hover:translate-y-0 dark:focus-visible:ring-offset-dark-2 sm:w-auto",
                v.confirmBtn,
                v.focusRing,
              )}
            >
              {isBusy ? (
                <span className="relative inline-flex items-center gap-2">
                  <span className="h-4 w-4 animate-spin rounded-full border-2 border-white/40 border-t-white" />
                  Processing…
                </span>
              ) : (
                <span className="relative">{confirmText}</span>
              )}
            </button>
          </div>
        </div>
      </div>
    </div>,
    document.body,
  );
};
export default ConfirmationModal;
