/**
 * Dialog — WealthX DS overrides (shadcn / \@base-ui dialog)
 *
 * Changes from shadcn default:
 *   - DialogOverlay:  `bg-black/50` → `bg-foreground/50` — DS foreground token (matches Figma)
 *   - DialogContent:  `rounded-lg` removed — sharp corners per Figma
 *   - DialogContent:  `shadow-lg` removed — flat panels per Figma
 *   - DialogContent:  `max-h-[calc(100dvh-2rem)]` + `overflow-y-auto` — tall dialogs scroll
 *                     inside themselves instead of pushing the footer off-screen
 *   - DialogHeader:   `text-center` removed — always left-aligned per DS
 *   - DialogFooter:   `border-t border-border pt-4` — separator above footer
 *   - Close button:   no radius, `hover:bg-foreground/5`, `focus:ring-border`
 */
import { type ReactElement } from "react";
import * as React from "react";
import { XIcon } from "lucide-react";
import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
import { cn } from "@/lib/utils";
import { asChildProps } from "@/lib/as-child";
import { useThemeVars } from "@/lib/theme-provider";
import { buttonVariants } from "@/components/ui/button";

export type DialogProps = React.ComponentProps<typeof DialogPrimitive.Root>;

function Dialog({ ...props }: DialogProps): ReactElement {
  return <DialogPrimitive.Root data-slot="dialog" {...props} />;
}

export type DialogTriggerProps = React.ComponentProps<
  typeof DialogPrimitive.Trigger
> & {
  /** shadcn-compatible alias for Base UI's `render`: replaces the trigger with its single child. */
  asChild?: boolean;
};

function DialogTrigger({
  asChild,
  children,
  ...props
}: DialogTriggerProps): ReactElement {
  return (
    <DialogPrimitive.Trigger
      data-slot="dialog-trigger"
      {...props}
      {...asChildProps(asChild, children)}
    />
  );
}

export type DialogPortalProps = React.ComponentProps<
  typeof DialogPrimitive.Portal
>;

function DialogPortal({ ...props }: DialogPortalProps): ReactElement {
  return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
}

export type DialogCloseProps = React.ComponentProps<
  typeof DialogPrimitive.Close
>;

function DialogClose({ ...props }: DialogCloseProps): ReactElement {
  return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
}

export type DialogOverlayProps = React.ComponentProps<
  typeof DialogPrimitive.Backdrop
>;

function DialogOverlay({
  className,
  ...props
}: DialogOverlayProps): ReactElement {
  return (
    <DialogPrimitive.Backdrop
      className={cn(
        // WealthX: foreground/50 scrim (matches Figma — foreground token at 50% opacity)
        "fixed inset-0 z-50 bg-foreground/50 pointer-events-auto data-ending-style:animate-out data-ending-style:fade-out-0 data-ending-style:fill-mode-forwards data-open:animate-in data-open:fade-in-0",
        className,
      )}
      data-slot="dialog-overlay"
      {...props}
    />
  );
}

/**
 * Maps the `size` prop to an exact CSS max-width value.
 * Applied via inline style — bypasses Tailwind v4 class scanning entirely.
 */
const DIALOG_MAX_WIDTHS: Record<string, string> = {
  sm: "24rem",
  md: "28rem",
  lg: "32rem",
  xl: "36rem",
  "2xl": "42rem",
  "3xl": "48rem",
  "4xl": "56rem",
  full: "100%",
};

/**
 * Default minimum width for size="auto" dialogs.
 * Prevents the dialog from collapsing too narrow when hugging content.
 * Override per-instance via the `minWidth` prop.
 */
const DIALOG_AUTO_MIN_WIDTH = "20rem"; // 320px

export type DialogContentProps = React.ComponentProps<
  typeof DialogPrimitive.Popup
> & {
  showCloseButton?: boolean;
  /**
   * Optional container element to render the Dialog portal into.
   * Pass a ref'd element to scope the overlay inside a parent (e.g. a Sheet drawer)
   * instead of appending to document.body.
   */
  container?: HTMLElement | null;
  /** Vertical alignment of the dialog. "top" (default) anchors to top-4; "center" vertically centers. */
  align?: "center" | "top";
  /**
   * Width behaviour of the dialog panel.
   * - Fixed sizes ("sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "full"):
   *   dialog fills width up to that maximum (applied via inline style — reliable in Tailwind v4).
   * - "auto": dialog shrinks to fit its content (hug-content). Has a built-in minimum
   *   width of `DIALOG_AUTO_MIN_WIDTH` (20rem / 320px) to avoid collapsing too narrow.
   * Defaults to "lg".
   */
  size?: "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "full" | "auto";
  /**
   * Override the minimum width for `size="auto"` dialogs.
   * Accepts any valid CSS length value (e.g. "24rem", "400px").
   * Ignored when using a fixed size.
   */
  minWidth?: string;
};

