import { FC, useEffect, useMemo, useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { useQuery } from 'react-query';

import { AxiosResponse } from 'axios';

import { IconInfoCircle, IconSearch } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuAccordion from '@material-hu/components/design-system/Accordion';
import HuInputClassic from '@material-hu/components/design-system/Inputs/Classic';
import RadioButton from '@material-hu/components/design-system/RadioButton/RadioButton';
import HuSkeleton from '@material-hu/components/design-system/Skeleton';

import { queryClient } from 'src/config/react-query';
import { regionKeys } from 'src/pages/dashboard/Regions/queries';
import * as regionService from 'src/services/regionsService';
import { Region } from 'src/types/regions';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { PaginatedResponse } from 'src/utils/tableUtils';

import ListEmptyState from '../../components/ListEmptyState';
import { kioskFields, TerminalFields } from '../form';

const regionSkeleton = Array(5)
  .fill(0)
  .map((_, index) => (
    <Stack
      key={index}
      sx={{
        alignItems: 'center',
        flexDirection: 'row',
        backgroundColor: ({ palette }) => palette.new.background.layout.default,
        borderRadius: 1,
        gap: 1,
        p: 2,
        height: 74,
      }}
    >
      <HuSkeleton
        variant="rounded"
        height={22.4}
        width={200}
      />
    </Stack>
  ));

type Props = {
  selectedSite: { id: number; name: string } | null;
  setSelectedSite: (site: { id: number; name: string } | null) => void;
};

const KioskSitesDrawer: FC<Props> = ({ selectedSite, setSelectedSite }) => {
  const { t } = useLokaliseTranslation('time_tracker');
  const [searches, setSearches] = useState<{ [regionId: string]: string }>({});
  const [expandedRegion, setExpandedRegion] = useState<number | null>(null);
  const form = useFormContext<TerminalFields>();
  const selectedSiteId = form.watch(kioskFields.general.siteId);
  const cachedRegions = queryClient.getQueryData<
    AxiosResponse<PaginatedResponse<Region>>
  >(regionKeys.all());
  const { data: regionData, isLoading } = useQuery(
    regionKeys.all(),
    regionService.getRegions,
    {
      select: response => response.data,
      staleTime: 5 * 60 * 1000,
      refetchOnMount: false,
      placeholderData: cachedRegions,
    },
  );

  const sortedRegions = useMemo(() => {
    if (!regionData?.items) return [];

    return regionData.items
      .filter(r => (r.sitesCount ?? 0) > 0)
      .sort((a, b) => {
        const aHasSite = a.sites?.some(s => s.id === selectedSite?.id) ?? false;
        const bHasSite = b.sites?.some(s => s.id === selectedSite?.id) ?? false;

        if (aHasSite && !bHasSite) return -1;
        if (!aHasSite && bHasSite) return 1;

        return a.title.localeCompare(b.title);
      });
  }, [regionData, selectedSiteId]);

  useEffect(() => {
    if (!regionData?.items || !selectedSite) return;
    // If there's only one region, expand it automatically
    if (regionData?.items.length === 1) {
      setExpandedRegion(regionData.items[0].id);
      return;
    }
    const regionWithSite = regionData.items.find(region =>
      region.sites.some(site => site.id === selectedSite.id),
    );
    if (regionWithSite) {
      setExpandedRegion(regionWithSite.id);
    }
  }, [regionData, selectedSite]);

  return (
    <Stack sx={{ height: '100%', gap: 2 }}>
      <Typography
        variant="globalM"
        sx={{ fontWeight: 'fontWeightSemiBold' }}
      >
        {t('sites')}
      </Typography>
      {isLoading && regionSkeleton}
      {!isLoading &&
        sortedRegions.length > 0 &&
        sortedRegions.map(region => {
          const searchValue = searches[region.id] || '';
          const filteredSites = region.sites.filter(site =>
            site.name.toLowerCase().includes(searchValue.toLowerCase()),
          );
          return (
            <HuAccordion
              key={region.id}
              title={region.title}
              expanded={expandedRegion === region.id}
              onChange={() =>
                setExpandedRegion(
                  expandedRegion === region.id ? null : region.id,
                )
              }
              sx={{
                backgroundColor: ({ palette }) =>
                  palette.new.background.layout.default,
                '& .MuiAccordionSummary-root': {
                  minHeight: 74,
                },
                boxShadow: 'none',
              }}
              customDetail={
                <>
                  <HuInputClassic
                    value={searchValue}
                    placeholder={t('regions_sites:search_site')}
                    startAdornment={<IconSearch />}
                    hasCounter={false}
                    onChange={value => {
                      setSearches(prev => ({
                        ...prev,
                        [region.id]: value,
                      }));
                    }}
                  />
                  {filteredSites.length > 0 && (
                    <Stack
                      sx={{
                        mt: 1,
                        maxHeight: 265,
                        overflowY: 'auto',
                        pr: 1,
                        gap: 2,
                        p: 1.5,
                        borderRadius: 2,
                        border: '1px solid',
                        borderColor: ({ palette }) => palette.grey[200],
                        backgroundColor: ({ palette }) =>
                          palette.background.default,
                      }}
                    >
                      {filteredSites.map(site => (
                        <RadioButton
                          key={site.id}
                          label={site.name}
                          isActive={selectedSite?.id === site.id}
                          value={site.id.toString()}
                          onClick={() => setSelectedSite(site)}
                          sx={{
                            flexShrink: 0,
                          }}
                        />
                      ))}
                    </Stack>
                  )}
                  {filteredSites.length === 0 && (
                    <ListEmptyState
                      title={t('general:no_results_for_search')}
                      description={t('general:try_again_with_other_words')}
                      icon={IconInfoCircle}
                      sx={{ mt: 1 }}
                    />
                  )}
                </>
              }
            />
          );
        })}
    </Stack>
  );
};

export default KioskSitesDrawer;
