"use client";

import {
  Autocomplete,
  MenuItem,
  TextField,
  Checkbox,
  Chip,
} from "@mui/material";
import {
  Controller,
  FieldValues,
  Path,
  Control,
  RegisterOptions,
} from "react-hook-form";
import { useTranslation } from "react-i18next";
import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank";
import CheckBoxIcon from "@mui/icons-material/CheckBox";

const icon = <CheckBoxOutlineBlankIcon fontSize="medium" />;
const checkedIcon = <CheckBoxIcon fontSize="medium" />;
// label -> e.g. code - name -> 001 - WL
// name -> WL
interface Props<
  T extends { id?: number | string | null; label?: string; name?: string },
  TField extends FieldValues,
> {
  control: Control<TField>;
  options: T[];
  name: Path<TField>; // register name
  label?: string; // display label
  noOptionsText?: string;
  isMultiple?: boolean;
  rules?: RegisterOptions<FieldValues>;
  disabled?: boolean;
}

function ControlledAutoComplete<
  T extends { id?: number | string; label?: string; name?: string },
  TField extends FieldValues,
>(props: Props<T, TField>) {
  const { t } = useTranslation();
  const {
    control,
    options,
    name,
    label,
    noOptionsText,
    isMultiple,
    rules,
    disabled,
  } = props;

  // set default value if value is null
  if (!Boolean(isMultiple) && !Boolean(control._formValues[name])) {
    control._formValues[name] = options[0]?.id ?? undefined;
  } else if (Boolean(isMultiple) && !Boolean(control._formValues[name])) {
    control._formValues[name] = [];
  }

  return (
    <Controller
      name={name}
      control={control}
      rules={rules}
      render={({ field, fieldState, formState }) => {
        return isMultiple ? (
          <Autocomplete
            multiple
            disableClearable
            disableCloseOnSelect
            // disablePortal
            disabled={disabled}
            noOptionsText={noOptionsText ?? t("No Options")}
            value={options.filter((option) => {
              return field.value?.includes(option.id);
            })}
            options={options}
            getOptionLabel={(option) => option.label ?? option.name!}
            isOptionEqualToValue={(option, value) => option.id === value.id}
            renderOption={(params, option, { selected }) => {
              return (
                <li {...params} key={option?.id}>
                  <Checkbox
                    icon={icon}
                    checkedIcon={checkedIcon}
                    checked={selected}
                    style={{ marginRight: 8 }}
                  />
                  {option.label ?? option.name}
                </li>
              );
            }}
            renderTags={(tagValue, getTagProps) => {
              return tagValue.map((option, index) => (
                <Chip
                  {...getTagProps({ index })}
                  key={option?.id}
                  label={option.label ?? option.name}
                />
              ));
            }}
            onChange={(event, value) => {
              field.onChange(value?.map((v) => v.id));
            }}
            onBlur={field.onBlur}
            renderInput={(params) => (
              <TextField
                {...params}
                error={Boolean(formState.errors[name])}
                variant="outlined"
                label={label}
              />
            )}
          />
        ) : (
          <Autocomplete
            disableClearable
            // disablePortal
            disabled={disabled}
            noOptionsText={noOptionsText ?? t("No Options")}
            value={
              options.find((option) => option.id === field.value) ?? options[0]
            }
            options={options}
            getOptionLabel={(option) => option.label ?? option.name!}
            isOptionEqualToValue={(option, value) => option?.id === value?.id}
            renderOption={(params, option) => {
              return (
                <MenuItem {...params} key={option?.id} value={option.id}>
                  {option.label ?? option.name}
                </MenuItem>
              );
            }}
            renderTags={(tagValue, getTagProps) => {
              return tagValue.map((option, index) => (
                <Chip
                  {...getTagProps({ index })}
                  key={option?.id}
                  label={option.label ?? option.name}
                />
              ));
            }}
            onChange={(event, value) => {
              field.onChange(value?.id ?? null);
            }}
            onBlur={field.onBlur}
            renderInput={(params) => (
              <TextField
                {...params}
                error={Boolean(formState.errors[name])}
                variant="outlined"
                label={label}
              />
            )}
          />
        );
      }}
    />
  );
}

export default ControlledAutoComplete;
