import { useEffect, useMemo } from 'react';
import { useInView } from 'react-intersection-observer';
import { useInfiniteQuery } from 'react-query';

import CloseIcon from '@material-hu/icons/material/Close';
import { IconSearch } from '@material-hu/icons/tabler';
import CircularProgress from '@material-hu/mui/CircularProgress';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuAvatar from '@material-hu/components/design-system/Avatar';
import HuCheckbox from '@material-hu/components/design-system/Checkbox/Checkbox';
import HuInputClassic from '@material-hu/components/design-system/Inputs/Classic';

import { getUserListSubordinatesForVacations } from 'src/services/vacations';
import { type MeUser, type User } from 'src/types/user';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getFullName, getInitials } from 'src/utils/userUtils';

import { goalsKeys } from '../../../queries';
import { isResponsibleOptionDisabled } from '../../../utils';

import { RESPONSIBLE_SUBORDINATES_PAGE_SIZE } from './constants';

type ResponsibleDrawerBodyProps = {
  userId: number;
  debouncedSearch: string;
  isDrawerOpen: boolean;
  isNewGoal: boolean;
  loggedUser: MeUser | null;
  draftUsers: User[];
  setDraftUsers: React.Dispatch<React.SetStateAction<User[]>>;
  searchInput: string;
  onSearchInputChange: (value: string) => void;
};

