import React, { FC, useMemo, useState } from "react";
import { useStoreActions, useStoreState } from "../../store";
import {
  Aligment,
  SearchInput,
  Table,
} from "venice-ui";
import { dictionary } from "../../untils/dictionary";
import { getContractsIDs, isUserIsSuperAdmin, isWeldingAppDomain, t } from "../../helpers/userHelper";
import { EmptyState } from "../UI/EmptyState";
import {
  OrganizationDetailsWrapper,
  OrganizationsWrapper,
  UsersHeader,
  UsersSearch,
  UsersSearchWrapper,
} from "./organizations.style";
import { MemberDetailsPanel } from "./MemberDetailsPanel";
import { IAction } from "venice-ui/dist/types/types";
import { ManageUserInContractModal } from "../Modals/ManageUserInContractModal";
import { apiCall } from "../../untils/apiCall";
import { UserModal } from "../Modals/UserModal";
import { roleScope } from "../../definitions/organizations";
import { ITableHeaderProps } from "../../definitions/ListDefinition";
import { DeleteUserModal } from "../Modals";
import { IChangeProps } from "../../helpers/organizationHelper";
import {
  IMemberAccess,
} from "../../store/interface/organization";
import { IProject } from "../../store/interface/projects";
import { Tabs } from "../UI/Tabs";
import { ContentWrapper } from "../components";
import { DEMO_MODE } from "../../untils/const";

