import { type FC, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { IconButton, Stack, Typography } from '@mui/material';
import { IconChevronLeft, IconChevronRight } from '@tabler/icons-react';
import {
  addMonths,
  lastDayOfMonth,
  nextMonday,
  nextSunday,
  previousMonday,
} from 'date-fns';

import Dropdown from '../../design-system/Dropdown';
import RadioButton from '../../design-system/RadioButton/RadioButton';

import MonthPickerPopover from './components/MonthPickerPopover';
import {
  type PeriodButton,
  type WeekMonthSelectorProps,
  WeekMonthPeriod,
} from './types';

const WeekMonthSelector: FC<WeekMonthSelectorProps> = ({
  fromDate,
  toDate,
  handleFromChange,
  handleToChange,
  dateFormatter,
  initialPeriod = WeekMonthPeriod.WEEKLY,
  onPeriodChange,
  onCurrentMonthClick,
  sx,
}) => {
  const { t } = useTranslation('material_hu_only');
  const [periodType, setPeriodType] = useState(initialPeriod);
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);

  const periodButtons: PeriodButton[] = [
    { type: WeekMonthPeriod.WEEKLY, text: t('date_period_selector.weekly') },
    { type: WeekMonthPeriod.MONTHLY, text: t('date_period_selector.monthly') },
  ];

  const dateLabel = {
    [WeekMonthPeriod.WEEKLY]: t('date_period_selector.date_from_to', {
      from: dateFormatter(fromDate).toUpperCase(),
      to: dateFormatter(toDate).toUpperCase(),
    }),
    [WeekMonthPeriod.MONTHLY]: dateFormatter(
      fromDate,
      'MMMM yyyy',
    ).toUpperCase(),
  }[periodType];

  const handlePeriodChange = (newPeriod: WeekMonthPeriod) => {
    setPeriodType(newPeriod);
    onPeriodChange?.(newPeriod);
    setIsDropdownOpen(false);

    if (newPeriod === WeekMonthPeriod.WEEKLY) {
      const weekStart =
        fromDate.getDay() === 1 ? fromDate : previousMonday(fromDate);
      handleFromChange(weekStart);
      handleToChange(nextSunday(weekStart));
    } else {
      handleFromChange(
        new Date(fromDate.getFullYear(), fromDate.getMonth(), 1),
      );
      handleToChange(lastDayOfMonth(fromDate));
    }
  };

  const handleNext = () => {
    if (periodType === WeekMonthPeriod.WEEKLY) {
      const weekStart = nextMonday(fromDate);
      handleFromChange(weekStart);
      handleToChange(nextSunday(weekStart));
    } else {
      const nextMonth = addMonths(fromDate, 1);
      handleFromChange(
        new Date(nextMonth.getFullYear(), nextMonth.getMonth(), 1),
      );
      handleToChange(lastDayOfMonth(nextMonth));
    }
  };

  const handlePrevious = () => {
    if (periodType === WeekMonthPeriod.WEEKLY) {
      const weekStart = previousMonday(fromDate);
      handleFromChange(weekStart);
      handleToChange(nextSunday(weekStart));
    } else {
      const prevMonth = addMonths(fromDate, -1);
      handleFromChange(
        new Date(prevMonth.getFullYear(), prevMonth.getMonth(), 1),
      );
      handleToChange(lastDayOfMonth(prevMonth));
    }
  };

  const handleLabelClick = (event: React.MouseEvent<HTMLElement>) => {
    if (periodType === WeekMonthPeriod.MONTHLY) {
      setAnchorEl(event.currentTarget);
    }
  };

  const handleMonthSelect = (date: Date) => {
    handleFromChange(new Date(date.getFullYear(), date.getMonth(), 1));
    handleToChange(lastDayOfMonth(date));
    setAnchorEl(null);
  };

  return (
    <Stack
      sx={{
        alignItems: 'stretch',
        justifyContent: 'center',
        flexDirection: 'row',
        gap: 3,
        ...sx,
      }}
    >
      <Dropdown
        label={t(`date_period_selector.${periodType.toLowerCase()}`)}
        position="center"
        open={isDropdownOpen}
        onOpen={() => setIsDropdownOpen(true)}
        onClose={() => setIsDropdownOpen(false)}
        sx={{ '.MuiButtonBase-root': { height: '100%' } }}
      >
        {periodButtons.map(button => (
          <RadioButton
            key={button.type}
            label={button.text}
            isActive={periodType === button.type}
            onClick={() => handlePeriodChange(button.type)}
            stackSx={{ p: 2 }}
          />
        ))}
      </Dropdown>

      <Stack
        sx={{
          alignItems: 'center',
          alignSelf: 'center',
          backgroundColor: ({ palette }) =>
            palette.new.background.elements.default,
          border: ({ palette }) =>
            `1px solid ${palette.new.border.neutral.default}`,
          borderRadius: 1,
          flexDirection: 'row',
          justifyContent: 'space-between',
          gap: 3,
          px: 1.5,
          py: 1,
          width: 336,
        }}
      >
        <IconButton
          title={t('date_period_selector.previous')}
          onClick={e => {
            e.stopPropagation();
            handlePrevious();
          }}
          sx={{ p: 0 }}
          disableRipple
        >
          <IconChevronLeft />
        </IconButton>

        <Typography
          variant="globalS"
          onClick={handleLabelClick}
          role={periodType === WeekMonthPeriod.MONTHLY ? 'button' : undefined}
          tabIndex={periodType === WeekMonthPeriod.MONTHLY ? 0 : undefined}
          onKeyDown={
            periodType === WeekMonthPeriod.MONTHLY
              ? e => {
                  if (e.key === 'Enter' || e.key === ' ')
                    handleLabelClick(
                      e as unknown as React.MouseEvent<HTMLElement>,
                    );
                }
              : undefined
          }
          sx={{
            cursor:
              periodType === WeekMonthPeriod.MONTHLY ? 'pointer' : 'default',
            '&:hover':
              periodType === WeekMonthPeriod.MONTHLY
                ? { textDecoration: 'underline' }
                : {},
          }}
        >
          {dateLabel}
        </Typography>

        <MonthPickerPopover
          anchorEl={anchorEl}
          open={Boolean(anchorEl)}
          onClose={() => setAnchorEl(null)}
          selectedDate={fromDate}
          onMonthSelect={handleMonthSelect}
          onCurrentMonthClick={onCurrentMonthClick}
        />

        <IconButton
          title={t('date_period_selector.next')}
          onClick={e => {
            e.stopPropagation();
            handleNext();
          }}
          sx={{ p: 0 }}
          disableRipple
        >
          <IconChevronRight />
        </IconButton>
      </Stack>
    </Stack>
  );
};

export default WeekMonthSelector;
