import Joi from "joi";
import React, { useEffect } from "react";
import { Navigate, useParams } from "react-router-dom";
import { toast } from "react-toastify";
import { useTranslation } from "react-i18next";
import { Namespaces } from "../../../../i18n/i18n";
import { useForm } from "../../../../components/common/useForm";
import { InputType } from "../../../../components/common/Input";
import { GeneralIdRef, MakeGeneralIdRef } from "../../../../utils/GeneralIdRef";
import authentication from "../../../frame/services/authenticationService";
import userService from "../services/usersService";
import Loading from "../../../../components/common/Loading";
import { CustomFieldValue } from "../../glossary/services/glossaryService";
import {
  renderInput,
  renderButton,
  renderError,
  renderDomainPicker,
} from "../../../../components/common/formHelpers";

interface GeneralTabProps {
  isEditMode: boolean;
}

const GeneralTab: React.FC<GeneralTabProps> = ({ isEditMode }) => {
  const { userId } = useParams<{ userId: string }>();
  const { t } = useTranslation(Namespaces.Common);

  const labelFirstName = t("FirstName");
  const labelMiddleNames = t("MiddleNames");
  const labelLastName = t("LastName");
  const labelEmail = t("Mail");
  const labelDomain = t("Domain");

  const labelApply = t("Save");
  const labelSave = t("SaveAndClose");

  const form = useForm({
    loaded: false,
    data: {
      firstName: "",
      lastName: "",
      middleNames: "",
      email: "",
      domain: [] as CustomFieldValue[],
    },
    errors: {},
    redirect: "",
  });

  form.schema = {
    firstName: Joi.string().required().max(450).label(labelFirstName),
    middleNames: Joi.string().allow("").required().label(labelMiddleNames),
    lastName: Joi.string().required().label(labelLastName),
    email: Joi.string()
      .required()
      .email({ tlds: { allow: false } })
      .label(labelEmail),
    domain: Joi.optional(),
  };

  useEffect(() => {
    const loadData = async () => {
      const newData = { ...form.state.data };

      if (userId !== undefined) {
        try {
          const loadedData = await userService.getUser(BigInt(userId));
          if (loadedData) {
            newData.firstName = loadedData.firstName;
            newData.lastName = loadedData.lastName;
            newData.middleNames = loadedData.middleNames;
            newData.email = loadedData.email;
            newData.domain = [{ value: loadedData.domain } as CustomFieldValue];
          }
        } catch (ex: any) {
          form.handleGeneralError(ex);
        }
      } else {
        const user = authentication.getCurrentUser();
        newData.domain = [
          { value: MakeGeneralIdRef(user?.domainid) } as CustomFieldValue,
        ];
      }

      form.setState({ loaded: true, data: newData });
    };

    loadData();
  }, [userId]); // eslint-disable-line react-hooks/exhaustive-deps

  const doSubmit = async (buttonName: string) => {
    try {
      const { firstName, middleNames, lastName, email, domain } =
        form.state.data;
      const firstNameStr = typeof firstName === "string" ? firstName : "";
      const middleNamesStr = typeof middleNames === "string" ? middleNames : "";
      const lastNameStr = typeof lastName === "string" ? lastName : "";
      const emailStr = typeof email === "string" ? email : "";
      const domainValues = (domain as CustomFieldValue[]) ?? [];
      const domainValue = domainValues[0]?.value as GeneralIdRef | undefined;

      if (isEditMode) {
        const generalIdRef = MakeGeneralIdRef(
          userId ? BigInt(userId) : undefined,
        );
        const response = await userService.putUser(
          generalIdRef,
          firstNameStr,
          middleNamesStr,
          lastNameStr,
          emailStr,
          domainValue,
        );
        if (response) {
          toast.info(t("UserEdited"));
        }
      } else {
        const response = await userService.postUser(
          firstNameStr,
          middleNamesStr,
          lastNameStr,
          emailStr,
          domainValue,
        );
        if (response) {
          toast.info(t("NewUserAdded"));
        }
      }

      if (buttonName === "save") {
        form.setState({ redirect: "/users" });
      }
    } catch (ex: any) {
      form.handleGeneralError(ex);
    }
  };

  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    form.handleSubmit(e, doSubmit);
  };

  const { loaded, redirect } = form.state;
  if (redirect) return <Navigate to={redirect} />;

  return (
    <Loading loaded={loaded}>
      <form onSubmit={handleSubmit}>
        {renderError("_general", form.state.errors)}
        {isEditMode &&
          renderInput(
            "email",
            labelEmail,
            form.state.data,
            form.state.errors,
            InputType.text,
            true,
            "",
            "",
            0,
            true,
            undefined,
            form.handleChange,
          )}
        {!isEditMode &&
          renderInput(
            "email",
            labelEmail,
            form.state.data,
            form.state.errors,
            InputType.text,
            false,
            "",
            "",
            0,
            true,
            undefined,
            form.handleChange,
          )}
        {renderInput(
          "firstName",
          labelFirstName,
          form.state.data,
          form.state.errors,
          InputType.text,
          false,
          "",
          "",
          0,
          true,
          undefined,
          form.handleChange,
        )}
        {renderInput(
          "middleNames",
          labelMiddleNames,
          form.state.data,
          form.state.errors,
          InputType.text,
          false,
          "",
          "",
          0,
          false,
          undefined,
          form.handleChange,
        )}
        {renderInput(
          "lastName",
          labelLastName,
          form.state.data,
          form.state.errors,
          InputType.text,
          false,
          "",
          "",
          0,
          true,
          undefined,
          form.handleChange,
        )}

        {renderDomainPicker(
          true,
          "domain",
          labelDomain,
          form.state.data,
          form.state.errors,
          1,
          undefined,
          form.handleDomainPickerChange,
        )}

        {isEditMode && renderButton(labelApply, form.state.errors, "save")}
        {renderButton(labelSave, form.state.errors, "save")}
      </form>
    </Loading>
  );
};

export default GeneralTab;
