import { FC, useCallback, useEffect, useState } from "react";
import { useObjectStateWrapper } from "../../hooks/useObjectState";
import { ValueField } from "./value-field";
import { HelpPopper } from "../Poppables/help";
import { Icon } from "../Icon";
import { RESERVED_FIELDS } from "../../constants/ReservedFields";
import {
  fieldTypeOptions,
  FieldTypes,
  fieldTypesWithValues,
} from "./fieldtypes";

interface IProps {
  update: (arg: FieldType) => void;
  field: FieldType;
  fieldName: string;
  deleteField: (arg: string) => void;
}

export const FieldEditor: FC<IProps> = (
  { update, field, fieldName, deleteField },
) => {
  const { bindProperty, bindPropertyCheck } = useObjectStateWrapper(
    field,
    (e) => update(typeof e === "function" ? e(field) : e),
  );

  const shouldShowValueField = useCallback(
    () => fieldTypesWithValues.includes(field.type) || field.isConstant,
    [field.isConstant, field.type],
  );

  const [reserved, setReserved] = useState<FieldType | undefined>(
    RESERVED_FIELDS[fieldName],
  );

  useEffect(() => {
    setReserved(RESERVED_FIELDS[fieldName]);
  }, [fieldName]);

  // useEffect(() => {
  //   console.log(field.value);
  // }, [field])

  return (
    <li className="odd:bg-black/50">
      <div className="flex gap-2 items-center">
        <p>{fieldName}</p>
        {reserved && (
          <HelpPopper>
            <p className="text-xs">
              This is a reserved field name, these exist for internal purposes,
              but are still useful when creating a type, and as such have
              specific settings that you cannot override. If you need control
              over the field properties, please use a different field name
            </p>
          </HelpPopper>
        )}
      </div>
      {!reserved && (
        <div className=" flex gap-x-4 items-center p-2 w-full">
          <label className="w-min">
            Field Type:&nbsp;
            <select
              className="capitalize"
              {...bindProperty("type")}
              disabled={!!reserved}
            >
              {fieldTypeOptions.map((o) => (
                <option
                  key={"fieldtypes" + o}
                  className="capitalize"
                  value={FieldTypes[o]}
                >
                  {o}
                </option>
              ))}
            </select>
          </label>

          {shouldShowValueField() && (
            <ValueField type={field.type} bind={bindProperty("value")} />
          )}
          <span className="flex items-center gap-2">
            <label>
              <input type="checkbox" {...bindPropertyCheck("isConstant")} />
              {" "}
              Is constant
            </label>
            <HelpPopper>
              <p className="text-sm">
                Constant values can&apos;t be overwritten in publications. When
                a dice field is set to a constant value, it instead rolls a dice
                of that value whenever this field is displayed (unless
                exported). This could be useful for a randomly generated
                scenario or for cards being drawn as the dice value will
                automatically be determined by the dice roll.
              </p>
            </HelpPopper>
          </span>
          <label className="w-min">
            Minimum:
            <input
              className="w-12"
              type="number"
              {...bindProperty("minimum")}
            />
          </label>
          <label className="w-min">
            Limit:
            <input className="w-12" type="number" {...bindProperty("limit")} />
          </label>
          <HelpPopper>
            <p className="text-sm">
              Minimum and Limit apply to the number of entries allowed for this
              field, not the maximum and minimum value. Set the minimum to 0 to
              make a field optional. Set the limit to 0 to allow for unlimited
              entries.
            </p>
          </HelpPopper>
          <button
            className="no-default self-end ml-auto"
            onClick={() => deleteField(fieldName)}
          >
            <Icon
              className="svg-red-700 hover:svg-red-500 trash-can w-6 h-6"
              icon="Trash"
            >
            </Icon>
          </button>
        </div>
      )}
    </li>
  );
};
