import React, { FC, useEffect, useMemo, useRef, useState } from "react";
import { ItemListContent, TableWrapper } from "./ItemList.styles";
import { Table, Toggle } from "venice-ui";
import { useStoreActions, useStoreState } from "../../store";
import { getPointsForList } from "../../helpers/pdfHelpers";
import { PointModal } from "../Modals/PointModal";
import {
  getElement,
  getReferenceElement,
  serializeSaveSourceElement,
  setOptionsSaveElement,
} from "../Section/sectionModel";
import { IElementType } from "../../definitions/element";
import { IAddtionalElements } from "../../definitions/additional";
import { useParams } from "react-router-dom";
import { apiCall } from "../../untils/apiCall";
import { IJointType } from "../../definitions/joint";
import { ifHaveReferences } from "../../helpers/weldHelpers";
import { Scopes } from "../../definitionsNew/fields";
import { getConfig, setHeaders } from "../../definitionsNew/setFieldsHelper";
import { serializeListSection } from "../../definitionsNew/serializaConfigs";
import { EmptyState } from "../UI/EmptyState";
import { dictionary } from "../../untils/dictionary";
import { getMonthNames, t, weekDaysShortName } from "../../helpers/userHelper";

interface IItemList {
  showJointWeld: boolean;
  toogleShowJointWeld: (mode: boolean) => void;
}

export const ItemList: FC<IItemList> = ({
  showJointWeld,
  toogleShowJointWeld,
}) => {
  const { sectionID, projectID } = useParams();
  const [loading, setLoading] = useState(false);
  const { elements, references, sections, spools } = useStoreState(
    (state) => state.projectDetails.projectDetails,
  );
  const { projects } = useStoreState((state) => state.projects);
  const { orgID, configs } = useStoreState((state) => state.user.userDetails);

  const [pointDetails, updatePointDetails] = useState({
    show: false,
    id: "",
    mode: "read",
    isRefernce: false,
  });
  const [loader, setLoader] = useState(false);
  const closeLoader = () => {
    setLoader(false);
  };

  const { updateElement, removeElement, removeReference, clearReferences } =
    useStoreActions((actions) => actions.projectDetails);

  const points = getPointsForList(
    elements,
    sectionID!,
    references,
    showJointWeld,
  );

  const handleClick = (id: string) => {
    const clicked = points.find((item) => item.id === id);
    updatePointDetails({
      show: true,
      id: id,
      mode: "read",
      isRefernce:
        "sourceElementID" in clicked! && clicked.sourceElementID !== undefined,
    });
  };

  const hidePointModal = () => {
    updatePointDetails({
      show: false,
      id: "",
      mode: "read",
      isRefernce: false,
    });
  };

  const saveElement = async (element: IElementType | IAddtionalElements) => {
    const options = setOptionsSaveElement(
      element as IElementType,
      orgID,
      projectID!,
    );
    await apiCall("projects/saveElement", options, (response: any) => {
      closeLoader();
      updateElement(element as IElementType);
      hidePointModal();
    });
  };

  const saveReference = async (element: IElementType | IAddtionalElements) => {
    const reference = element as IElementType;
    const sourceElement = getElement(
      reference.sourceElementID as string,
      elements,
    );
    const referenceElement = serializeSaveSourceElement(
      element as IJointType,
      sourceElement as IJointType,
    );
    saveElement(referenceElement as IElementType);
  };

  const deleteElement = async (
    id: string,
    mapElement: boolean,
    isReference: boolean,
  ) => {
    await apiCall(
      "projects/removeElement",
      {
        orgID: orgID,
        projectID: projectID,
        elementID: id,
        mapElement: mapElement,
        isReference: isReference,
      },
      (response: any) => {
        setLoading(false);
        if (isReference) {
          removeReference(id);
        } else {
          if (ifHaveReferences(id, references)) {
            clearReferences(id);
          }
          removeElement(id);
        }
        hidePointModal();
      },
    );
  };
  const tablePoints = useMemo(() => {
    return serializeListSection(points, projectID!, projects, sections, spools);
  }, [points, configs]);


  const tableHeaders = useMemo(() => {
    return setHeaders(getConfig(configs, Scopes.ListSection), "show");
  }, [configs]);

  const headerExtraContent = useMemo(() => {
    return (
      <Toggle
        handleClick={() => toogleShowJointWeld(!showJointWeld)}
        value={showJointWeld}
        size="sm"
        label={t(dictionary.showConnectingWelds)}
        labelPosition="left"
        labelInversed={true}
      />
    );
  }, [showJointWeld, toogleShowJointWeld]);
  return (
    <>
      {tablePoints.length > 0 ? (
        <Table
          headers={tableHeaders}
          elements={tablePoints}
          onRowClick={handleClick}
          selectable={false}
          sortable={true}
          filtrable={true}
          pagination={true}
          tableHeight="calc(100vh - 19.6rem)"
          tableWrapperHeight="calc(100vh - 14s.6rem)"
          filterLabels={{
            title: t(dictionary.filters),
            close: t(dictionary.close),
            confirm: t(dictionary.confirm),
            trigger: t(dictionary.filters),
            clearAll: t(dictionary.resetFilters),
            clear: t(dictionary.clear),
          }}
          paginationLabel={{
            label: t(dictionary.itemPerPage),
          }}
          calendarLabels={{
            placeholder: t(dictionary.selectDate),
          }}
          calendarLocaleLabels={{
            months: getMonthNames(),
            weekdaysShort: weekDaysShortName(),
            firstDayOfWeek: 1,
          }}
          headerExtraContent={headerExtraContent}
          searchInputPlaceholder={t(dictionary.weldSection)}
          noResultsText={t(dictionary.noResultsFound)}
        />
      ) : (
        <EmptyState
          title={t(dictionary.emptyStateSectionListTitle)}
          actionLabel={t(dictionary.addSection)}
        />
      )}
      {pointDetails.show && (
        <PointModal
          handleCancel={hidePointModal}
          elementID={pointDetails.id}
          element={
            pointDetails.isRefernce
              ? getReferenceElement(pointDetails.id, references, elements)
              : getElement(pointDetails.id, elements)
          }
          handleDelete={deleteElement}
          handleSave={pointDetails.isRefernce ? saveReference : saveElement}
          modalMode="read"
          fullSpec={true}
          loading={loader}
          setLoading={closeLoader}
          isOpen={pointDetails.show}
          elementTypeMode={"joints"}
        />
      )}
    </>
  );
};
