"use client";

import { ChevronUpIcon } from "@/assets/icons";
import { cn } from "@/lib/utils";
import { useId, useState, type ChangeEvent } from "react";
import {
  type FieldErrors,
  type FieldValues,
  type Path,
  type UseFormRegister,
  type UseFormRegisterReturn,
} from "react-hook-form";

type PropsType<T extends FieldValues> = {
  name: Path<T>;
  label: string;
  items: { value: string; label: string }[];
  prefixIcon?: React.ReactNode;
  onChange?: (e: ChangeEvent<HTMLSelectElement>) => void;
  className?: string;
  register?: UseFormRegister<T>;
  errors?: FieldErrors<T>;
  required?: boolean;
} & (
  | { placeholder?: string; defaultValue: string }
  | { placeholder: string; defaultValue?: string }
) &
  Partial<UseFormRegisterReturn>;

export function Select<T extends FieldValues>({
  items,
  label,
  defaultValue,
  placeholder,
  prefixIcon,
  className,
  name,
  register,
  errors,
  required,
  onChange,
  onBlur,
  ref,
  ...props
}: PropsType<T>) {
  const id = useId();

  const [isOptionSelected, setIsOptionSelected] = useState(!!defaultValue);
  const error = errors && errors[name];

  return (
    <div className={cn("space-y-3", className)}>
      <label
        htmlFor={id}
        className="block text-body-sm font-medium text-dark dark:text-white"
      >
        {label}
        {required && <span className="ml-1 select-none text-error">*</span>}
      </label>

      <div className="relative">
        {prefixIcon && (
          <div className="absolute left-4 top-1/2 -translate-y-1/2">
            {prefixIcon}
          </div>
        )}

        <select
          id={id}
          name={name}
          ref={ref}
          defaultValue={defaultValue || ""}
          onChange={(e) => {
            setIsOptionSelected(!!e.target.value);
            onChange?.(e);
          }}
          onBlur={onBlur}
          className={cn(
            "w-full appearance-none rounded-lg border border-stroke bg-transparent px-5.5 py-3 outline-none transition focus:border-primary active:border-primary dark:border-dark-3 dark:bg-dark-2 dark:focus:border-primary [&>option]:text-dark-5 dark:[&>option]:text-dark-6",
            isOptionSelected && "text-dark dark:text-white",
            error && "border-red focus:border-red dark:border-red",
            prefixIcon && "pl-11.5",
          )}
        >
          {placeholder && (
            <option value="" disabled hidden>
              {placeholder}
            </option>
          )}

          {items.map((item) => (
            <option key={item.value} value={item.value}>
              {item.label}
            </option>
          ))}
        </select>

        <ChevronUpIcon className="pointer-events-none absolute right-4 top-1/2 -translate-y-1/2 rotate-180" />
      </div>

      {error && (
        <p className="text-red mt-1.5 text-sm">{error.message as string}</p>
      )}
    </div>
  );
}