function DialogContent({
  className,
  children,
  showCloseButton = true,
  style,
  container,
  align = "top",
  size = "lg",
  minWidth,
  ...props
}: DialogContentProps): ReactElement {
  const themeVars = useThemeVars();
  const isAuto = size === "auto";

  const sizeStyle = isAuto
    ? { minWidth: minWidth ?? DIALOG_AUTO_MIN_WIDTH }
    : { maxWidth: `min(${DIALOG_MAX_WIDTHS[size]}, calc(100% - 2rem))` };

  return (
    <DialogPortal container={container ?? undefined}>
      <DialogOverlay style={themeVars as React.CSSProperties} />
      <DialogPrimitive.Popup
        className={cn(
          // WealthX: removed rounded-lg (sharp corners), shadow-lg (flat panels)
          // max-w-[calc(100%-2rem)] is the viewport-edge guard for size="auto".
          // Fixed sizes set maxWidth via inline style (min(size, calc(100%-2rem)))
          // — inline style wins over the className, so the min() must carry the
          // guard itself, otherwise a fixed size overflows a narrow viewport.
          // pointer-events-auto: Vaul Drawer (Radix DismissableLayer) sets body{pointer-events:none}
          // when open — dialog portals to body and must override that on its own element.
          // max-h-[calc(100dvh-2rem)] + overflow-y-auto: a dialog taller than the viewport
          // scrolls inside itself instead of pushing its footer off-screen (1rem top + 1rem
          // bottom breathing room, matching the top-4 / centered offsets).
          "fixed left-[50%] z-50 grid max-h-[calc(100dvh-2rem)] max-w-[calc(100%-2rem)] translate-x-[-50%] gap-4 overflow-y-auto border bg-background p-6 duration-200 outline-none pointer-events-auto data-ending-style:animate-out data-ending-style:fade-out-0 data-ending-style:zoom-out-95 data-ending-style:fill-mode-forwards data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95",
          // "auto" → hug content (with min-width floor); fixed sizes → fill to max-width
          isAuto ? "w-auto" : "w-full",
          align === "center"
            ? "top-[50%] translate-y-[-50%]"
            : "top-4 translate-y-0",
          className,
        )}
        data-slot="dialog-content"
        style={{ ...themeVars, ...sizeStyle, ...style } as React.CSSProperties}
        {...props}
      >
        {children}
        {showCloseButton ? (
          <DialogPrimitive.Close
            className="absolute top-4 right-4 inline-flex size-7 items-center justify-center transition-colors hover:bg-foreground/5 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-border focus-visible:ring-offset-0 disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
            // WealthX: removed rounded-xs (sharp), replaced opacity fade with hover:bg-foreground/5,
            // focus ring uses border color (subtle, matches Figma DialogClose focus state).
            // size-7 = 28px hit area (icon is size-4=16px, centered via inline-flex).
            data-slot="dialog-close"
          >
            <XIcon />
            <span className="sr-only">Close</span>
          </DialogPrimitive.Close>
        ) : null}
      </DialogPrimitive.Popup>
    </DialogPortal>
  );
}

export type DialogHeaderProps = React.ComponentProps<"div">;

function DialogHeader({
  className,
  ...props
}: DialogHeaderProps): ReactElement {
  return (
    <div
      // WealthX: always left-aligned (no sm:text-left — no centered variant)
      className={cn("flex flex-col gap-1.5", className)}
      data-slot="dialog-header"
      {...props}
    />
  );
}

export type DialogFooterProps = React.ComponentProps<"div"> & {
  showCloseButton?: boolean;
};

function DialogFooter({
  className,
  showCloseButton = false,
  children,
  ...props
}: DialogFooterProps): ReactElement {
  return (
    <div
      className={cn(
        // WealthX: always row layout, right-aligned, separator above footer
        "flex flex-row justify-end gap-2 border-t border-border pt-4",
        className,
      )}
      data-slot="dialog-footer"
      {...props}
    >
      {children}
      {showCloseButton ? (
        <DialogPrimitive.Close
          className={cn(buttonVariants({ variant: "outline" }))}
          // type="button" prevents accidental form submission inside Dialog forms
          type="button"
        >
          Close
        </DialogPrimitive.Close>
      ) : null}
    </div>
  );
}

export type DialogTitleProps = React.ComponentProps<
  typeof DialogPrimitive.Title
>;

function DialogTitle({ className, ...props }: DialogTitleProps): ReactElement {
  return (
    <DialogPrimitive.Title
      className={cn("text-h5", className)}
      data-slot="dialog-title"
      {...props}
    />
  );
}

export type DialogDescriptionProps = React.ComponentProps<
  typeof DialogPrimitive.Description
>;

function DialogDescription({
  className,
  ...props
}: DialogDescriptionProps): ReactElement {
  return (
    <DialogPrimitive.Description
      className={cn("text-body-small text-muted-foreground", className)}
      data-slot="dialog-description"
      {...props}
    />
  );
}

export {
  Dialog,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogOverlay,
  DialogPortal,
  DialogTitle,
  DialogTrigger,
};
