"use client"
import * as ModalPrimitive from "@radix-ui/react-dialog"
import React, { ComponentProps, ElementRef, forwardRef } from "react"
import { Close } from "../../icons/material-symbols/outlined/Close"
import { borderVariants } from "../../styles"
import { overlayVariants } from "../../styles/utils/overlay"
import { classNames, tv, VariantProps } from "../../utils"
import { Button } from "../Button"
import { Container } from "../Container"
import { FlexCenterProps } from "../FlexCenter"
import { VisuallyHidden } from "../VisuallyHidden"

export type TakeoverModalProps = Pick<
  ComponentProps<typeof ModalPrimitive.Root>,
  "open" | "defaultOpen" | "onOpenChange" | "modal"
> &
  Omit<ComponentProps<typeof ModalPrimitive.Content>, "content"> & {
    content: React.ReactNode
    withCloseIcon?: boolean
    transparent?: boolean
    overrides?: {
      Overlay: ComponentProps<typeof ModalPrimitive.Overlay>
    }
  } & VariantProps<typeof takeoverModalContentVariants>

const fadeInAnimation = classNames(
  "data-[state=open]:duration-300 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
)

const fadeOutAnimation = classNames(
  "data-[state=closed]:duration-300 data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
)

export const takeoverModalContentVariants = tv({
  base: classNames(
    "fixed inset-0 z-takeover-modal overflow-y-auto bg-bg-app ease-out-quint focus-visible:outline-hidden lg:m-4 lg:rounded-xl 2xl:m-6",
    borderVariants({ border: "border-1" }),
  ),
  variants: {
    animation: {
      in: fadeInAnimation,
      out: fadeOutAnimation,
      "in-and-out": classNames(fadeInAnimation, fadeOutAnimation),
    },
  },
})

const TakeoverModalBase = forwardRef<
  ElementRef<typeof ModalPrimitive.Content>,
  TakeoverModalProps
>(function TakeoverModal(
  {
    open,
    defaultOpen,
    onOpenChange,
    content,
    children,
    className,
    modal,
    overrides,
    withCloseIcon = true,
    animation = "in-and-out",
    ...props
  },
  ref,
) {
  return (
    <>
      <ModalPrimitive.Root
        defaultOpen={defaultOpen}
        modal={modal}
        open={open}
        onOpenChange={onOpenChange}
      >
        <ModalPrimitive.Trigger asChild>{children}</ModalPrimitive.Trigger>
        <ModalPrimitive.Portal>
          <ModalPrimitive.Overlay
            data-testid="Overlay"
            {...overrides?.Overlay}
            className={classNames(
              overlayVariants(),
              "z-takeover-modal-overlay",
              overrides?.Overlay.className,
            )}
          />
          <ModalPrimitive.Content
            aria-describedby={undefined}
            className={classNames(
              takeoverModalContentVariants({ animation }),
              className,
            )}
            ref={ref}
            {...props}
          >
            <VisuallyHidden>
              <ModalPrimitive.Title />
            </VisuallyHidden>
            {content}

            {withCloseIcon ? (
              <ModalPrimitive.Close
                asChild
                className="absolute right-6 top-6 z-modal"
              >
                <Button icon={Close} rounded variant="secondary" />
              </ModalPrimitive.Close>
            ) : null}
          </ModalPrimitive.Content>
        </ModalPrimitive.Portal>
      </ModalPrimitive.Root>
    </>
  )
})

export const TakeoverModalHeader = ({
  className,
  ...props
}: FlexCenterProps) => {
  return (
    <Container
      className={classNames(
        "sticky top-0 z-10 flex min-h-[96px] items-center bg-bg-app py-6",
        className,
      )}
      {...props}
    />
  )
}

export const TakeoverModalBody = Container

/**
 * A full-screen modal that blurs the background content.
 * Turns into a bottom sheet on mobile.
 */
export const TakeoverModal = Object.assign(TakeoverModalBase, {
  Header: TakeoverModalHeader,
  Body: TakeoverModalBody,
})
