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

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

type SelectItemType =
  | "default"
  | "icon"
  | "avatar"
  | "flag"
  | "company"
  | "payment"
  | "dot"
type SelectStatusTone =
  | "success"
  | "warning"
  | "danger"
  | "info"
  | "brand"
  | "neutral"
type SelectIconName =
  | "check-fill"
  | "check-line"
  | "chevron-down"
  | "error"
  | "info"
  | "plus"
  | "user"

const selectStatusDot = cva(
  "block size-[var(--bh-select-status-dot-size)] rounded-[var(--bh-radius-full)]",
  {
    variants: {
      tone: {
        success: "bg-[var(--bh-bg-success-default)]",
        warning: "bg-[var(--bh-bg-warning-default)]",
        danger: "bg-[var(--bh-bg-danger-default)]",
        info: "bg-[var(--bh-bg-info-default)]",
        brand: "bg-[var(--bh-bg-brand-default)]",
        neutral: "bg-[var(--bh-bg-neutral-default)]",
      },
    },
    defaultVariants: {
      tone: "success",
    },
  }
)

type SelectItemAvatarProps = React.ComponentProps<"span"> & {
  alt?: string
  fallback?: React.ReactNode
  src?: string
}

function SelectItemAvatar({
  alt = "",
  className,
  fallback,
  src,
  ...props
}: SelectItemAvatarProps) {
  return (
    <span
      data-slot="select-item-avatar"
      className={cn(
        "relative flex size-[var(--bh-select-icon-slot-size)] shrink-0 items-center justify-center overflow-hidden rounded-[var(--bh-radius-full)] border border-[var(--bh-border-subtle)] bg-[var(--bh-bg-accent-blue-soft)] text-[length:var(--bh-select-avatar-font-size)] font-[var(--bh-font-weight-semibold)] leading-none text-[var(--bh-content-accent-blue-strong)]",
        className
      )}
      {...props}
    >
      {src ? (
        <img alt={alt} className="size-full object-cover" src={src} />
      ) : fallback ? (
        <span aria-hidden={alt ? undefined : "true"}>{fallback}</span>
      ) : null}
    </span>
  )
}

type SelectItemFlagProps = React.ComponentProps<"span"> & {
  alt?: string
  src?: string
}

function SelectItemFlag({
  alt = "",
  className,
  src,
  ...props
}: SelectItemFlagProps) {
  return (
    <span
      data-slot="select-item-flag"
      className={cn(
        "relative size-[var(--bh-select-icon-slot-size)] shrink-0 overflow-hidden rounded-[var(--bh-radius-full)] bg-[var(--bh-bg-always-white)]",
        className
      )}
      {...props}
    >
      {src ? (
        <img alt={alt} className="size-full object-cover" src={src} />
      ) : (
        <>
          <span className="absolute inset-x-0 top-0 h-1/3 bg-[var(--bh-bg-accent-red-default)]" />
          <span className="absolute inset-x-0 top-1/3 h-1/3 bg-[var(--bh-bg-always-white)]" />
          <span className="absolute inset-x-0 bottom-0 h-1/3 bg-[var(--bh-bg-always-dark)]" />
          <span className="absolute start-1/2 top-1/2 size-[var(--bh-space-xs-4)] -translate-x-1/2 -translate-y-1/2 rounded-[var(--bh-radius-full)] bg-[var(--bh-bg-accent-golden-default)]" />
        </>
      )}
    </span>
  )
}

type SelectItemCompanyLogoProps = React.ComponentProps<"span">

function SelectItemCompanyLogo({
  className,
  ...props
}: SelectItemCompanyLogoProps) {
  return (
    <span
      data-slot="select-item-company"
      className={cn(
        "flex size-[var(--bh-select-icon-slot-size)] shrink-0 items-center justify-center rounded-[var(--bh-radius-full)] bg-[var(--bh-bg-accent-purple-soft)] text-[var(--bh-content-accent-purple-default)]",
        className
      )}
      {...props}
    >
      <svg
        aria-hidden="true"
        className="size-[var(--bh-select-company-icon-size)]"
        fill="none"
        focusable="false"
        viewBox="0 0 18 18"
      >
        <path
          d="M3 10.25C5.4 6.75 7.5 6.75 10 9.4C11.6 11.1 13 11 15 8.75"
          stroke="currentColor"
          strokeLinecap="round"
          strokeWidth="2.4"
        />
        <path
          d="M3 7.7C5.3 4.5 7.4 4.5 9.8 7.05C11.4 8.75 13 8.65 15 6.4"
          stroke="currentColor"
          strokeLinecap="round"
          strokeWidth="2.4"
          opacity="var(--bh-opacity-70)"
        />
      </svg>
    </span>
  )
}

type SelectItemPaymentIconProps = React.ComponentProps<"span">

