"use client";

import * as DialogPrimitive from "@radix-ui/react-dialog";
import { XIcon } from "lucide-react";
import * as React from "react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";

const MEDIA_QUERY = "(min-width: 640px)";

function useMediaQuery(query: string) {
  const [matches, setMatches] = React.useState(() => {
    if (typeof window === "undefined") return true;
    return window.matchMedia(query).matches;
  });

  React.useEffect(() => {
    const mql = window.matchMedia(query);
    const handler = (e: MediaQueryListEvent) => setMatches(e.matches);
    mql.addEventListener("change", handler);
    return () => mql.removeEventListener("change", handler);
  }, [query]);

  return matches;
}

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

const ResponsiveDialogContext =
  React.createContext<ResponsiveDialogContextValue | null>(null);

function useResponsiveDialog() {
  const ctx = React.useContext(ResponsiveDialogContext);
  if (!ctx)
    throw new Error(
      "ResponsiveDialog components must be used within ResponsiveDialog",
    );
  return ctx;
}

function ResponsiveDialog({
  open,
  onOpenChange,
  children,
}: {
  open?: boolean;
  onOpenChange?: (open: boolean) => void;
  children: React.ReactNode;
}) {
  const [internalOpen, setInternalOpen] = React.useState(false);
  const isDesktop = useMediaQuery(MEDIA_QUERY);

  const controlled = open !== undefined;
  const currentOpen = controlled ? open : internalOpen;
  // biome-ignore lint/style/noNonNullAssertion: controlled ensures it's defined
  const setCurrentOpen = controlled ? onOpenChange! : setInternalOpen;

  return (
    <ResponsiveDialogContext
      value={{ open: currentOpen, onOpenChange: setCurrentOpen, isDesktop }}
    >
      {isDesktop ? (
        <DialogPrimitive.Root open={currentOpen} onOpenChange={setCurrentOpen}>
          {children}
        </DialogPrimitive.Root>
      ) : (
        <DialogPrimitive.Root open={currentOpen} onOpenChange={setCurrentOpen}>
          {children}
        </DialogPrimitive.Root>
      )}
    </ResponsiveDialogContext>
  );
}

function ResponsiveDialogTrigger({
  children,
  asChild,
  ...props
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
  return (
    <DialogPrimitive.Trigger data-slot="responsive-dialog-trigger" {...props}>
      {children}
    </DialogPrimitive.Trigger>
  );
}

function ResponsiveDialogContent({
  className,
  children,
  ...props
}: React.ComponentProps<typeof DialogPrimitive.Content>) {
  const { isDesktop, open, onOpenChange } = useResponsiveDialog();

  if (isDesktop) {
    return (
      <DialogPrimitive.Portal>
        <DialogPrimitive.Overlay
          data-slot="responsive-dialog-overlay"
          className="fixed inset-0 z-50 bg-black/10 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0"
        />
        <DialogPrimitive.Content
          data-slot="responsive-dialog-content"
          className={cn(
            "fixed left-1/2 top-1/2 z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2",
            "flex flex-col gap-4 rounded-xl border bg-popover p-6 text-popover-foreground shadow-lg",
            "data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-open:slide-in-from-left-1/2 data-open:slide-in-from-top-[48%]",
            "data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-closed:slide-out-to-left-1/2 data-closed:slide-out-to-top-[48%]",
            "duration-200",
            className,
          )}
          {...props}
        >
          {children}
          <DialogPrimitive.Close asChild>
            <Button
              variant="ghost"
              className="absolute top-3 right-3"
              size="icon-sm"
            >
              <XIcon />
              <span className="sr-only">Close</span>
            </Button>
          </DialogPrimitive.Close>
        </DialogPrimitive.Content>
      </DialogPrimitive.Portal>
    );
  }

  if (!open) return null;

  return (
    <div
      className="fixed inset-0 z-50 flex items-end sm:hidden"
      data-slot="responsive-dialog-mobile"
    >
      <button
        type="button"
        className="fixed inset-0 z-40 bg-black/10 supports-backdrop-filter:backdrop-blur-xs cursor-default"
        onClick={() => onOpenChange(false)}
        aria-label="Cerrar"
      />
      <div
        className={cn(
          "relative z-50 flex w-full flex-col gap-4 rounded-t-xl border bg-popover p-6 text-popover-foreground shadow-lg",
          "animate-in slide-in-from-bottom-10 fade-in-0 duration-200",
          className,
        )}
      >
        <div className="mx-auto -mt-2 mb-1 h-1.5 w-10 rounded-full bg-muted" />
        <DialogPrimitive.Close asChild>
          <Button
            variant="ghost"
            size="icon-sm"
            className="absolute top-3 right-3"
          >
            <XIcon />
            <span className="sr-only">Close</span>
          </Button>
        </DialogPrimitive.Close>
        {children}
      </div>
    </div>
  );
}

function ResponsiveDialogHeader({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="responsive-dialog-header"
      className={cn("flex flex-col gap-0.5", className)}
      {...props}
    />
  );
}

function ResponsiveDialogFooter({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="responsive-dialog-footer"
      className={cn(
        "mt-2 flex flex-col-reverse sm:flex-row sm:justify-end gap-2",
        className,
      )}
      {...props}
    />
  );
}

function ResponsiveDialogTitle({
  className,
  ...props
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
  return (
    <DialogPrimitive.Title
      data-slot="responsive-dialog-title"
      className={cn("text-base font-medium text-foreground", className)}
      {...props}
    />
  );
}

function ResponsiveDialogDescription({
  className,
  ...props
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
  return (
    <DialogPrimitive.Description
      data-slot="responsive-dialog-description"
      className={cn("text-sm text-muted-foreground", className)}
      {...props}
    />
  );
}

function ResponsiveDialogClose({
  ...props
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
  return (
    <DialogPrimitive.Close data-slot="responsive-dialog-close" {...props} />
  );
}

export {
  ResponsiveDialog,
  ResponsiveDialogClose,
  ResponsiveDialogContent,
  ResponsiveDialogDescription,
  ResponsiveDialogFooter,
  ResponsiveDialogHeader,
  ResponsiveDialogTitle,
  ResponsiveDialogTrigger,
};
