import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"

import { cn } from "@/lib/utils"

const alertVariants = cva(
  [
    "ds-alert relative flex min-w-0 max-w-full overflow-hidden",
    "bg-[var(--alert-bg)] text-[var(--alert-title)] shadow-[inset_0_0_0_var(--bh-border-width-default)_var(--alert-border)]",
    "font-[var(--bh-font-family)] tracking-[var(--bh-text-base-letter-spacing)]",
  ],
  {
    variants: {
      status: {
        danger:
          "[--alert-bg:var(--bh-bg-danger-subtle)] [--alert-border:var(--bh-border-danger-subtle)] [--alert-title:var(--bh-content-danger-strong)] [--alert-description:var(--bh-content-danger-default)] [--alert-icon:var(--bh-content-danger-default)]",
        success:
          "[--alert-bg:var(--bh-bg-success-subtle)] [--alert-border:var(--bh-border-success-subtle)] [--alert-title:var(--bh-content-success-strong)] [--alert-description:var(--bh-content-success-default)] [--alert-icon:var(--bh-content-success-default)]",
        warning:
          "[--alert-bg:var(--bh-bg-warning-subtle)] [--alert-border:var(--bh-border-warning-subtle)] [--alert-title:var(--bh-content-warning-strong)] [--alert-description:var(--bh-content-warning-default)] [--alert-icon:var(--bh-content-warning-default)]",
        info:
          "[--alert-bg:var(--bh-bg-info-subtle)] [--alert-border:var(--bh-border-info-subtle)] [--alert-title:var(--bh-content-brand-strong)] [--alert-description:var(--bh-content-brand-default)] [--alert-icon:var(--bh-content-brand-default)]",
        neutral:
          "[--alert-bg:var(--bh-bg-neutral-subtle)] [--alert-border:var(--bh-border-subtle)] [--alert-title:var(--bh-content-default)] [--alert-description:var(--bh-content-default)] [--alert-icon:var(--bh-content-default)]",
      },
      isExpandable: {
        false:
          "h-[var(--bh-alert-compact-height)] w-[var(--bh-alert-compact-width)] items-center gap-[var(--bh-space-xl-12)] rounded-[var(--bh-alert-compact-radius)] p-[var(--bh-alert-compact-padding)]",
        true:
          "h-[var(--bh-alert-expanded-height)] w-[var(--bh-alert-expanded-width)] items-start gap-[var(--bh-space-xl-12)] rounded-[var(--bh-alert-expanded-radius)] px-[var(--bh-alert-expanded-padding-x)] py-[var(--bh-alert-expanded-padding-y)]",
      },
    },
    defaultVariants: {
      status: "danger",
      isExpandable: false,
    },
  }
)

type AlertStatus = "danger" | "success" | "warning" | "info" | "neutral"
type AlertDirection = "ltr" | "rtl"

type AlertAction = {
  label: React.ReactNode
  onClick?: () => void
}

type AlertProps = Omit<
  React.ComponentPropsWithoutRef<"section">,
  "dir" | "title"
> &
  Omit<VariantProps<typeof alertVariants>, "status"> & {
    actions?: AlertAction[]
    closeLabel?: string
    description?: React.ReactNode
    dir?: AlertDirection
    onClose?: () => void
    showActions?: boolean
    showCloseButton?: boolean
    status?: AlertStatus
    title?: React.ReactNode
  }

const defaultActions: Record<AlertDirection, AlertAction[]> = {
  ltr: [{ label: "Action" }, { label: "Action" }],
  rtl: [
    { label: "\u0632\u0631 \u0627\u0644\u0631\u0627\u0628\u0637" },
    { label: "\u0632\u0631 \u0627\u0644\u0631\u0627\u0628\u0637" },
  ],
}

const defaultCopy = {
  ltr: {
    title: "Alert title",
    description:
      "Lorem ipsum dolor sit amet consectetur. Libero feugiat velit risus egestas blandit eget curabitur.",
  },
  rtl: {
    title:
      "\u0623\u062f\u062e\u0644 \u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u062a\u0646\u0628\u064a\u0647 \u0627\u0644\u062e\u0627\u0635 \u0628\u0643 \u0647\u0646\u0627!",
    description:
      "\u0623\u062f\u062e\u0644 \u0648\u0635\u0641 \u0627\u0644\u062a\u0646\u0628\u064a\u0647 \u0647\u0646\u0627\u060c \u0633\u064a\u0628\u062f\u0648 \u0623\u0641\u0636\u0644 \u0643\u0633\u0637\u0631\u064a\u0646 \u0645\u0646 \u0627\u0644\u0646\u0635.",
  },
}