export const OrganizationUsers: FC = () => {
  const {
    id: orgID,
    members,
    invitations,
    contracts,
    email: orgMail,
  } = useStoreState((state) => state.organization);
  const { uid, lang,email } = useStoreState((state) => state.user.userDetails);
  const { updateUserAccess } = useStoreActions(
    (actions) => actions.organization,
  );
  const [activeTab, setActiveTab] = useState("users");
  const [selectedMemberID, setSelectedMemberID] = useState("");

  const [searchValue, setSearchValue] = useState("");

  const showed = useMemo(() => {
    const search = searchValue.toLowerCase();

    return {
      members: members.filter(
        (item) =>
          item.status !== "deleted" &&
          item.email.toLowerCase().includes(search),
      ),
      invitations: invitations.filter((item) =>
        item.user.toLowerCase().includes(search),
      ),
      deleted: members.filter(
        (item) =>
          item.status === "deleted" &&
          item.email.toLowerCase().includes(search),
      ),
    };
  }, [members, invitations, searchValue]);

  const [deleteUserDetails, setDeleteUserDetails] = useState({
    show: false,
    memberID: "",
    loader: false,
  });

  const [assignModal, setAssignModal] = useState({
    show: false,
    memberID: "",
  });

  const [editModal, toogleEditModal] = useState({
    show: false,
    memberID: "",
  });
  const { removeInvitation, removeUser, setEmail } = useStoreActions(
    (actions) => actions.organization,
  );
  const { updateProjects } = useStoreActions((actions) => actions.projects);

  const { updateContractsInUser } = useStoreActions((actions) => actions.user);

  const showAssignModal = (memberID?: string) => {
    if (memberID) {
      setAssignModal({
        show: true,
        memberID: memberID,
      });
    }
  };
  const hideAssignModal = () => {
    setAssignModal({
      show: false,
      memberID: "",
    });
  };
  const showEditModal = (id?: string) => {
    toogleEditModal({
      show: true,
      memberID: id!,
    });
  };
  const hideEditModal = () => {
    toogleEditModal({
      show: false,
      memberID: "",
    });
  };

  const showDeleteModal = (id?: string) => {
    setDeleteUserDetails({
      show: true,
      memberID: id || "",
      loader: false,
    });
  };

  const hideDeleteModal = () => {
    setDeleteUserDetails({
      show: false,
      memberID: "",
      loader: false,
    });
  };

  const cancelInvitation = async (id?: string) => {
    const options = {
      invitationID: id,
    };
    await apiCall("organization/cancelInvitation", options, (response: any) => {
      removeInvitation(id!);
    });
  };
  const handleMemeberDelete = async (newEmail?: string) => {
    setDeleteUserDetails({
      ...deleteUserDetails,
      loader: true,
    });
    const options = {
      userID: deleteUserDetails.memberID,
      contractsIDs: getContractsIDs(uid!, contracts),
      lang: lang,
      newEmail: newEmail ? newEmail : "",
    };
    await apiCall("user/deleteUser", options, (response: any) => {
      removeUser(deleteUserDetails.memberID);
      setDeleteUserDetails({
        ...deleteUserDetails,
        loader: false,
      });
      if (newEmail !== "") {
        setEmail(newEmail!);
      }
      hideDeleteModal();
    });
  };

  const handleContractManagement = async (changes: IChangeProps[]) => {
    const options = {
      orgID: orgID,
      changes: changes,
    };

    await apiCall(
      "organization/updateMemberInContract",
      options,
      (response: any) => {
        updateUserAccess(changes);
        changes.forEach((_change) => {
          if (_change.id === uid) {
            // update access in user => contracts
            updateContractsInUser({
              changes: _change.access as IMemberAccess[],
              contracts: response.contracts,
            });

            //update projects in projects => projects
            updateProjects({
              changes: _change.access as IMemberAccess[],
              projects: response.projects as IProject[],
            });
          }
        });
        hideAssignModal();
      },
    );
  };

  const usersHeaders: ITableHeaderProps[] = [
    {
      name: t(dictionary.email),
      valueSource: "email",
    },
    {
      name: t(dictionary.role),
      valueSource: "role",
      scope: roleScope,
    },
  ];

  const moreActions: IAction[] = [
    {
      label: t(dictionary.manageAccess),
      action: showAssignModal,
    },
    {
      label: t(dictionary.editUser),
      action: showEditModal,
      disableID: uid,
    },
    {
      label: t(dictionary.deleteUser),
      action: showDeleteModal,
      disableID: uid,
      disabled : DEMO_MODE && !isUserIsSuperAdmin(uid!, members),
    },
  ];

  const invitationsHeaders: ITableHeaderProps[] = [
    {
      name: t(dictionary.email),
      valueSource: "user",
    },
    {
      name: t(dictionary.role),
      valueSource: "role",
      scope: roleScope,
    },
    {
      name: t(dictionary.dateSent),
      valueSource: "date",
      date: true,
    },
  ];

  const moreInvitationsctions: IAction[] = [
    {
      label: t(dictionary.cancelInvitation),
      action: cancelInvitation,
    },
  ];

  const tabs = [
    {
      value: "users",
      label: t(dictionary.users) + ` (${showed.members.length})`,
    },
    {
      value: "deleted",
      label: t(dictionary.deleted) + ` (${showed.deleted.length})`,
    },
    {
      value: "invitations",
      label: t(dictionary.invitations) + ` (${showed.invitations.length})`,
    },
  ];
  const handleSearchChange = (value: string) => {
    setSearchValue(value);
  };

  const handleChangeTab = (value: string) => {
    setActiveTab(value);
    setSelectedMemberID('')
  }
  return (
    <>
      {members.length > 0 ? (
        <Aligment>
          <OrganizationsWrapper>
            <UsersHeader>
              <Tabs
                activeValue={activeTab}
                tabs={tabs}
                onClick={(value) => handleChangeTab(value)}
              />
              <UsersSearchWrapper>
                <UsersSearch>
                  <SearchInput
                    placeholder={t(dictionary.search)}
                    handleSearch={handleSearchChange}
                  />
                </UsersSearch>
              </UsersSearchWrapper>
            </UsersHeader>

            <ContentWrapper componentHeight="calc(100vh - 20.6rem)">
              {activeTab === "users" &&
                (showed.members.length > 0 ? (
                  <Table
                    headers={usersHeaders}
                    elements={showed.members}
                    onRowClick={setSelectedMemberID}
                    sortable={true}
                    selectable={true}
                    moreActions={moreActions}
                    tableHeight="calc(100vh - 20.6rem)"
                    tableWrapperHeight="calc(100vh - 20.6rem)"
                    searchable={false}
                  />
                ) : (
                  <EmptyState title={t(dictionary.noUserToShow)} />
                ))}
              {activeTab === "deleted" &&
                (showed.deleted.length > 0 ? (
                  <Table
                    headers={usersHeaders}
                    elements={showed.deleted}
                    onRowClick={setSelectedMemberID}
                    sortable={true}
                    selectable={true}
                    moreActions={moreActions}
                    tableHeight="calc(100vh - 20.6rem)"
                    tableWrapperHeight="calc(100vh - 20.6rem)"
                    searchable={false}
                  />
                ) : (
                  <EmptyState title={t(dictionary.noDeletedUsers)} />
                ))}
              {activeTab === "invitations" &&
                (showed.invitations.length > 0 ? (
                  <Table
                    headers={invitationsHeaders}
                    elements={showed.invitations}
                    sortable={false}
                    selectable={false}
                    moreActions={moreInvitationsctions}
                    tableHeight="calc(100vh - 20.6rem)"
                    tableWrapperHeight="calc(100vh - 20.6rem)"
                    searchable={false}
                  />
                ) : (
                  <EmptyState title={t(dictionary.noInvitations)} />
                ))}
            </ContentWrapper>
          </OrganizationsWrapper>
          <OrganizationDetailsWrapper>
            <MemberDetailsPanel
              memberID={selectedMemberID}
              handleAssing={showAssignModal}
              handleEdit={showEditModal}
              handleDelete={showDeleteModal}
            />
          </OrganizationDetailsWrapper>
        </Aligment>
      ) : (
        <EmptyState title={t(dictionary.noUsersInOrg)} />
      )}
      {assignModal.show && (
        <ManageUserInContractModal
          memberID={assignModal.memberID}
          handleCancel={hideAssignModal}
          handleConfirm={handleContractManagement}
          isOpen={assignModal.show}
        />
      )}
      {editModal.show && (
        <UserModal
          handleClose={hideEditModal}
          memberID={editModal.memberID}
          isOpen={editModal.show}
        />
      )}
      {deleteUserDetails.show && (
        <DeleteUserModal
          handleCancel={hideDeleteModal}
          handleDelete={handleMemeberDelete}
          loader={deleteUserDetails.loader}
          userID={deleteUserDetails.memberID}
          isOpen={deleteUserDetails.show}
        />
      )}
    </>
  );
};
