import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns";
import { Paginated } from "../../../../services/Paginated";
import { MakeGeneralIdRef } from "../../../../utils/GeneralIdRef";
import UserRolesTable from "./UserRolesTable";
import roleService, { RoleUser } from "../serrvices/rolesService";
import Button, { ButtonType } from "../../../../components/common/Button";
import Loading from "../../../../components/common/Loading";
import Permission from "../../../../components/common/Permission";

const initialPagedData: Paginated<RoleUser> = {
  page: 1,
  pageSize: 10,
  count: 0,
  totalPages: 1,
  data: [],
};

interface UserRoleEditorProps {
  role: any | undefined;
}

const UserRoleEditor: React.FC<UserRoleEditorProps> = ({ role }) => {
  const { t } = useTranslation();
  const [loaded, setLoaded] = useState(false);
  const [pagedData, setPagedData] =
    useState<Paginated<RoleUser>>(initialPagedData);
  const [sortColumn, setSortColumn] = useState<Column<RoleUser>>({
    key: "name",
    label: t("Name"),
    order: "asc",
  });
  const [filters, setFilters] = useState<Map<string, string>>(
    () => new Map<string, string>(),
  );

  const roleGeneralIdRef = useMemo(
    () => MakeGeneralIdRef(role?.id, role?.guid),
    [role?.id, role?.guid],
  );

  const getRoleUsers = useCallback(
    async (
      page: number,
      pageSize: number,
      nextSortColumn: Column<RoleUser>,
      nextFilters: Map<string, string>,
    ) => {
      const pagedDataResult = await roleService.getRoleUsers(
        page,
        pageSize,
        nextSortColumn.key,
        nextSortColumn.order === "asc",
        roleGeneralIdRef,
        nextFilters,
      );
      if (pagedDataResult) {
        setLoaded(true);
        setFilters(nextFilters);
        setPagedData(pagedDataResult);
        setSortColumn(nextSortColumn);
      } else {
        setLoaded(false);
      }
    },
    [roleGeneralIdRef],
  );

  useEffect(() => {
    const loadInitial = async () => {
      await getRoleUsers(
        initialPagedData.page,
        initialPagedData.pageSize,
        sortColumn,
        new Map<string, string>(),
      );
    };

    void loadInitial();
  }, [getRoleUsers, role?.id, sortColumn]);

  const changePage = async (page: number, pageSize: number) => {
    await getRoleUsers(page, pageSize, sortColumn, filters);
  };

  const onSort = async (nextSortColumn: Column<RoleUser>) => {
    const { page, pageSize } = pagedData;
    await getRoleUsers(page, pageSize, nextSortColumn, filters);
  };

  const onSearch = async (name: string, value: string) => {
    const { page, pageSize } = pagedData;
    const nextFilters = new Map(filters);
    nextFilters.set(name, value);

    await getRoleUsers(page, pageSize, sortColumn, nextFilters);
  };

  const onDelete = async (user?: RoleUser) => {
    const userId = MakeGeneralIdRef(user?.id, user?.guid);

    const response = await roleService.deleteRoleUser(userId, roleGeneralIdRef);
    if (response) {
      await changePage(pagedData.page, pagedData.pageSize);
    }
  };

  const addLink = "editRole/" + role?.id + "/addUserToRole";

  return (
    <Loading loaded={loaded}>
      <Permission privilegeKey="AddRoleUser">
        <div>
          <Button
            id="btnAddUserToRole"
            buttonType={ButtonType.primary}
            to={addLink}
          >
            {t("Add")}
          </Button>
        </div>
      </Permission>
      <hr />
      <UserRolesTable
        data={pagedData}
        sortColumn={sortColumn}
        onChangePage={changePage}
        onSort={onSort}
        onSearch={onSearch}
        onDelete={onDelete}
      />
    </Loading>
  );
};

export default UserRoleEditor;
