import { useState } from 'react';
import { useMutation, useQuery } from 'react-query';
import { useNavigate, useParams } from 'react-router';
import { useSearchParams } from 'react-router-dom';

import { useModal } from '@material-hu/hooks/useModal';
import { useServerPagination } from '@material-hu/hooks/useServerPagination';
import {
  IconFileSpreadsheet,
  IconListCheck,
  IconPlus,
  IconTrash,
  IconUserMinus,
  IconUserPlus,
} from '@material-hu/icons/tabler';
import Alert from '@material-hu/mui/Alert';
import AlertTitle from '@material-hu/mui/AlertTitle';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuMenuList from '@material-hu/components/composed-components/MenuList';
import CardContainer from '@material-hu/components/design-system/CardContainer';
import Dialog from '@material-hu/components/design-system/Dialog';
import Dropdown from '@material-hu/components/design-system/Dropdown';
import List from '@material-hu/components/design-system/List';
import ListItem from '@material-hu/components/design-system/List/components/ListItem';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';
import HuTable from '@material-hu/components/design-system/Table';
import HuTableBody from '@material-hu/components/design-system/Table/components/TableBody';
import HuTableCell from '@material-hu/components/design-system/Table/components/TableCell';
import HuTableContainer from '@material-hu/components/design-system/Table/components/TableContainer';
import HuTableHead from '@material-hu/components/design-system/Table/components/TableHead';
import HuTableRow from '@material-hu/components/design-system/Table/components/TableRow';

import useAuth from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import usePermissions from 'src/hooks/usePermissions';
import {
  getGroupDetails,
  getGroupMembers,
  removeMember,
  updateMemberRole,
} from 'src/services/groupsService';
import { GroupMemberRoles } from 'src/types/groups';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { LogEvents, logEvent } from 'src/utils/logging';
import { UserPermissions } from 'src/utils/permissions';
import { Pagination } from 'src/utils/tableUtils';
import { formatUTCDate } from 'src/utils/timeUtils';

import { CriteriaProvider } from 'src/components/Audience/criteriaContext';
import CenteredCircularProgress from 'src/components/CircularProgress';
import UserInfo from 'src/components/UserInfo';

import { groupsKeys } from '../queries';
import { groupRoutes } from '../routes';
import {
  isSourceSegmentation,
  memberIsFromGroupCreatorInstance,
  userIsGroupAdmin,
} from '../utils';

import { InviteExternalMembersDrawer } from './inviteExternalMembersDrawer';
import ManageMembers from './ManageMembers';

const { ADMIN, REGULAR } = GroupMemberRoles;

