"use client"
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
import React, { forwardRef, ElementRef, ComponentPropsWithoutRef } from "react"
import { tv } from "tailwind-variants"
import { type VariantProps } from "tailwind-variants"
import { Check } from "../../icons/material-symbols/outlined/Check"
import { HorizontalRule } from "../../icons/material-symbols/outlined/HorizontalRule"
import { disabledVariants } from "../../styles"
import { disabledWrapperVariants } from "../../styles/utils/disabledWrapper"
import { classNames } from "../../utils"

export type CheckboxProps = Pick<
  ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>,
  | "autoFocus"
  | "checked"
  | "className"
  | "disabled"
  | "id"
  | "name"
  | "onClick"
  | "asChild"
> &
  VariantProps<typeof checkboxVariants> & {
    onCheckedChange?: (checked: boolean) => void
  }

const checkboxVariants = tv({
  base: classNames(
    "size-4 min-h-4 min-w-4 rounded border outline-hidden transition-colors duration-150",
    // Only show focus border when keyboard is used, not on mouse click
    "focus:border-border-3 [&:not(:focus-visible)]:border-border-2",
  ),
  variants: {
    checked: {
      false: "border-border-2 bg-bg-primary",
      true: "border-0 bg-blue-3",
      indeterminate: "border-0 bg-blue-3",
    },
  },
})

/**
 * A control that allows the user to toggle between checked and not checked.
 */
export const Checkbox = forwardRef<
  ElementRef<typeof CheckboxPrimitive.Root>,
  CheckboxProps
>(function Checkbox(
  { className, checked = false, disabled, onCheckedChange, ...props },
  ref,
) {
  const Icon = checked === "indeterminate" ? HorizontalRule : Check
  return (
    <span className={classNames(disabledWrapperVariants({ disabled }))}>
      <CheckboxPrimitive.Root
        checked={checked}
        className={classNames(
          checkboxVariants({ checked }),
          disabledVariants({ disabled }),
          className,
        )}
        disabled={disabled}
        ref={ref}
        onCheckedChange={() => {
          // Handles both checked and indeterminate states
          onCheckedChange?.(!checked)
        }}
        {...props}
      >
        <CheckboxPrimitive.Indicator className="flex items-center justify-center">
          <Icon fill="white" size={14} />
        </CheckboxPrimitive.Indicator>
      </CheckboxPrimitive.Root>
    </span>
  )
})
