import React, { FC, useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Modal, Card, Table, Form, Icon, Aligment } from "venice-ui";
import { apiCall } from "../../untils/apiCall";
import { Content, ContentFull, ContentWrapper } from "../components";
import { LoadingContent } from "../layouts/Loading";

import { IAction } from "venice-ui/dist/types/types";
import {
  getContactsNames,
  getContractName,
  getProjectParams,
} from "../../helpers/projectHelper";
import { EmptyState } from "../UI/EmptyState";
import { dictionary } from "../../untils/dictionary";
import { useStoreActions, useStoreState } from "../../store";
import { getMonthNames, t, weekDaysShortName } from "../../helpers/userHelper";
import { IProject } from "../../store/interface/projects";
import { EmptyContracts } from "./EmptyContracts";
import { MEMBER_ROLE } from "../../definitions/organizations";
import {
  getConfig,
  setFormConfig,
  setHeaders,
  setObjectState,
} from "../../definitionsNew/setFieldsHelper";
import { Scopes } from "../../definitionsNew/fields";
import {
  serializeProject,
  serliazizeProjectsList,
} from "../../definitionsNew/serializaConfigs";
import { TScopesType } from "../../untils/const";
import { DeleteProjectModal, EditProjectModal } from "../Modals";

interface IPageProps {
  loading: boolean;
  actionLoader: boolean;
}

