import { type FC, useEffect, useMemo, useState } from 'react';
import {
  FormProvider,
  useForm,
  useFormContext,
  type DeepPartial,
} from 'react-hook-form';

import { useClientPagination } from '@material-hu/hooks/useClientPagination';
import { useDrawerV2 } from '@material-hu/hooks/useDrawerV2';
import { useModal } from '@material-hu/hooks/useModal';
import { IconPlus } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';
import CardContainer from '@material-hu/components/design-system/CardContainer';
import Dialog from '@material-hu/components/design-system/Dialog';
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 HuTableLoader from '@material-hu/components/design-system/Table/components/TableLoader';
import HuTableRow from '@material-hu/components/design-system/Table/components/TableRow';

import { useAuth } from 'src/contexts/JWTContext';
import { type User } from 'src/types/user';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';

import MemberHeaderCell, { type Header } from './MemberHeaderCell';
import MemberRow from './MemberRow';
import SelectMembers from './SelectMembers';

const PAGE_SIZE = 10;

const ManageMembers: FC = () => {
  const { t } = useTranslation(['group']);
  const { user } = useAuth();
  const form = useFormContext<{ members: User[] }>();
  const { members } = form.watch();
  const [loadedCount, setLoadedCount] = useState(PAGE_SIZE);

  const addMembers = (users: User[]) => {
    form.setValue('members', [...members, ...users]);
  };
  const removeUser = (userId: string) => {
    form.setValue(
      'members',
      members.filter(member => String(member.id) !== String(userId)),
    );
  };

  const { Searchbar, paginatedItems: filteredItems } = useClientPagination({
    labelRowsPerPage: t('ROWS_PER_PAGE'),
    limitOptions: [10000],
    items: members,
    queriedKeys: [
      'id',
      'email',
      'fullName',
      'firstName',
      'lastName',
      'profilePicture',
      'createdAt',
    ],
  });

  useEffect(() => {
    setLoadedCount(Math.min(PAGE_SIZE, filteredItems.length));
  }, [filteredItems.length]);

  const paginatedItems = useMemo(
    () => filteredItems.slice(0, loadedCount),
    [filteredItems, loadedCount],
  );

  const handleLoadMore = () => {
    setLoadedCount(prev => Math.min(prev + PAGE_SIZE, filteredItems.length));
  };

  const handleScrollToTop = () => {
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const headers: Header[] = [
    {
      id: 'FULL_NAME',
      label: t('group:member_name_web'),
      sort: false,
      enabled: true,
    },
    {
      id: 'ROLE',
      label: t('group:member_role_web'),
      sort: false,
      enabled: true,
    },
    {
      id: 'MAIL',
      label: t('group:member_mail_web'),
      sort: false,
      enabled: true,
    },
    {
      id: 'CREATED_AT',
      label: t('group:member_joined_date_web'),
      sort: false,
      enabled: true,
    },
  ];

  const filteredHeaders = headers.filter(header => header.enabled);
  const showFilterEmptyState = filteredItems.length === 0 && members.length > 0;

  const formDrawer = useForm<{ selectedItems: User[] }>({
    defaultValues: {
      selectedItems: members ?? [],
    } as DeepPartial<{ selectedItems: User[] }>,
  });

  const submit = (values: { selectedItems: User[] }) => {
    addMembers(values.selectedItems);
    formDrawer.reset();
    closeDrawer();
  };

  const {
    showDrawer: showAddMemberDrawer,
    drawer: addMemberDrawer,
    closeDrawer,
  } = useDrawerV2(({ closeDrawer: closeDrawerFn }) => ({
    title: t('group:individual_users_title'),
    children: (
      <SelectMembers
        previousUserIds={members.map(member => Number(member.id))}
      />
    ),
    primaryButtonProps: {
      children: t('general:select'),
      onClick: formDrawer.handleSubmit(submit),
    },
    secondaryButtonProps: {
      children: t('general:cancel'),
      onClick: () => closeDrawerFn(),
    },
    hasBackButton: false,
    onClose: closeDrawerFn,
  }));

  const {
    modal: deleteMemberModal,
    showModal: showDeleteMemberModal,
    closeModal: closeDeleteMemberModal,
  } = useModal<{ userId: string }>(
    ({ userId }) => (
      <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('general:cancel'),
          onClick: closeDeleteMemberModal,
        }}
        onClose={closeDeleteMemberModal}
      />
    ),
    { fullWidth: true },
  );

  const renderTableContent = () => {
    if (showFilterEmptyState) {
      return (
        <HuTableRow>
          <HuTableCell colSpan={filteredHeaders.length + 1}>
            <Stack
              sx={{
                alignItems: 'center',
                gap: 2,
                p: 2,
              }}
            >
              <Typography
                variant="globalM"
                fontWeight="fontWeightSemiBold"
              >
                {t('group:no_members_found')}
              </Typography>
            </Stack>
          </HuTableCell>
        </HuTableRow>
      );
    }

    return paginatedItems.map(member => (
      <MemberRow
        key={member.id}
        member={member}
        currentUserId={user?.id}
        onRemove={userId => showDeleteMemberModal({ userId })}
        t={t}
      />
    ));
  };

  const AddMembersButton = (
    <Button
      variant="outlined"
      onClick={() => showAddMemberDrawer({})}
      sx={{
        mt: 2,
      }}
      startIcon={<IconPlus size={16} />}
    >
      {t('group:add_members_web')}
    </Button>
  );

  return (
    <>
      <Stack
        sx={{ flexDirection: 'row', justifyContent: 'space-between', mb: 2 }}
      >
        <Stack>
          <Typography
            variant="globalL"
            fontWeight="fontWeightSemiBold"
          >
            {t('group:members')}
          </Typography>
          <Typography variant="globalS">
            {t('group:members_description')}
          </Typography>
        </Stack>
        {members.length !== 0 && AddMembersButton}
      </Stack>
      <CardContainer fullWidth>
        {members.length === 0 && (
          <Stack sx={{ alignItems: 'center', py: 3, gap: 2 }}>
            <Typography
              variant="globalM"
              fontWeight="fontWeightSemiBold"
            >
              {t('group:no_members_title')}
            </Typography>
            <Typography variant="body1">
              {t('group:no_members_body')}
            </Typography>
            {AddMembersButton}
          </Stack>
        )}
        {members.length !== 0 && (
          <Stack sx={{ gap: 3 }}>
            <Stack
              sx={{
                p: 2,
                backgroundColor: theme =>
                  theme.palette.new.background.layout.default,
                borderRadius: theme => theme.shape.borderRadiusL,
              }}
            >
              <Searchbar
                placeholder={t('general:search')}
                sx={{
                  backgroundColor: theme => theme.palette.background.paper,
                  '.MuiFormHelperText-root': {
                    display: 'none',
                  },
                }}
              />
            </Stack>
            <HuTableContainer>
              <HuTable
                sx={{
                  minWidth: 650,
                  tableLayout: 'fixed',
                }}
              >
                <MemberHeaderCell headers={filteredHeaders} />
                <HuTableBody>{renderTableContent()}</HuTableBody>
              </HuTable>
            </HuTableContainer>
            {filteredItems.length > 0 && (
              <HuTableLoader
                loadedCount={loadedCount}
                totalCount={filteredItems.length}
                onLoadMore={handleLoadMore}
                onScrollToTop={handleScrollToTop}
              />
            )}
          </Stack>
        )}
      </CardContainer>
      {deleteMemberModal}
      <FormProvider {...formDrawer}>{addMemberDrawer}</FormProvider>
    </>
  );
};

export default ManageMembers;
