"use client"

import * as SelectPrimitive from "@radix-ui/react-select"
import { ChevronDown, ChevronUp } from "lucide-react"
import { CheckIcon } from "../icons-v2-generated/signs-and-symbols/check-icon"
import { Chevron02DownIcon } from "../icons-v2-generated/arrows/chevron-02-down-icon"
import * as React from "react"

import { cn } from "../../utils/cn"
import { FieldWrapper } from "./field-wrapper"

const Select = SelectPrimitive.Root

const SelectGroup = SelectPrimitive.Group

const SelectValue = SelectPrimitive.Value

const SelectTrigger = React.forwardRef<
  React.ComponentRef<typeof SelectPrimitive.Trigger>,
  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & {
    invalid?: boolean
    label?: string
    /** Label scale forwarded to FieldWrapper ("large" = text-h4 for designs with body-scale field titles) */
    labelVariant?: "default" | "large"
    error?: string
  }
>(({ className, children, invalid, label, labelVariant, error, ...props }, ref) => {
  const isInvalid = invalid || !!error

  const trigger = (
    <SelectPrimitive.Trigger
      ref={ref}
      data-invalid={isInvalid || undefined}
      className={cn(
        // Layout & spacing - match Input
        // text-left resets the <button> UA default text-align:center, which the
        // SelectValue span inherits and would otherwise center short values,
        // reading as spurious left indentation on the selected value.
        "flex w-full items-center justify-between gap-2 rounded-[6px] border px-3 h-11 md:h-12 outline-none text-left",
        // Typography - match Input exactly
        "text-h4",
        // Theme palette - match Input exactly
        "bg-ods-card border-ods-border text-ods-text-primary data-[placeholder]:text-ods-text-secondary",
        "enabled:hover:bg-ods-bg-hover enabled:hover:border-ods-border-hover enabled:active:bg-ods-bg-active enabled:active:border-ods-border-active",
        !isInvalid && "data-[state=open]:border-ods-accent data-[state=open]:hover:border-ods-accent",
        "group",
        // Disabled - match Input exactly: value greys out, placeholder dims
        // further. The `data-[placeholder]` rule above is a class+attribute
        // selector, so the disabled placeholder rule stacks `:disabled` on top
        // of it to win on specificity rather than on source order.
        "disabled:!cursor-not-allowed disabled:bg-ods-bg",
        "disabled:text-ods-text-disabled disabled:data-[placeholder]:text-ods-border",
        // The chevron sets its own colour — grey it with the value.
        "disabled:[&_svg]:text-ods-text-disabled",
        "transition-colors duration-200 cursor-pointer",
        "[&>span]:line-clamp-1",
        isInvalid && "border-ods-error enabled:hover:border-ods-error enabled:active:border-ods-error data-[state=open]:border-ods-error",
        className
      )}
      {...props}
    >
      {children}
      <SelectPrimitive.Icon asChild>
        <Chevron02DownIcon className={cn(
          "shrink-0 text-ods-text-secondary transition-all duration-200 group-data-[state=open]:rotate-180",
          isInvalid ? "text-ods-error" : "group-data-[state=open]:text-ods-accent"
        )} size={24} />
      </SelectPrimitive.Icon>
    </SelectPrimitive.Trigger>
  )

  return (
    <FieldWrapper label={label} labelVariant={labelVariant} error={error}>
      {trigger}
    </FieldWrapper>
  )
})
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName

const SelectScrollUpButton = React.forwardRef<
  React.ComponentRef<typeof SelectPrimitive.ScrollUpButton>,
  React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
  <SelectPrimitive.ScrollUpButton
    ref={ref}
    className={cn(
      "flex cursor-default items-center justify-center py-1",
      className
    )}
    {...props}
  >
    <ChevronUp className="h-4 w-4" />
  </SelectPrimitive.ScrollUpButton>
))
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName

const SelectScrollDownButton = React.forwardRef<
  React.ComponentRef<typeof SelectPrimitive.ScrollDownButton>,
  React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
  <SelectPrimitive.ScrollDownButton
    ref={ref}
    className={cn(
      "flex cursor-default items-center justify-center py-1",
      className
    )}
    {...props}
  >
    <ChevronDown className="h-4 w-4" />
  </SelectPrimitive.ScrollDownButton>
))
SelectScrollDownButton.displayName =
  SelectPrimitive.ScrollDownButton.displayName

const SelectContent = React.forwardRef<
  React.ComponentRef<typeof SelectPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = "popper", ...props }, ref) => (
  <SelectPrimitive.Portal>
    <SelectPrimitive.Content
      ref={ref}
      className={cn(
        "relative z-[9999] max-h-96 overflow-hidden rounded-[4px] border border-ods-border bg-ods-card text-ods-text-primary",
        "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
        position === "popper" &&
          "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
        className
      )}
      position={position}
      style={{
        width: 'var(--radix-select-trigger-width)',
        minWidth: 'var(--radix-select-trigger-width)'
      }}
      {...props}
    >
      <SelectScrollUpButton />
      <SelectPrimitive.Viewport className="w-full">
        {children}
      </SelectPrimitive.Viewport>
      <SelectScrollDownButton />
    </SelectPrimitive.Content>
  </SelectPrimitive.Portal>
))
SelectContent.displayName = SelectPrimitive.Content.displayName

const SelectLabel = React.forwardRef<
  React.ElementRef<typeof SelectPrimitive.Label>,
  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
>(({ className, ...props }, ref) => (
  <SelectPrimitive.Label
    ref={ref}
    className={cn("py-1.5 pl-8 pr-2 text-h6 font-semibold", className)}
    {...props}
  />
))
SelectLabel.displayName = SelectPrimitive.Label.displayName

const SelectItem = React.forwardRef<
  React.ComponentRef<typeof SelectPrimitive.Item>,
  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
  <SelectPrimitive.Item
    ref={ref}
    className={cn(
      "flex w-full cursor-pointer select-none items-center justify-between h-11 md:h-12 px-4 border-b border-ods-border last:border-b-0",
      // Typography - match trigger
      "text-h4 whitespace-nowrap",
      // Hover state with visible background change
      "outline-none hover:bg-ods-bg-hover data-[highlighted]:bg-ods-bg-surface",
      "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
      "transition-colors duration-150",
      className
    )}
    {...props}
  >
    <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
    <SelectPrimitive.ItemIndicator>
      <CheckIcon className="text-ods-accent" size={20} />
    </SelectPrimitive.ItemIndicator>
  </SelectPrimitive.Item>
))
SelectItem.displayName = SelectPrimitive.Item.displayName

const SelectSeparator = React.forwardRef<
  React.ComponentRef<typeof SelectPrimitive.Separator>,
  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
>(({ className, ...props }, ref) => (
  <SelectPrimitive.Separator
    ref={ref}
    className={cn("-mx-1 my-1 h-px bg-ods-border", className)}
    {...props}
  />
))
SelectSeparator.displayName = SelectPrimitive.Separator.displayName

export {
  Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue
}