function SelectItemPaymentIcon({
  className,
  ...props
}: SelectItemPaymentIconProps) {
  return (
    <span
      data-slot="select-item-payment"
      className={cn(
        "relative block h-[var(--bh-select-payment-height)] w-[var(--bh-select-payment-width)] shrink-0 rounded-[var(--bh-select-payment-radius)] border border-[var(--bh-border-subtle)] bg-[var(--bh-bg-always-white)]",
        className
      )}
      {...props}
    >
      <span className="absolute start-[var(--bh-select-payment-mark-offset)] top-1/2 size-[var(--bh-select-payment-mark-size)] -translate-y-1/2 rounded-[var(--bh-radius-full)] bg-[var(--bh-bg-accent-red-default)]" />
      <span className="absolute end-[var(--bh-select-payment-mark-offset)] top-1/2 size-[var(--bh-select-payment-mark-size)] -translate-y-1/2 rounded-[var(--bh-radius-full)] bg-[var(--bh-bg-accent-blue-default)] mix-blend-multiply" />
    </span>
  )
}

type SelectItemStatusDotProps = React.ComponentProps<"span"> &
  VariantProps<typeof selectStatusDot>

function SelectItemStatusDot({
  className,
  tone,
  ...props
}: SelectItemStatusDotProps) {
  return (
    <span
      data-slot="select-item-dot-wrap"
      className="flex size-[var(--bh-select-icon-slot-size)] shrink-0 items-center justify-center p-[var(--bh-space-xxxs-1)]"
      {...props}
    >
      <span
        data-slot="select-item-dot"
        className={cn(selectStatusDot({ tone }), className)}
      />
    </span>
  )
}

const defaultSelectItemMedia: Partial<Record<SelectItemType, () => React.ReactNode>> = {
  avatar: () => <SelectItemAvatar />,
  company: () => <SelectItemCompanyLogo />,
  dot: () => <SelectItemStatusDot />,
  flag: () => <SelectItemFlag />,
  icon: () => <SelectIcon name="plus" />,
  payment: () => <SelectItemPaymentIcon />,
}

function getDefaultSelectItemMedia(itemType: SelectItemType) {
  return defaultSelectItemMedia[itemType]?.() ?? null
}

function SelectIcon({
  className,
  name,
}: {
  className?: string
  name: SelectIconName
}) {
  const iconClassName = cn("size-[var(--bh-select-icon-size)]", className)

  if (name === "user") {
    return (
      <svg
        aria-hidden="true"
        className={iconClassName}
        fill="none"
        focusable="false"
        viewBox="0 0 16 16"
      >
        <path
          d="M8 8C5.79 8 4 6.21 4 4S5.79 0 8 0s4 1.79 4 4s-1.79 4-4 4Zm0 1.5c3.31 0 6 1.79 6 4v1H2v-1c0-2.21 2.69-4 6-4Zm0-3A2.5 2.5 0 1 0 8 1a2.5 2.5 0 0 0 0 5.5Zm-4.36 7h8.72C11.8 12.08 10.05 11 8 11s-3.8 1.08-4.36 2.5Z"
          fill="currentColor"
        />
      </svg>
    )
  }

  if (name === "info" || name === "error") {
    return (
      <svg
        aria-hidden="true"
        className={iconClassName}
        fill="none"
        focusable="false"
        viewBox="0 0 16 16"
      >
        <path
          d="M8 14.667A6.667 6.667 0 1 1 8 1.333a6.667 6.667 0 0 1 0 13.334ZM7.333 9.333v1.334h1.334V9.333H7.333Zm0-4v2.834h1.334V5.333H7.333Z"
          fill="currentColor"
        />
      </svg>
    )
  }

  if (name === "chevron-down") {
    return (
      <svg
        aria-hidden="true"
        className={iconClassName}
        fill="none"
        focusable="false"
        viewBox="0 0 16 16"
      >
        <path
          d="M8 10.667 3.333 6l.934-.933L8 8.8l3.733-3.733.934.933L8 10.667Z"
          fill="currentColor"
        />
      </svg>
    )
  }

  if (name === "plus") {
    return (
      <svg
        aria-hidden="true"
        className={iconClassName}
        fill="none"
        focusable="false"
        viewBox="0 0 20 20"
      >
        <path d="M9.167 9.167V4.5h1.666v4.667H15.5v1.666h-4.667V15.5H9.167v-4.667H4.5V9.167h4.667Z" fill="currentColor" />
      </svg>
    )
  }

  if (name === "check-fill" || name === "check-line") {
    return (
      <svg
        aria-hidden="true"
        className={iconClassName}
        fill="none"
        focusable="false"
        viewBox="0 0 20 20"
      >
        <path
          d="m8.333 12.643 7.66-7.66 1.179 1.178-8.839 8.839-5.303-5.303 1.178-1.179 4.125 4.125Z"
          fill="currentColor"
        />
      </svg>
    )
  }

  return null
}

export {
  getDefaultSelectItemMedia,
  SelectIcon,
  SelectItemAvatar,
  SelectItemCompanyLogo,
  SelectItemFlag,
  SelectItemPaymentIcon,
  SelectItemStatusDot,
}
export type { SelectIconName, SelectItemType, SelectStatusTone }
