import React, { useEffect, useState, useCallback } from "react";
import Select from "../common/Select";
import Option from "../common/option";
import { GeneralIdRef, MakeGeneralIdRef } from "../../utils/GeneralIdRef";
import customFieldsService, {
  CustomField,
} from "../../modules/manager/customfields/services/customFieldsService";

interface CustomFieldPickerProps {
  name: string;
  label: string;
  error?: string;
  value: any;
  exclude?: CustomField[];
  onChange?: (name: string, id: GeneralIdRef, displayValue: string) => void;
}

export default function CustomFieldPicker({
  name,
  label,
  error,
  value,
  exclude,
  onChange,
}: CustomFieldPickerProps) {
  const [options, setOptions] = useState<Option[]>([]);

  useEffect(() => {
    async function load() {
      const pagedData = await customFieldsService.getFields(
        0,
        10,
        "name",
        true,
      );
      if (pagedData) {
        const opts: Option[] = (pagedData.data as any[]).map(
          (x: { id: any; name: any }) => ({
            _id: x.id,
            name: x.name,
          }),
        );
        setOptions(opts);
      }
    }

    load();
  }, []);

  const getOptionById = useCallback(
    (val: string) => {
      for (const option of options) {
        if (String(option._id) === val) return option.name;
      }
      return "";
    },
    [options],
  );

  const handleChange = useCallback(
    (e: React.ChangeEvent<HTMLSelectElement>) => {
      const input = e.currentTarget;
      const generalIdRef = MakeGeneralIdRef(BigInt(input.value));
      const displayValue = getOptionById(input.value);

      if (onChange) onChange(input.name, generalIdRef, displayValue);
    },
    [onChange, getOptionById],
  );

  const getFilteredOptions = useCallback(() => {
    return options.filter((o) => {
      if (exclude) {
        for (const excludedItem of exclude) {
          const idAsString: string = String(excludedItem.id);
          const oid: string = String(o._id);
          if (oid === idAsString) return false;
        }
      }
      return true;
    });
  }, [options, exclude]);

  const filteredOptions = getFilteredOptions();

  return (
    <Select
      name={name}
      label={label}
      error={error}
      value={value?.id}
      options={filteredOptions}
      includeBlankFirstEntry={true}
      onChange={handleChange}
    />
  );
}