const Alert = React.forwardRef<HTMLElement, AlertProps>(function Alert(
  {
    actions,
    children,
    className,
    closeLabel,
    description,
    dir = "ltr",
    isExpandable = false,
    onClose,
    showActions = true,
    showCloseButton = true,
    status = "danger",
    title,
    ...props
  },
  ref
) {
  const expanded = Boolean(isExpandable)
  const resolvedStatus = status ?? "danger"
  const copy = defaultCopy[dir]
  const renderedTitle = title ?? children ?? copy.title
  const renderedDescription = description ?? copy.description
  const actionItems = actions ?? defaultActions[dir]
  const visibleActions = showActions ? actionItems.slice(0, expanded ? 2 : 1) : []

  return (
    <section
      data-slot="alert"
      data-status={resolvedStatus}
      data-expandable={expanded ? "true" : "false"}
      dir={dir}
      ref={ref}
      className={cn(
        alertVariants({ status: resolvedStatus, isExpandable: expanded }),
        expanded && dir === "rtl" && "h-[var(--bh-alert-expanded-rtl-height)]",
        expanded &&
          dir === "ltr" &&
          resolvedStatus === "neutral" &&
          "[--alert-border:var(--bh-border-default)]",
        className
      )}
      {...props}
    >
      <div
        data-slot="alert-main"
        className={cn(
          "flex flex-[1_0_0] min-w-0",
          expanded
            ? "items-start gap-[var(--bh-space-xl-12)]"
            : "items-center gap-[var(--bh-space-md-8)]"
        )}
      >
        <span
          data-slot="alert-icon"
          className="inline-flex size-[var(--bh-alert-icon-size)] shrink-0 items-center justify-center text-[var(--alert-icon)]"
        >
          <AlertStatusIcon status={resolvedStatus} />
        </span>
        <div
          data-slot="alert-copy"
          className={cn(
            "flex flex-[1_0_0] min-w-0 text-start",
            expanded && "flex-col justify-center gap-[var(--bh-space-xl-12)]",
            dir === "rtl" && "text-right"
          )}
        >
          <div
            data-slot="alert-info"
            className={cn(
              "flex w-full min-w-0 flex-[1_0_0] flex-col justify-center gap-[var(--bh-space-xs-4)]",
              dir === "rtl" && "items-end text-right"
            )}
          >
            <p
              data-slot="alert-title"
              dir="auto"
              className={cn(
                "m-0 min-w-0 w-full break-words text-[length:var(--bh-text-body-md-medium-font-size)] font-[var(--bh-font-weight-medium)] leading-[var(--bh-text-body-md-medium-line-height)] tracking-[var(--bh-text-body-md-medium-letter-spacing)] text-[var(--alert-title)]",
                dir === "rtl" && "[direction:rtl] text-right leading-[var(--bh-text-body-sm-regular-line-height)]"
              )}
            >
              {renderedTitle}
            </p>
            {expanded && (
              <p
                data-slot="alert-description"
                dir="auto"
                className="m-0 w-full break-words text-[length:var(--bh-text-body-sm-regular-font-size)] font-[var(--bh-font-weight-regular)] leading-[var(--bh-text-body-sm-regular-line-height)] tracking-[var(--bh-text-body-sm-regular-letter-spacing)] text-[var(--alert-description)] opacity-[var(--bh-opacity-80)]"
              >
                {renderedDescription}
              </p>
            )}
          </div>

          {expanded && visibleActions.length > 0 && (
            <AlertActions actions={visibleActions} />
          )}
        </div>
      </div>

      {!expanded && visibleActions.length > 0 && (
        <AlertActions actions={visibleActions} />
      )}

      {showCloseButton && (
        <button
          data-slot="alert-close"
          aria-label={closeLabel}
          className="inline-flex size-[var(--bh-alert-icon-size)] shrink-0 cursor-pointer items-center justify-center rounded-[var(--bh-radius-full)] border-0 bg-transparent p-0 text-[var(--bh-content-subtle)] outline-none focus-visible:shadow-[var(--shadow-button-focus)]"
          onClick={onClose}
          type="button"
        >
          <CloseIcon />
        </button>
      )}
    </section>
  )
})

function AlertActions({ actions }: { actions: AlertAction[] }) {
  return (
    <div
      data-slot="alert-actions"
      className="flex shrink-0 items-center gap-[var(--bh-space-3xl-16)]"
    >
      {actions.map((action, index) => (
        <button
          data-slot="alert-action"
          className="inline-flex shrink-0 cursor-pointer items-center justify-center gap-[var(--bh-space-xxs-2)] border-0 bg-transparent p-0 text-start text-[length:var(--bh-text-body-md-underline-font-size)] font-[var(--bh-text-body-md-underline-font-weight)] leading-[var(--bh-text-body-md-underline-line-height)] tracking-[var(--bh-text-body-md-underline-letter-spacing)] text-[var(--bh-content-default)] underline outline-none [text-underline-position:from-font] focus-visible:shadow-[var(--shadow-button-focus)]"
          key={index}
          onClick={action.onClick}
          type="button"
        >
          {action.label}
        </button>
      ))}
    </div>
  )
}