const Projects: FC = () => {
  const navigate = useNavigate();

  const { setProjects, addProject: addProjectToStore } = useStoreActions(
    (actions) => actions.projects,
  );

  const { uid, contracts, orgID, orgRole, email, lang, configs } =
    useStoreState((state) => state.user.userDetails);
  const { projects } = useStoreState((state) => state.projects);
  const { projectDetails } = useStoreState((state) => state.projectDetails);

  const [modal, toogleModal] = useState(false);
  const [deleteProjectModal, toggleDeleteProjectModal] = useState({
    show: false,
    id: "",
    projectName: "",
  });

  const [pageProps, updatePageProps] = useState<IPageProps>({
    loading: true,
    actionLoader: false,
  });

  const [project, setProject] = useState<Record<string, string | number>>(
    setObjectState(configs, Scopes.AddProjectForm),
  );

  const [selctedProject, setSelectedProject] = useState<TScopesType>({
    show: false,
    id: "",
    name: "",
    contract: "",
  });

  const cancelEditProjectModal = () => {
    setSelectedProject({
      show: false,
      id: "",
      name: "",
      contract: "",
    });
  };

  const openEditProjectModal = (projectID?: string) => {
    if (projectID) {
      const projectParams = getProjectParams(projects, projectID);
      setSelectedProject({
        show: true,
        id: projectID,
      });
    }
  };

  const getProjects = async () => {
    const userAccess = contracts.map((item) => {
      return {
        id: item.contractID,
        projects: item.projects,
      };
    });
    const options = {
      orgID: orgID,
      userAccess: userAccess,
      lang: lang,
    };
    await apiCall("projects/getProjects", options, (response: any) => {
      const userProjects = getContactsNames(response.projects, contracts);
      setProjects(userProjects);
      updatePageProps({
        ...pageProps,
        loading: false,
      });
    });
  };
  useEffect(() => {
    getProjects();
  }, []);

  const selectProject = async (id: string) => {
    navigate(`/project/${id}`);
  };

  const addProject = async () => {
    if (!pageProps.actionLoader && !validationNewProject()) {
      updatePageProps({ ...pageProps, actionLoader: true });
      const options = {
        project: serializeProject(project, uid as string),
        orgID: orgID,
      };

      await apiCall("projects/createProject", options, (response: any) => {
        options.project.author = email;
        addProjectToStore({
          projectID: response.newProjectID as string,
          contractName: getContractName(
            options.project.contractID as string,
            contracts,
          ),
          ...(options.project as IProject),
        });
        updatePageProps({
          ...pageProps,
          actionLoader: false,
        });
        hideModal();
      });
    }
  };
  const hideModal = () => {
    toogleModal(false);
  };
  const showModal = () => {
    setProject({ ...project, projectName: "", contractName: "" });
    toogleModal(true);
  };

  const updateForm = (field: string, value: string | number) => {
    setProject({ ...project, [field]: value });
  };

  const validationNewProject = () => {
    const name = project.projectName as string;
    return name.trim().length === 0 || project.contractName === "";
  };

  const newProjectForm = {
    action: updateForm,
    data: setFormConfig(
      configs,
      Scopes.AddProjectForm,
      project,
      contracts,
      projectDetails,
      projects,
      false,
      undefined,
      [],
      true,
    ),
  };

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

  const tableProjects = useMemo(() => {
    return serliazizeProjectsList(projects);
  }, [projects, configs]);

  const showDeleteProjectModal = (id?: string) => {
    if (id) {
      toggleDeleteProjectModal({
        show: true,
        id: id,
        projectName: getProjectParams(projects, id).projectName,
      });
    }
  };

  const hideDeleteProjectModal = () => {
    toggleDeleteProjectModal({
      show: false,
      id: "",
      projectName: "",
    });
  };

  const moreActions: IAction[] = [
    {
      label: t(dictionary.changeName),
      action: openEditProjectModal,
      disabled: orgRole === "readOnly",
    },
    {
      label: t(dictionary.deleteProject),
      action: showDeleteProjectModal,
      disabled: orgRole === "readOnly",
    },
  ];

  if (pageProps.loading) {
    return (
      <ContentFull>
        <LoadingContent />
      </ContentFull>
    );
  }

  if (contracts.length === 0) {
    return <EmptyContracts isAdmin={orgRole === MEMBER_ROLE.admin} />;
  }

  return (
    <Content>
      <Card
        title={t(dictionary.projects)}
        actionLabel={t(dictionary.addProject)}
        handleClick={showModal}
        shadow={false}
        componentHeight="calc(100vh - 4rem)"
        actionDisabled={orgRole === "readOnly"}
        noVerticalPadding={true}
      >
        {tableProjects.length > 0 ? (
          <ContentWrapper componentHeight="calc(100vh - 9.6rem)">
            <Table
              headers={headers}
              elements={tableProjects}
              onRowClick={selectProject}
              selectable={false}
              sortable={true}
              filtrable={true}
              pagination={true}
              moreActions={moreActions}
              tableHeight="calc(100vh - 14.6rem)"
              tableWrapperHeight="calc(100vh - 9.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,
              }}
              searchInputPlaceholder={t(dictionary.searchProject)}
              noResultsText={t(dictionary.noResultsFound)}
            ></Table>
          </ContentWrapper>
        ) : (
          <EmptyState
            title={t(dictionary.emptyStateProjectTitle)}
            actionLabel={t(dictionary.addProject)}
            action={() => showModal()}
          />
        )}
      </Card>
      {modal && (
        <Modal
          title={t(dictionary.addProject)}
          handleClose={() => hideModal()}
          handleConfirm={() => addProject()}
          headerDivader={true}
          submitDisabled={validationNewProject()}
          labels={{
            primary: t(dictionary.addProject),
            secondary: t(dictionary.cancel),
          }}
          isOpen={modal}
          exitOnEsc={true}
        >
          <Form formData={newProjectForm} />
        </Modal>
      )}
      {selctedProject.show && (
        <EditProjectModal
          onClose={cancelEditProjectModal}
          projectID={selctedProject.id as string}
          show={selctedProject.show as boolean}
        />
      )}
      {deleteProjectModal.show && (
        <DeleteProjectModal
          handleCancel={() => hideDeleteProjectModal()}
          id={deleteProjectModal.id}
          name={deleteProjectModal.projectName}
          isOpen={deleteProjectModal.show}
        />
      )}
    </Content>
  );
};

export default Projects;
