'use client';

import * as React from 'react';
import { createPortal } from 'react-dom';
import { motion, AnimatePresence } from 'framer-motion';
import { X } from 'lucide-react';
import { cn } from '@/lib/utils';
import { useMediaQuery } from '@/hooks/useMediaQuery';
import { useIsMounted } from '@/hooks/useIsMounted';

export interface ResponsiveModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  children: React.ReactNode;
}

interface ResponsiveModalContextType {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  isDesktop: boolean;
}

const ResponsiveModalContext = React.createContext<ResponsiveModalContextType | null>(null);

export function useResponsiveModal() {
  const context = React.useContext(ResponsiveModalContext);
  if (!context) {
    throw new Error('useResponsiveModal must be used within a ResponsiveModal');
  }
  return context;
}

export function ResponsiveModal({
  open,
  onOpenChange,
  children,
}: ResponsiveModalProps) {
  const isDesktop = useMediaQuery('(min-width: 768px)');
  const mounted = useIsMounted();

  if (!mounted) return null;

  return (
    <ResponsiveModalContext.Provider value={{ open, onOpenChange, isDesktop }}>
      {children}
    </ResponsiveModalContext.Provider>
  );
}

export function ResponsiveModalContent({
  className,
  children,
  showClose = true,
}: {
  className?: string;
  children: React.ReactNode;
  showClose?: boolean;
}) {
  const { open, onOpenChange, isDesktop } = useResponsiveModal();
  const mounted = useIsMounted();

  React.useEffect(() => {
    if (open) {
      document.body.style.overflow = 'hidden';
      const handleKeyDown = (e: KeyboardEvent) => {
        if (e.key === 'Escape') onOpenChange(false);
      };
      document.addEventListener('keydown', handleKeyDown);
      return () => {
        document.body.style.overflow = '';
        document.removeEventListener('keydown', handleKeyDown);
      };
    } else {
      document.body.style.overflow = '';
    }
  }, [open, onOpenChange]);

  if (!mounted) return null;

  return createPortal(
    <AnimatePresence>
      {open && (
        <div
          className={cn(
            'fixed inset-0 z-50 flex',
            isDesktop ? 'items-center justify-center p-4' : 'items-end justify-center'
          )}
          role="dialog"
          aria-modal="true"
        >
          {/* Backdrop */}
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.2 }}
            className="fixed inset-0 bg-zinc-950/60 backdrop-blur-xs"
            onClick={() => onOpenChange(false)}
            aria-hidden="true"
          />

          {/* Desktop Centered Modal vs Mobile Bottom Drawer */}
          {isDesktop ? (
            <motion.div
              initial={{ opacity: 0, scale: 0.95, y: 10 }}
              animate={{ opacity: 1, scale: 1, y: 0 }}
              exit={{ opacity: 0, scale: 0.95, y: 10 }}
              transition={{ duration: 0.25, ease: [0.16, 1, 0.3, 1] }}
              className={cn(
                'relative z-50 w-full max-w-md bg-white dark:bg-zinc-900 rounded-3xl p-6 sm:p-8 shadow-2xl border border-zinc-200 dark:border-zinc-800 text-start overflow-hidden',
                className
              )}
              onClick={(e) => e.stopPropagation()}
            >
              {showClose && (
                <button
                  type="button"
                  onClick={() => onOpenChange(false)}
                  className="absolute top-5 end-5 w-8 h-8 rounded-full flex items-center justify-center text-zinc-400 hover:text-zinc-900 dark:hover:text-white hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors cursor-pointer"
                  aria-label="Close"
                >
                  <X className="w-4 h-4" />
                </button>
              )}
              {children}
            </motion.div>
          ) : (
            <motion.div
              initial={{ y: '100%' }}
              animate={{ y: 0 }}
              exit={{ y: '100%' }}
              transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }}
              className={cn(
                'relative z-50 w-full max-w-lg bg-white dark:bg-zinc-900 rounded-t-3xl p-6 shadow-2xl border-t border-zinc-200 dark:border-zinc-800 text-start overflow-hidden pb-8 pb-safe max-h-[90dvh] overflow-y-auto overscroll-contain',
                className
              )}
              onClick={(e) => e.stopPropagation()}
            >
              {/* iOS Native Style Drag Pill */}
              <div className="w-12 h-1.5 bg-zinc-300 dark:bg-zinc-700 rounded-full mx-auto mb-4 shrink-0" />

              {showClose && (
                <button
                  type="button"
                  onClick={() => onOpenChange(false)}
                  className="absolute top-5 end-5 w-8 h-8 rounded-full flex items-center justify-center text-zinc-400 hover:text-zinc-900 dark:hover:text-white hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors cursor-pointer"
                  aria-label="Close"
                >
                  <X className="w-4 h-4" />
                </button>
              )}

              {children}
            </motion.div>
          )}
        </div>
      )}
    </AnimatePresence>,
    document.body
  );
}

export function ResponsiveModalHeader({
  className,
  children,
  ...props
}: React.HTMLAttributes<HTMLDivElement>) {
  const { isDesktop } = useResponsiveModal();
  return (
    <div
      className={cn(
        'flex flex-col space-y-1.5 mb-6',
        isDesktop ? 'text-start' : 'text-center',
        className
      )}
      {...props}
    >
      {children}
    </div>
  );
}

export function ResponsiveModalTitle({
  className,
  children,
  ...props
}: React.HTMLAttributes<HTMLHeadingElement>) {
  return (
    <h2
      className={cn(
        'text-2xl font-extrabold text-zinc-900 dark:text-white tracking-tight',
        className
      )}
      {...props}
    >
      {children}
    </h2>
  );
}

export function ResponsiveModalDescription({
  className,
  children,
  ...props
}: React.HTMLAttributes<HTMLParagraphElement>) {
  return (
    <p
      className={cn('text-sm text-zinc-500 dark:text-zinc-400 mt-1', className)}
      {...props}
    >
      {children}
    </p>
  );
}
