import { FC, useState } from "react";
import { IAction, Table } from "venice-ui";
import { useStoreActions, useStoreState } from "../../store";
import { IUserDemoDetails } from "../../store/interface/demo";
import { dictionary } from "../../untils/dictionary";
import { t } from "../../helpers/userHelper";
import { apiCall } from "../../untils/apiCall";
import {
  ArchiveDemoUserModal,
  AssingOrganizationForDemoUserModal,
  DeleteDemoUserModal,
  InfoModal,
} from "../Modals";
import { FinishTestsModal } from "../Modals";

type DemoDateField =
  | "reguestDate"
  | "invitationDate"
  | "demoStartDate"
  | "demoEndDate";
type DemoTableUser = Omit<IUserDemoDetails, DemoDateField> &
  Partial<Record<DemoDateField, number | null | undefined>>;

export const DemoUsers: FC = () => {
  const users = useStoreState((state) => state.demo.users);
  const organizations = useStoreState((state) => state.demo.organizations);
  const { uid } = useStoreState((state) => state.user.userDetails);
  const removeInvitationFromDemoOrganization = useStoreActions(
    (actions) => actions.demo.removeInvitationFromDemoOrganization,
  );
  const dateFields = [
    "reguestDate",
    "invitationDate",
    "demoStartDate",
    "demoEndDate",
  ] as DemoDateField[];
  const tableUsers: DemoTableUser[] = users.map((user) => {
    const demoOrganization = organizations.find(
      (organization) => organization.orgID === user.demoOrganization,
    );
    const tableUser: DemoTableUser = {
      ...user,
      demoOrganization: demoOrganization?.orgName || "",
    };

    dateFields.forEach((field) => {
      if (tableUser[field] === 0 || tableUser[field] === null) {
        tableUser[field] = undefined;
      }
    });

    return tableUser;
  });

  const getDemoUserById = (id?: string) => {
    if (!id) {
      return undefined;
    }

    return users.find((item) => item.id === id || item.email === id);
  };

  const [userToAssign, setUserToAssign] = useState<IUserDemoDetails | null>(
    null,
  );
  const [userToFinish, setUserToFinish] = useState<{
    orgID?: string;
    userID?: string;
  } | null>(null);
  const [userToArchive, setUserToArchive] =
    useState<IUserDemoDetails | null>(null);
  const [userToDelete, setUserToDelete] =
    useState<IUserDemoDetails | null>(null);

  const [infoBox, setInfoBox] = useState({
    isOpen: false,
    content: "",
  });

  const assignOrganization = (id?: string) => {
    const user = getDemoUserById(id);
    if (user) {
      setUserToAssign(user);
    }
  };

  const removeInvitation = async (id?: string) => {
    const user = getDemoUserById(id);
    const isInvited =
      typeof user?.status === "string" &&
      user.status.trim().toLowerCase() === "invaited";

    if (!user || !isInvited) {
      return;
    }

    const organization = organizations.find(
      (item) => item.orgID === user.demoOrganization,
    );
    const userID = user.id || user.email;

    if (!uid || !organization?.orgID || !userID) {
      return;
    }

    try {
      await apiCall(
        "demoManagment/removeInvitationFromDemoOrganization",
        {
          uid,
          orgID: organization.orgID,
          userID,
        },
        () => {
          removeInvitationFromDemoOrganization({
            orgID: organization.orgID,
            userID,
          });
        },
      );
    } catch (error) {
      return;
    }
  };

  const finishTests = (id?: string) => {
    const user = getDemoUserById(id);
    if (!user) {
      return;
    }

    const organization = organizations.find(
      (item) => item.orgID === user.demoOrganization,
    );

    const hasActiveDemo =
      user.status?.trim().toLowerCase() === "busy" ||
      organization?.status?.trim().toLowerCase() === "busy";

    if (hasActiveDemo && organization?.orgID && (user.id || user.email)) {
      setUserToFinish({
        orgID: organization.orgID,
        userID: user.id || user.email,
      });
    } else {
      setInfoBox({
        isOpen: true,
        content: t(dictionary.organizationNoTests),
      });
    }
  };

  const archiveUser = (id?: string) => {
    const user = getDemoUserById(id);
    if (user) {
      setUserToArchive(user);
    }
  };

  const deleteUser = (id?: string) => {
    const user = getDemoUserById(id);
    if (user) {
      setUserToDelete(user);
    }
  };

  const moreActions: IAction[] = [
    {
      label: t(dictionary.assignOrganizationUserAction),
      action: assignOrganization,
    },
    {
      label: t(dictionary.removeInvitationAction),
      action: removeInvitation,
    },
    {
      label: t(dictionary.finishTestAction),
      action: finishTests,
    },
    {
      label: t(dictionary.archiveUserAction),
      action: archiveUser,
    },
    {
      label: t(dictionary.deleteUserAction),
      action: deleteUser,
    },
  ];

  const headers = [
    {
      name: t(dictionary.email),
      valueSource: "email",
      filterType: "text" as const,
    },
    {
      name: t(dictionary.status),
      valueSource: "status",
      filterType: "select" as const,
    },
    {
      name: t(dictionary.demoOrganization),
      valueSource: "demoOrganization",
      filterType: "select" as const,
    },
    {
      name: t(dictionary.name),
      valueSource: "name",
      filterType: "text" as const,
    },
    {
      name: t(dictionary.surname),
      valueSource: "surname",
      filterType: "text" as const,
    },
    {
      name: t(dictionary.company),
      valueSource: "orgName",
      filterType: "select" as const,
    },
    {
      name: t(dictionary.requestDate),
      valueSource: "reguestDate",
      date: true,
      filterType: "date" as const,
    },
    {
      name: t(dictionary.invitationDate),
      valueSource: "invitationDate",
      date: true,
      filterType: "date" as const,
    },
    {
      name: t(dictionary.demoStartDate),
      valueSource: "demoStartDate",
      date: true,
      filterType: "date" as const,
    },
    {
      name: t(dictionary.demoEndDate),
      valueSource: "demoEndDate",
      date: true,
      filterType: "date" as const,
    },
    {
      name: t(dictionary.language),
      valueSource: "lang",
      filterType: "select" as const,
    },
  ];

  return (
    <>
      <Table
        headers={headers}
        elements={tableUsers}
        pagination
        pageSize={10}
        searchable
        sortable
        filtrable
        selectable={false}
        moreActions={moreActions}
        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),
        }}
        emptyStateText={t(dictionary.noDemoUsers)}
      />
      {userToAssign && (
        <AssingOrganizationForDemoUserModal
          isOpen={userToAssign !== null}
          onClose={() => setUserToAssign(null)}
          user={userToAssign}
        />
      )}
      {userToFinish && (
        <FinishTestsModal
          isOpen={userToFinish !== null}
          onClose={() => setUserToFinish(null)}
          orgID={userToFinish.orgID}
          userID={userToFinish.userID}
          label={userToFinish.userID || userToFinish.orgID}
        />
      )}
      {userToArchive && (
        <ArchiveDemoUserModal
          isOpen={userToArchive !== null}
          user={userToArchive}
          onClose={() => setUserToArchive(null)}
        />
      )}
      {userToDelete && (
        <DeleteDemoUserModal
          isOpen={userToDelete !== null}
          user={userToDelete}
          onClose={() => setUserToDelete(null)}
        />
      )}
      {infoBox.isOpen && (
        <InfoModal
          isOpen={infoBox.isOpen}
          onClose={() => setInfoBox({ isOpen: false, content: "" })}
          content={infoBox.content}
        />
      )}
    </>
  );
};