export function ResponsibleDrawerBody({
  userId,
  debouncedSearch,
  isDrawerOpen,
  isNewGoal,
  loggedUser,
  draftUsers,
  setDraftUsers,
  searchInput,
  onSearchInputChange,
}: ResponsibleDrawerBodyProps) {
  const { t } = useLokaliseTranslation('goals');

  const {
    data: infiniteData,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isLoading,
  } = useInfiniteQuery(
    goalsKeys.responsibleSubordinates(userId),
    ({ pageParam = 1 }) =>
      getUserListSubordinatesForVacations(
        userId,
        '',
        pageParam,
        RESPONSIBLE_SUBORDINATES_PAGE_SIZE,
      ),
    {
      getNextPageParam: (lastPage, allPages) => {
        const items = lastPage?.data as User[] | undefined;
        if (
          !Array.isArray(items) ||
          items.length < RESPONSIBLE_SUBORDINATES_PAGE_SIZE
        ) {
          return undefined;
        }
        return allPages.length + 1;
      },
      enabled: isDrawerOpen && Boolean(userId),
    },
  );

  const flatUsers = useMemo(() => {
    const pages = infiniteData?.pages ?? [];
    const fromApi = pages.flatMap(page => {
      const payload = page?.data as User[] | undefined;
      return Array.isArray(payload) ? payload : [];
    });
    const merged = loggedUser
      ? [...fromApi, loggedUser as unknown as User]
      : fromApi;
    const byId = new Map<number, User>();
    for (const u of merged) {
      if (u?.id != null) {
        byId.set(u.id, u);
      }
    }
    return Array.from(byId.values());
  }, [infiniteData?.pages, loggedUser]);

  const filteredUsers = useMemo(() => {
    if (!debouncedSearch.trim()) return flatUsers;
    const q = debouncedSearch.toLowerCase().trim();
    return flatUsers.filter(u => {
      const nameLower = getFullName(u).toLowerCase();
      const emailLower = (u.email ?? '').toLowerCase();
      return nameLower.includes(q) || emailLower.includes(q);
    });
  }, [debouncedSearch, flatUsers]);

  const { ref: loadMoreRef, inView } = useInView({ threshold: 0 });

  useEffect(() => {
    if (inView && hasNextPage && !isFetchingNextPage) {
      fetchNextPage();
    }
  }, [inView, hasNextPage, isFetchingNextPage, fetchNextPage]);

  const toggleUser = (user: User) => {
    if (!loggedUser) return;
    const disabled = isResponsibleOptionDisabled({
      isNewGoal,
      currentResponsible: draftUsers,
      option: user,
      loggedUser,
    });
    if (disabled) return;

    if (isNewGoal) {
      setDraftUsers(prev => {
        const exists = prev.some(u => u.id === user.id);
        if (exists) {
          return prev.filter(u => u.id !== user.id);
        }
        return [...prev, user];
      });
    } else {
      setDraftUsers(prev => {
        if (prev[0]?.id === user.id) {
          return [];
        }
        return [user];
      });
    }
  };

  const isUserChecked = (user: User) => draftUsers.some(u => u.id === user.id);

  const isRowDisabled = (user: User) => {
    if (!loggedUser) return false;
    return isResponsibleOptionDisabled({
      isNewGoal,
      currentResponsible: draftUsers,
      option: user,
      loggedUser,
    });
  };

  return (
    <Stack
      sx={{
        gap: 2,
        flex: 1,
        minHeight: 0,
        height: '100%',
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      <HuInputClassic
        hasCounter={false}
        value={searchInput}
        onChange={onSearchInputChange}
        placeholder={t('search_by_name')}
        aria-label={t('search_by_name')}
        startAdornment={<IconSearch size={24} />}
        sx={{
          '& .MuiInputBase-root': {
            minHeight: 56,
          },
        }}
      />
      <Typography
        variant="globalXS"
        fontWeight="fontWeightSemiBold"
        color="new.text.neutral.brand"
      >
        {t('new.responsible_scope', {
          count: draftUsers.length,
        })}
      </Typography>
      {draftUsers.length > 0 ? (
        <Stack
          direction="row"
          flexWrap="wrap"
          gap={0.5}
        >
          {draftUsers.map(user => {
            const chipName = getFullName(user);
            return (
              <Stack
                key={user.id}
                direction="row"
                alignItems="center"
                sx={{
                  gap: 0.5,
                  pl: 1,
                  pr: 0.5,
                  py: 0.25,
                  borderRadius: 1,
                  border: ({ palette }) =>
                    `1px solid ${palette.new.border.neutral.brand}`,
                  bgcolor: 'new.action.background.brand.default',
                  maxWidth: '100%',
                }}
              >
                <Typography
                  variant="globalXS"
                  fontWeight="fontWeightSemiBold"
                  color="new.text.neutral.brand"
                  sx={{
                    overflow: 'hidden',
                    textOverflow: 'ellipsis',
                    whiteSpace: 'nowrap',
                    maxWidth: 200,
                  }}
                >
                  {chipName}
                </Typography>
                <IconButton
                  size="small"
                  aria-label={t('new.responsible_chip_remove', {
                    name: chipName,
                  })}
                  onClick={() => {
                    toggleUser(user);
                  }}
                  sx={{ p: 0.25, color: 'new.text.neutral.brand' }}
                >
                  <CloseIcon sx={{ fontSize: 16 }} />
                </IconButton>
              </Stack>
            );
          })}
        </Stack>
      ) : null}
      <Stack
        sx={{
          gap: 0,
          flex: 1,
          minHeight: 0,
          overflowY: 'auto',
          pr: 0.5,
        }}
      >
        {isLoading && (
          <Stack
            alignItems="center"
            py={4}
          >
            <CircularProgress size={32} />
          </Stack>
        )}
        {!isLoading &&
          filteredUsers.map(user => {
            const name = getFullName(user);
            const email = user.email ?? '';
            const disabledRow = isRowDisabled(user);
            const checked = isUserChecked(user);

            return (
              <Stack
                key={user.id}
                direction="row"
                alignItems="center"
                gap={1.5}
                py={1.5}
                sx={{
                  borderBottom: ({ palette }) =>
                    `1px solid ${palette.new.border.neutral.default}`,
                }}
              >
                <HuCheckbox
                  aria-label={email ? `${name}, ${email}` : name}
                  checked={checked}
                  disabled={disabledRow}
                  onChange={() => {
                    toggleUser(user);
                  }}
                  sx={{ m: 0, alignItems: 'center' }}
                />
                <HuAvatar
                  src={user.profilePicture ?? undefined}
                  alt=""
                  text={getInitials(name)}
                  sx={{ width: 40, height: 40, flexShrink: 0 }}
                />
                <Stack sx={{ minWidth: 0, flex: 1, gap: 0.25 }}>
                  <Typography
                    variant="globalS"
                    fontWeight="fontWeightSemiBold"
                    color="new.text.neutral.default"
                  >
                    {name}
                  </Typography>
                  {email ? (
                    <Typography
                      variant="globalXS"
                      color="new.text.neutral.lighter"
                    >
                      {email}
                    </Typography>
                  ) : null}
                </Stack>
              </Stack>
            );
          })}
        {!isLoading && filteredUsers.length === 0 && (
          <Typography
            variant="globalS"
            color="new.text.neutral.lighter"
          >
            {t('team.no_collaborators_search')}
          </Typography>
        )}
        <Stack
          ref={loadMoreRef}
          sx={{ height: 1 }}
        />
        {isFetchingNextPage ? (
          <Stack
            alignItems="center"
            py={2}
          >
            <CircularProgress size={24} />
          </Stack>
        ) : null}
      </Stack>
    </Stack>
  );
}