function AlertStatusIcon({ status }: { status: AlertStatus }) {
  if (status === "success") {
    return (
      <svg aria-hidden="true" className="size-[var(--bh-alert-icon-size)] fill-current" viewBox="0 0 16.6667 16.6667">
        <path d="M8.33333 16.6667C12.9357 16.6667 16.6667 12.9357 16.6667 8.33333C16.6667 3.73096 12.9357 0 8.33333 0C3.73096 0 0 3.73096 0 8.33333C0 12.9357 3.73096 16.6667 8.33333 16.6667ZM12.8809 6.21426L7.5 11.5952L3.99407 8.08925L5.17259 6.91075L7.5 9.23817L11.7024 5.03574L12.8809 6.21426Z" />
      </svg>
    )
  }

  if (status === "warning") {
    return (
      <svg aria-hidden="true" className="size-[var(--bh-alert-icon-size)] fill-current" viewBox="0 0 17.544 15.4168">
        <path d="M9.49356 0.416809L17.4321 14.1668C17.6623 14.5654 17.5257 15.0751 17.1271 15.3052C17.0005 15.3783 16.8567 15.4168 16.7105 15.4168H0.833333C0.3731 15.4168 0 15.0438 0 14.5835C0 14.4372 0.0385084 14.2935 0.11165 14.1668L8.05022 0.416809C8.28031 0.0182258 8.78997 -0.118333 9.18856 0.111784C9.31522 0.184926 9.42047 0.290126 9.49356 0.416809ZM7.93856 11.2502V12.9168H9.60522V11.2502H7.93856ZM7.93856 5.41681V9.5835H9.60522V5.41681H7.93856Z" />
      </svg>
    )
  }

  if (status === "info") {
    return (
      <svg aria-hidden="true" className="size-[var(--bh-alert-icon-size)] fill-current" viewBox="0 0 16.6667 16.6667">
        <path d="M8.33333 16.6667C3.73096 16.6667 0 12.9357 0 8.33333C0 3.73096 3.73096 0 8.33333 0C12.9357 0 16.6667 3.73096 16.6667 8.33333C16.6667 12.9357 12.9357 16.6667 8.33333 16.6667ZM8.33333 6.25C9.02367 6.25 9.58333 5.69036 9.58333 5C9.58333 4.30964 9.02367 3.75 8.33333 3.75C7.643 3.75 7.08333 4.30964 7.08333 5C7.08333 5.69036 7.643 6.25 8.33333 6.25ZM10 10.8333H9.16667V7.08333H6.66667V8.75H7.5V10.8333H6.66667V12.5H10V10.8333Z" />
      </svg>
    )
  }

  if (status === "neutral") {
    return (
      <svg aria-hidden="true" className="size-[var(--bh-alert-icon-size)] fill-current" viewBox="0 0 15.851 15.0752">
        <path d="M7.92545 12.0833L3.02726 15.0752L4.35901 9.49217L0 5.75819L5.72128 5.29952L7.92545 0L10.1297 5.29952L15.851 5.75819L11.492 9.49217L12.8237 15.0752L7.92545 12.0833Z" />
      </svg>
    )
  }

  return (
    <svg aria-hidden="true" className="size-[var(--bh-alert-icon-size)] fill-current" viewBox="0 0 16.6667 16.6667">
      <path d="M8.33333 16.6667C3.73096 16.6667 0 12.9357 0 8.33333C0 3.73096 3.73096 0 8.33333 0C12.9357 0 16.6667 3.73096 16.6667 8.33333C16.6667 12.9357 12.9357 16.6667 8.33333 16.6667ZM7.5 10.8333V12.5H9.16667V10.8333H7.5ZM7.5 4.16667V9.16667H9.16667V4.16667H7.5Z" />
    </svg>
  )
}

function CloseIcon() {
  return (
    <svg aria-hidden="true" className="size-[var(--bh-alert-icon-size)] fill-current" viewBox="0 0 16 16">
      <path d="M8.00004 7.05723L11.2999 3.75739L12.2427 4.7002L8.94284 8.00003L12.2427 11.2998L11.2999 12.2427L8.00004 8.94283L4.70021 12.2427L3.75739 11.2998L7.05723 8.00003L3.75739 4.7002L4.70021 3.75739L8.00004 7.05723Z" />
    </svg>
  )
}

export {
  Alert,
  alertVariants,
  type AlertAction,
  type AlertDirection,
  type AlertProps,
  type AlertStatus,
}
