/* eslint-disable @typescript-eslint/no-explicit-any */
import { useState, ReactNode } from "react";
import Select, { StylesConfig } from "react-select";
import CreatableSelect from "react-select/creatable";

// Option type
export interface CustomOption {
  id: string | number;
  name: string;
  code: string;
}

interface CustomSelectOptionsProps {
  options: CustomOption[]; // <-- required
  className?: string;
  name: string;
  id?: string;
  onChange: (value: CustomOption | CustomOption[] | null, name: string, index?: string | number) => void;
  value?: CustomOption | CustomOption[] | null;
  required?: boolean;
  isMulti?: boolean;
  label?: string;
  isCreatable?: boolean;
  isLoading?: boolean;
  icon?: ReactNode | string;
  errors?: string;
  width?: string | number;
  index?: string | number;
  isClearable?: boolean;
  isDisabled?: boolean;
  placeholder?: string;
  style?: StylesConfig<CustomOption, boolean>;
  divClassName?: string;
  onCreateOption?: (inputValue: string) => void;
}

const customStyles: StylesConfig<CustomOption, boolean> = {
  option: (provided, state) => ({
    ...provided,
    borderBottom: "1px dotted gray",
    color: state.isSelected ? "white" : "black",
  }),
  control: (base, state) => ({
    ...base,
    border: state.isFocused ? "2px solid #1976d2" : "2px solid #222",
    borderRadius: "8px",
    minHeight: "48px",
    boxShadow: state.isFocused ? "0 0 0 1px #1976d2" : base.boxShadow,
  }),
};

function CustomSelectOptions({
  options,
  className = "",
  name,
  id,
  onChange,
  value,
  required = false,
  isMulti = false,
  label = "",
  isCreatable = false,
  isLoading = false,
  icon,
  errors,
  width,
  index = "",
  isClearable = true,
  isDisabled = false,
  placeholder = "",
  style,
  divClassName = "",
  onCreateOption,
}: CustomSelectOptionsProps) {
  const [selectedValues, setSelectedValues] = useState<CustomOption | CustomOption[] | null>(value || (isMulti ? [] : null));
  const Multiselect = isCreatable ? CreatableSelect : Select;

  // Add new option handler
  const handleCreate = (inputValue: string) => {
    const newOption: CustomOption = { id: inputValue, name: inputValue, code: inputValue };
    setSelectedValues(newOption);
    onChange(newOption, name, index);
    onCreateOption?.(inputValue);
  };

  // Custom create label
  const formatCreateLabel = (inputValue: string) => {
    if (inputValue.trim() === "") {
      return "Add";
    } else {
      return (
        <div
          style={{
            background: "#e6f0ff",
            border: "1px solid #b3d1ff",
            borderRadius: 8,
            margin: 0,
            padding: 12,
            cursor: "pointer",
            display: "flex",
            alignItems: "center",
            gap: 8,
          }}
        >
          <span>
            <i className="ri-add-circle-fill" style={{ fontSize: 20, color: "#003399", verticalAlign: "middle" }}></i>
          </span>
          <span style={{ color: "#003399", fontWeight: 700, fontSize: 16 }}>
            Add <strong>&lsquo;{inputValue}&rsquo;</strong> to {label ? label : name} options
          </span>
        </div>
      );
    }
  };

  // Option label: code - name
  const getOptionLabel = (option: CustomOption) => `${option.code}${(option.name) ? ` - ${option.name}` : ``}`;
  // Selected value label: code only
  const getSingleValueLabel = (option: CustomOption) => option.code;

  return (
    <div
      className={divClassName}
      style={{ width: width || "auto", position: "relative" }}
    >
      {icon && (
        <span
          style={{
            position: "absolute",
            left: 12,
            top: "50%",
            transform: "translateY(-50%)",
            zIndex: 2,
            pointerEvents: "none",
          }}
        >
          {typeof icon === "string" ? <i className={icon} /> : icon}
        </span>
      )}
      <Multiselect
        name={name}
        id={id}
        isMulti={isMulti}
        value={selectedValues}
        onChange={(selected) => {
          setSelectedValues(selected as any);
          onChange(selected as any, name, index);
        }}
        options={options}
        required={required}
        className={className + " multiple-select01" + (errors ? " has-error" : "")}
        onCreateOption={isCreatable ? handleCreate : undefined}
        getOptionValue={(option) => option.id.toString()}
        getOptionLabel={getOptionLabel}
        styles={style || customStyles}
        formatCreateLabel={formatCreateLabel}
        isClearable={isClearable}
        isDisabled={isDisabled}
        placeholder={placeholder}
        isLoading={isLoading}
        isSearchable
        components={{
          SingleValue: (props) => (
            <div className="react-select__single-value">{getSingleValueLabel(props.data as CustomOption)}</div>
          ),
        }}
      />
      {errors && (
        <div style={{ color: "red", fontSize: 12, marginTop: 4 }}>{errors}</div>
      )}
    </div>
  );
}

export default CustomSelectOptions;