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 {
  renderInput,
  renderButton,
  renderError,
  renderSelect,
} from "../../../components/common/formHelpers";
import { MakeGeneralIdRef } from "../../../utils/GeneralIdRef";
import Option from "../../../components/common/option";
import siteService from "./services/sitessService";
import Loading from "../../../components/common/Loading";

interface SiteDetailsProps {
  editMode?: boolean;
}

const SiteDetails: React.FC<SiteDetailsProps> = ({ editMode = false }) => {
  const { organisationId, siteId } = useParams<{
    organisationId: string;
    siteId?: string;
  }>();
  const { t } = useTranslation(Namespaces.Common);

  const labelName = t("Name");
  const labelAddress = t("Address");
  const labelStatus = t("Status");

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

  const form = useForm({
    loaded: false,
    data: {
      name: "",
      address: "",
      status: "Active",
    },
    errors: {},
    redirect: "",
  });

  form.schema = {
    name: Joi.string().required().max(450).label(labelName),
    address: Joi.string().required().max(450).label(labelAddress),
    status: Joi.string().required().max(450).label(labelStatus),
  };

  useEffect(() => {
    const loadData = async () => {
      if (siteId !== undefined) {
        try {
          const loadedData = await siteService.getSite(BigInt(siteId));
          if (loadedData) {
            const newData = { ...form.state.data };
            newData.name = loadedData.name;
            newData.address = loadedData.address;
            newData.status = loadedData.status;
            form.setState({ loaded: true, data: newData });
          } else {
            form.setState({ loaded: false });
          }
        } catch (ex: any) {
          form.handleGeneralError(ex);
        }
      }

      if (!editMode) {
        form.setState({ loaded: true });
      }
    };

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

  const doSubmit = async (buttonName: string) => {
    try {
      const { name, address, status } = form.state.data;
      const nameStr = typeof name === "string" ? name : "";
      const addressStr = typeof address === "string" ? address : "";
      const statusStr = typeof status === "string" ? status : "";
      const organisationGeneralIdRef = MakeGeneralIdRef(
        organisationId ? BigInt(organisationId) : undefined,
      );

      if (editMode) {
        const siteGeneralIdRef = MakeGeneralIdRef(
          siteId ? BigInt(siteId) : undefined,
        );
        const response = await siteService.putSite(
          siteGeneralIdRef,
          nameStr,
          addressStr,
          statusStr,
          organisationGeneralIdRef,
        );
        if (response) {
          toast.info(t("SiteEdited"));
        }
      } else {
        const response = await siteService.postSite(
          nameStr,
          addressStr,
          statusStr,
          organisationGeneralIdRef,
        );
        if (response) {
          toast.info(t("NewSiteAdded"));
        }
      }

      if (buttonName === "save") {
        form.setState({ redirect: "/site/" + organisationId });
      }
    } 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} />;

  const organisationStatusOptions: Option[] = [
    { _id: "Active", name: t("Active") },
    { _id: "Pending", name: t("Pending") },
    { _id: "Blocked", name: t("Blocked") },
  ];

  const mode = editMode ? t("Edit") : t("Add");

  return (
    <Loading loaded={loaded}>
      <h1>
        {mode} {t("Site")}
      </h1>
      <form onSubmit={handleSubmit}>
        {renderError("_general", form.state.errors)}
        {renderInput(
          "name",
          labelName,
          form.state.data,
          form.state.errors,
          InputType.text,
          false,
          "",
          "",
          0,
          true,
          undefined,
          form.handleChange,
        )}
        {renderInput(
          "address",
          labelAddress,
          form.state.data,
          form.state.errors,
          InputType.text,
          false,
          "",
          "",
          0,
          true,
          undefined,
          form.handleChange,
        )}
        {renderSelect(
          "status",
          labelStatus,
          form.state.data,
          form.state.errors,
          organisationStatusOptions,
          form.handleSelectChange,
        )}
        {editMode && renderButton(labelApply, form.state.errors, "save")}
        {renderButton(labelSave, form.state.errors, "save")}
      </form>
    </Loading>
  );
};

export default SiteDetails;
