import React, { FC, useState } from "react";
import { IElementType } from "../../definitions/element";
import { Aligment, Form, Modal, Text } from "venice-ui";
import { dictionary } from "../../untils/dictionary";
import { t } from "../../helpers/userHelper";
import { jointValidator } from "../../definitions/definitionHelper";
import { IJointType } from "../../definitions/joint";
import { ConnectedWeld } from "../ConnectedWeld/ConnectedWeld";
import { IAddtionalElements } from "../../definitions/additional";
import { ifHaveReferences, isReferencePoint } from "../../helpers/weldHelpers";
import { useStoreActions, useStoreState } from "../../store";
import { setShowListPoints } from "../Section/sectionModel";
import {
  getConfig,
  setFormConfig,
  setFormStructure,
  setObjectState,
} from "../../definitionsNew/setFieldsHelper";
import { Scopes } from "../../definitionsNew/fields";
import { TScopesType } from "../../untils/const";
import { Tabs } from "../UI/Tabs";
import { TabModalWrapper } from "./modals.style";
import { ExistingSpool } from "../ExistingSpools/ExistingSpools";
import { apiCall } from "../../untils/apiCall";
import { isDisabled } from "@testing-library/user-event/dist/utils";
import { DeleteElementFrame } from "../components";

interface IPointModal {
  handleCancel: () => void;
  handleDelete: (
    id: string,
    isMapElement: boolean,
    isReference: boolean,
  ) => void;
  handleSave: (
    element: IElementType | IAddtionalElements,
    isSource: boolean,
  ) => void;
  elementID: string;
  element: IElementType;
  modalMode: string;
  predefineName?: string;
  handleAdd?: (element: IElementType) => void;
  handleAddSpool?: (spoolName: string) => void;
  handleAddReference?: (id: string) => void;
  handleAddSpoolReference?: (id: string) => void;
  fullSpec?: boolean;
  loading: boolean;
  setLoading: () => void;
  isOpen: boolean;
  sectionID?: string;
  elementTypeMode: string;
}
export const PointModal: FC<IPointModal> = ({
  handleCancel,
  handleDelete,
  handleSave,
  elementID,
  element,
  modalMode,
  predefineName,
  handleAdd,
  handleAddSpool,
  handleAddReference,
  handleAddSpoolReference,
  fullSpec = false,
  loading,
  setLoading,
  isOpen,
  sectionID,
  elementTypeMode,
}) => {
  const { configs, contracts, orgID, orgRole } = useStoreState(
    (state) => state.user.userDetails,
  );
  const { references, elements, sections, projectID } = useStoreState(
    (state) => state.projectDetails.projectDetails,
  );

  const { projects } = useStoreState((state) => state.projects);
  const { projectDetails } = useStoreState((state) => state.projectDetails);

  const { addSpool } = useStoreActions((actions) => actions.projectDetails);

  const allElements = setShowListPoints(
    elements,
    sections,
    projectID,
    getConfig(configs, Scopes.JointDetail),
    projects,
    projectDetails,
    contracts,
  );

  const [pageDetails, setPageDetails] = useState({
    mode: modalMode,
    existingJoint: false,
    existingSpool: false,
    selectedWeld: "",
    selectedSpool: "",
    spool: "",
    activeTab: elementTypeMode,
  });

  const syncName = (dataSet: IJointType) => {
    if (pageDetails.mode === "add" && dataSet.joint_name === "") {
      dataSet.joint_name = predefineName ? predefineName : "";
    }
    return dataSet;
  };

  const [details, setDetails] = useState<IJointType>(
    syncName(element as IJointType),
  );

  const switchMode = () => {
    setDetails(syncName(details));
    setPageDetails({
      ...pageDetails,
      existingJoint: !pageDetails.existingJoint,
      selectedWeld: "",
    });
  };

  const switchSpoolMode = () => {
    setPageDetails({
      ...pageDetails,
      existingSpool: !pageDetails.existingSpool,
      selectedSpool: "",
      spool: "",
    });
  };

  const closeAction = () => {
    setPageDetails({ ...pageDetails, mode: "read" });
    handleCancel();
  };

  const updateForm = (field: string, value: string | number) => {
    setDetails({ ...details, [field]: value });
  };
  const updateSpoolForm = (field: string, value: string | number) => {
    setPageDetails({ ...pageDetails, spool: value as string });
  };

  const setTitle = () => {
    if (pageDetails.mode === "add") {
      return elementTypeMode === "joints"
        ? t(dictionary.addJoint)
        : t(dictionary.addSpool);
    } else if (pageDetails.mode === "read") {
      return `${t(dictionary.details)} ${details!.joint_name}`;
    } else if (pageDetails.mode === "delete") {
      return `${t(dictionary.confirmDelete)} ${details!.joint_name}`;
    } else {
      return `${t(dictionary.edition)}  ${details!.joint_name}`;
    }
  };

  const setConfirmLabel = () => {
    if (pageDetails.mode === "add") {
      return t(dictionary.add);
    } else if (pageDetails.mode === "read") {
      return t(dictionary.edit);
    } else if (pageDetails.mode === "delete") {
      return t(dictionary.delete);
    } else {
      return t(dictionary.save);
    }
  };

  const setAdditionalLabel = () => {
    if (pageDetails.mode === "read") {
      return t(dictionary.delete);
    } else if (pageDetails.mode === "add") {
      return pageDetails.activeTab === "joints"
        ? t(dictionary.existingJoint)
        : t(dictionary.existingSpool);
    }
    return undefined;
  };

  const setAdditionalAction = () => {
    if (pageDetails.mode === "read") {
      return setPageDetails({ ...pageDetails, mode: "delete" });
    } else if (pageDetails.mode === "add") {
      return pageDetails.activeTab === "joints"
        ? switchMode()
        : switchSpoolMode();
    } else {
      return undefined;
    }
  };

  const addSpoolToScope = async (name: string) => {
    let idToSet = sectionID;
    if (sectionID === undefined) {
      if (pageDetails.mode === "edit") {
        idToSet = details.sectionID;
      }
    }

    const options = {
      orgID: orgID,
      projectID: projectDetails.projectID,
      spoolName: name,
      sectionID: idToSet,
    };

    await apiCall("projects/addSpoolToScope", options, (response: any) => {
      addSpool({
        spoolID: response.newSpoolId,
        spoolName: name,
        sectionID: sectionID!,
        instances: [],
      });
      setDetails({ ...details, spoolID: response.newSpoolId });
    });
  };

  const funcArray = [
    {
      id: "spoolID",
      fn: addSpoolToScope,
    },
  ];

  const elementForm = {
    action: updateForm,
    data: setFormStructure(
      setFormConfig(
        configs,
        Scopes.JointDetail,
        details as any,
        contracts,
        projectDetails,
        projects,
        true,
        sectionID,
        funcArray,
      ),
      configs,
      Scopes.JointDetail,
    ),
  };
  const spoolForm = {
    action: updateSpoolForm,
    data: [
      {
        type: "text",
        label: t(dictionary.spoolName),
        value: pageDetails.spool,
        name: "spool",
        autofocus: true,
      },
    ],
  };

  const setConfirmAction = () => {
    if (!loading) {
      if (pageDetails.activeTab === "joints") {
        if (pageDetails.mode === "add") {
          setLoading();
          if (pageDetails.existingJoint && handleAddReference) {
            handleAddReference(pageDetails.selectedWeld);
          } else {
            if (jointValidator(details as IJointType) && handleAdd) {
              handleAdd(details as IJointType);
            }
          }
        } else if (pageDetails.mode === "read") {
          setPageDetails({ ...pageDetails, mode: "edit" });
        } else if (pageDetails.mode === "edit") {
          setLoading();
          handleSave(details, true);
        } else if (pageDetails.mode === "delete") {
          setLoading();
          handleDelete(
            elementID,
            false,
            isReferencePoint(elementID, references),
          );
        }
      } else {
        setLoading();
        if (pageDetails.existingSpool) {
          handleAddSpoolReference &&
            handleAddSpoolReference(pageDetails.selectedSpool);
        } else {
          handleAddSpool && handleAddSpool(pageDetails.spool);
        }
      }
    }
  };
  const validateSeclectedWeld = (value: string) => {
    return value.length === 0;
  };
  const setDisableValidator = (
    weldDetail: IElementType,
    selected: string,
    spool: string,
  ) => {
    if (orgRole === "readOnly") return true;
    if (pageDetails.activeTab === "joints") {
      if (pageDetails.mode === "edit" || pageDetails.mode === "add") {
        return pageDetails.existingJoint
          ? validateSeclectedWeld(selected)
          : !jointValidator(weldDetail as IJointType);
      }
    } else {
      return pageDetails.existingSpool
        ? validateSeclectedWeld(pageDetails.selectedSpool)
        : pageDetails.mode === "add" && spool.trim().length === 0;
    }
    return undefined;
  };

  const onSelect = (id: string) => {
    setPageDetails({
      ...pageDetails,
      selectedWeld: id,
    });
  };
  const onSpoolSelect = (id: string) => {
    setPageDetails({
      ...pageDetails,
      selectedSpool: id,
    });
  };

  return (
    <Modal
      title={setTitle()}
      headerDivader={true}
      handleClose={closeAction}
      handleConfirm={setConfirmAction}
      handleAdditional={setAdditionalAction}
      size="md"
      submitDisabled={setDisableValidator(
        details,
        pageDetails.selectedWeld,
        pageDetails.spool,
      )}
      additionalType={pageDetails.mode === "add" ? "toggle" : "button"}
      additionalValue={
        pageDetails.activeTab === "joints"
          ? pageDetails.existingJoint
          : pageDetails.existingSpool
      }
      submitLoader={loading}
      isOpen={isOpen}
      exitOnEsc={true}
      additionDisabled={orgRole === "readOnly"}
      labels={{
        primary: setConfirmLabel(),
        secondary: t(dictionary.cancel),
        additional: setAdditionalLabel(),
      }}
    >
      <>
        {pageDetails.activeTab === "joints" &&
          (pageDetails.mode === "delete" ? (
            <Aligment
              direction="column"
              align="flex-start"
              justify="flex-start"
              gap={16}
            >
              <Text>{t(dictionary.deleteWeldHeader)}</Text>
              <DeleteElementFrame>{details!.joint_name}</DeleteElementFrame>
              <Text>
                {ifHaveReferences(details.id, references)
                  ? t(dictionary.doYouWantDeletePointWithReferences)
                  : t(dictionary.doYouWantDeletePoint)}
              </Text>
            </Aligment>
          ) : pageDetails.existingJoint ? (
            <ConnectedWeld elements={allElements} onSelect={onSelect} />
          ) : (
            <Form formData={elementForm} read={pageDetails.mode === "read"} />
          ))}
        {pageDetails.activeTab === "spools" &&
          (pageDetails.existingSpool ? (
            <ExistingSpool
              sectionID={sectionID!}
              onSpoolSelect={onSpoolSelect}
            />
          ) : (
            <Form formData={spoolForm} read={false} />
          ))}
      </>
    </Modal>
  );
};