const MembersList = () => {
  const [manageIsOpen, setManageIsOpen] = useState(false);
  const [isAlertOpen, setIsAlertOpen] = useState(true);
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
  const [inviteExternalUsersDrawerOpen, setInviteExternalUsersDrawerOpen] =
    useState(false);
  const { t } = useLokaliseTranslation(['group', 'general']);
  const navigate = useNavigate();
  const { user, instance } = useAuth();
  const { enqueueSnackbar } = useHuSnackbar();
  const showGeneralError = useGeneralError();

  const { id: groupIdParam } = useParams();
  const [searchParams] = useSearchParams();
  const groupId = searchParams.get('groupId');

  const { hasAll: canManageMultiCompanyGroups } = usePermissions([
    UserPermissions.MANAGE_MULTICOMPANY_GROUPS,
  ]);

  const id = groupId || groupIdParam;

  const { paginationController, pagination, Searchbar, query } =
    useServerPagination({
      labelRowsPerPage: t('general:ROWS_PER_PAGE'),
      limitOptions: [5, 10],
    });

  const paginationAndOrder: Pagination = {
    ...pagination,
    q: query || undefined,
  };

  const { data, isLoading, refetch } = useQuery(
    groupsKeys.members(id!, paginationAndOrder),
    () => getGroupMembers(id!, paginationAndOrder),
    {
      select: r => r.data,
      enabled: !!id,
    },
  );

  const { data: groupData } = useQuery(
    groupsKeys.groupDetails(id!),
    () => getGroupDetails(id!),
    {
      enabled: !!id,
      select: r => r.data,
      refetchOnMount: false,
    },
  );

  const isGroupAdmin =
    !!groupData && !!user && userIsGroupAdmin(groupData, user);

  const isMultiCompany = groupData?.isMultiCompany ?? false;

  const { mutate: removeUser } = useMutation(
    (userId: number) => {
      if (!id) throw new Error('Group ID is required');
      return removeMember(id, userId);
    },
    {
      onSuccess: (resp, removedUserId) => {
        refetch();
        logEvent(LogEvents.GROUPS_USER_REMOVED, {
          userId: user?.id,
          groupId: id,
          removedUserId,
        });
        enqueueSnackbar({
          title: t('group:remove_member_success_web'),
          variant: 'success',
        });
      },
      onError: err => {
        showGeneralError(err);
      },
    },
  );

  const { mutate: updateUserRole } = useMutation(
    ({ userId, ...body }: { userId: number; role: GroupMemberRoles }) => {
      if (!id) throw new Error('Group ID is required');
      return updateMemberRole(id, userId, body);
    },
    {
      onSuccess: (resp, { userId: updatedUserId, role: newRole }) => {
        refetch();
        logEvent(LogEvents.GROUPS_USER_ROLE_CHANGED, {
          userId: user?.id,
          groupId: id,
          updatedUserId,
          newRole,
        });
        enqueueSnackbar({
          title: t('group:role_updated_success'),
          variant: 'success',
        });
      },
      onError: err => {
        showGeneralError(err);
      },
    },
  );

  const {
    modal: deleteMemberModal,
    showModal: showDeleteMemberModal,
    closeModal: closeDeleteMemberModal,
  } = useModal(({ userId }: { userId: number }) => (
    <Dialog
      title={t('group:remove_member_modal_title_web')}
      textBody={t('group:remove_member_modal_body_web')}
      primaryButtonProps={{
        children: t('group:remove_member_modal_confirm_web'),
        onClick: () => {
          removeUser(userId);
          closeDeleteMemberModal();
        },
      }}
      secondaryButtonProps={{
        children: t('group:cancel'),
        onClick: closeDeleteMemberModal,
      }}
      onClose={closeDeleteMemberModal}
    />
  ));

  const isAdmin = (role: GroupMemberRoles) => role === ADMIN;

  const {
    modal: updateRoleModal,
    showModal: showUpdateRoleModal,
    closeModal: closeUpdateRoleModal,
  } = useModal(
    ({
      userId,
      userRole,
      newRole,
    }: {
      userId: number;
      userRole: GroupMemberRoles;
      newRole: GroupMemberRoles;
    }) => (
      <Dialog
        title={t('group:update_role_modal_title', { context: userRole })}
        textBody={t('group:update_role_modal_body', { context: userRole })}
        primaryButtonProps={{
          children: t('group:update_role_modal_confirm', {
            context: userRole,
          }),
          onClick: () => {
            updateUserRole({ userId, role: newRole });
            closeUpdateRoleModal();
          },
        }}
        secondaryButtonProps={{
          children: t('group:cancel'),
          onClick: closeUpdateRoleModal,
        }}
        onClose={closeUpdateRoleModal}
      />
    ),
  );

  const handleUpdateMemberRole = (userId: number, userRole: GroupMemberRoles) =>
    showUpdateRoleModal({
      userId,
      userRole,
      newRole: isAdmin(userRole) ? REGULAR : ADMIN,
    });

  const handleAddMembers = () => setManageIsOpen(true);

  const dropdownOptions = [
    {
      icon: IconUserPlus,
      label: t('group:manage_members'),
      onClick: handleAddMembers,
    },
    {
      icon: IconFileSpreadsheet,
      label: t('group:group_bulk_upload'),
      onClick: () => navigate(groupRoutes.membersBulkUpload(id!)),
    },
    ...(isMultiCompany &&
    canManageMultiCompanyGroups &&
    isGroupAdmin &&
    memberIsFromGroupCreatorInstance(instance?.id, groupData?.instanceId)
      ? [
          {
            icon: IconListCheck,
            label: t('group:invite_external_members'),
            onClick: () => {
              setIsDropdownOpen(false);
              setInviteExternalUsersDrawerOpen(true);
            },
          },
        ]
      : []),
  ];

  const members = data?.items || [];

  const count = data?.count || 0;

  const pageTitle = t('group:collaborators');

  const handleCloseManage = () => setManageIsOpen(false);

  if (manageIsOpen)
    return (
      <CriteriaProvider>
        <ManageMembers
          onClose={
            groupId ? () => navigate(groupRoutes.base()) : handleCloseManage
          }
        />
      </CriteriaProvider>
    );

  return (
    <>
      <Stack sx={{ gap: 2 }}>
        {deleteMemberModal}
        {updateRoleModal}
        <Stack sx={{ flexDirection: 'row', justifyContent: 'space-between' }}>
          <Typography
            variant="globalL"
            fontWeight="fontWeightSemiBold"
          >
            {pageTitle}
          </Typography>
          <Dropdown
            open={isDropdownOpen}
            onOpen={() => setIsDropdownOpen(true)}
            onClose={() => setIsDropdownOpen(false)}
            buttonProps={{
              startIcon: <IconPlus />,
            }}
            buttonVariant="primary"
            label={t('group:manage_members')}
          >
            <List>
              {dropdownOptions.map(option => (
                <ListItem
                  avatar={{ Icon: option.icon }}
                  key={option.label}
                  text={{ title: option.label }}
                  onClick={option.onClick}
                />
              ))}
            </List>
          </Dropdown>
        </Stack>
        {isAlertOpen && (
          <Alert
            severity="info"
            onClose={() => setIsAlertOpen(false)}
          >
            <AlertTitle>{t('group:manage_members_alert_title')}</AlertTitle>
            {t('group:manage_members_alert_info')}
          </Alert>
        )}
        <CardContainer fullWidth>
          <Searchbar
            placeholder={t('group:members_query_placeholder')}
            sx={{ p: 1 }}
          />
          {isLoading && (
            <CenteredCircularProgress
              centered
              sx={{ my: 4 }}
            />
          )}
          {!isLoading && members?.length !== 0 && (
            <HuTableContainer>
              <HuTable sx={{ minWidth: 650, tableLayout: 'fixed' }}>
                <HuTableHead>
                  <HuTableRow headerRow>
                    <HuTableCell headerCell>
                      <Typography
                        variant="globalS"
                        fontWeight="fontWeightSemiBold"
                      >
                        {t('group:member_name')}
                      </Typography>
                    </HuTableCell>
                    {isMultiCompany && (
                      <HuTableCell headerCell>
                        <Typography
                          variant="globalS"
                          fontWeight="fontWeightSemiBold"
                        >
                          {t('group:member_community')}
                        </Typography>
                      </HuTableCell>
                    )}
                    <HuTableCell
                      headerCell
                      sx={{ width: '150px' }}
                    >
                      <Typography
                        variant="globalS"
                        fontWeight="fontWeightSemiBold"
                      >
                        {t('group:member_role')}
                      </Typography>
                    </HuTableCell>
                    <HuTableCell headerCell>
                      <Typography
                        variant="globalS"
                        fontWeight="fontWeightSemiBold"
                      >
                        {t('group:member_mail')}
                      </Typography>
                    </HuTableCell>
                    <HuTableCell
                      headerCell
                      sx={{ width: '170px' }}
                    >
                      <Typography
                        variant="globalS"
                        fontWeight="fontWeightSemiBold"
                      >
                        {t('group:member_joined_date')}
                      </Typography>
                    </HuTableCell>
                    <HuTableCell
                      headerCell
                      sx={{ width: '80px' }}
                    />
                  </HuTableRow>
                </HuTableHead>
                <HuTableBody>
                  {members.map(member => (
                    <HuTableRow key={member.userId}>
                      <HuTableCell
                        component="th"
                        scope="row"
                      >
                        <UserInfo
                          showEmail={false}
                          showEmployeeInternalId={false}
                          user={
                            member?.user
                              ? {
                                  ...member.user,
                                  employeeInternalId: '',
                                }
                              : null
                          }
                          nameMaxWidth={225}
                          usernameProps={{ noWrap: false }}
                        />
                      </HuTableCell>
                      {isMultiCompany && (
                        <HuTableCell align="left">
                          <Typography
                            noWrap
                            title={member.instanceName ?? undefined}
                            sx={{ maxWidth: 200 }}
                          >
                            {member.instanceName || '-'}
                          </Typography>
                        </HuTableCell>
                      )}
                      <HuTableCell align="left">
                        {t(member.role.toLowerCase())}
                      </HuTableCell>
                      <HuTableCell align="left">
                        <Typography
                          noWrap
                          title={member.user?.email ?? undefined}
                          sx={{ maxWidth: 200 }}
                        >
                          {member.user?.email}
                        </Typography>
                      </HuTableCell>
                      <HuTableCell
                        component="th"
                        scope="row"
                      >
                        {formatUTCDate(member.createdAt)}
                      </HuTableCell>
                      <HuTableCell align="left">
                        <HuMenuList
                          options={[
                            {
                              onClick: () =>
                                handleUpdateMemberRole(
                                  member.userId,
                                  member.role,
                                ),
                              Icon: isAdmin(member.role)
                                ? IconUserMinus
                                : IconUserPlus,
                              title: t('group:update_role', {
                                context: member.role.toLowerCase(),
                              }),
                            },
                            {
                              onClick: () =>
                                showDeleteMemberModal({
                                  userId: member.userId,
                                }),
                              Icon: IconTrash,
                              title: t('group:remove_member'),
                              disabled: isSourceSegmentation(member.source),
                            },
                          ]}
                        />
                      </HuTableCell>
                    </HuTableRow>
                  ))}
                </HuTableBody>
              </HuTable>
            </HuTableContainer>
          )}
          {members?.length === 0 && !isLoading && (
            <Stack
              justifyContent="center"
              alignItems="center"
              py={6}
              mb={3}
            >
              <Typography
                variant="globalM"
                fontWeight="fontWeightSemiBold"
              >
                {t(query ? 'group:no_members' : 'group:empty_members')}
              </Typography>
              <Typography
                variant="globalS"
                color="textColors.neutralTextLighter"
                mt={1}
              >
                {t(query ? 'group:no_members_sub' : 'group:empty_members_sub')}
              </Typography>
            </Stack>
          )}
          {members?.length !== 0 && paginationController(count)}
        </CardContainer>
      </Stack>
      <InviteExternalMembersDrawer
        groupId={id!}
        isOpen={inviteExternalUsersDrawerOpen}
        onClose={() => setInviteExternalUsersDrawerOpen(false)}
      />
    </>
  );
};

export default MembersList;
