import { format, parseISO } from 'date-fns';

import { IconPlayerPlay, IconSquare } from '@material-hu/icons/tabler';
import Divider from '@material-hu/mui/Divider';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import Alert from '@material-hu/components/design-system/Alert';
import Button from '@material-hu/components/design-system/Buttons/Button';
import CardContainer from '@material-hu/components/design-system/CardContainer';
import Pills from '@material-hu/components/design-system/Pills';

import { type UseClockingInfoReturn } from 'src/components/dashboard/hooks/timeTracking';
import { useAuth } from 'src/contexts/JWTContext';
import { getCurrentLocale } from 'src/utils/locale';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { useTimeTrack } from '../../hooks/useTimeTrack';
import {
  ACTIVITY,
  CONSUMPTION,
  truncateTimeToHHMM,
  getTimeOffPillLabel,
  isPeriodTimeOff,
} from '../../constants';
import TimeTrackSkeleton from './TimeTrackSkeleton';

type TimeTrackProps = {
  clockingInfo: UseClockingInfoReturn;
};

const TimeTrack = ({ clockingInfo }: TimeTrackProps) => {
  const {
    workedTime,
    workedSeconds,
    schedule,
    programmedTime,
    isClockRunning,
    isInitialLoading,
    isLoading,
    isTodayDayOff,
    todayHoliday,
    todayTimeOff,
    handleToggle,
    drawer,
    timeTrackingClockIsEnabled,
  } = useTimeTrack(clockingInfo);

  const { user } = useAuth();
  const locale = getCurrentLocale(user);
  const { t } = useLokaliseTranslation([
    'clock',
    'time_tracker',
    'time_tracking_common',
  ]);

  if (!timeTrackingClockIsEnabled) return null;
  if (isInitialLoading) return <TimeTrackSkeleton />;

  const showDayOffAlert = isTodayDayOff && !todayHoliday && !todayTimeOff;
  const hasHoliday = !!todayHoliday;
  const hasTimeOff = !!todayTimeOff;

  const isHoursTimeOff =
    hasTimeOff &&
    todayTimeOff.consumptionType === CONSUMPTION.HOURS &&
    todayTimeOff.fromTime &&
    todayTimeOff.toTime;

  const getDayStatusPillLabels = () => {
    const labels: string[] = [];
    if (hasTimeOff) {
      labels.push(
        getTimeOffPillLabel(
          todayTimeOff,
          !!isPeriodTimeOff(todayTimeOff),
          t,
          locale,
        ),
      );
    }
    if (hasHoliday) {
      labels.push(t('time_tracking_common:vacations_holidays'));
    }
    return labels;
  };
  const dayStatusPillLabels = getDayStatusPillLabels();

  const isWorkableTimeOff =
    hasTimeOff && todayTimeOff.activityType === ACTIVITY.WORK;

  const getAlertConfig = () => {
    if (showDayOffAlert) {
      return {
        title: t('time_tracker:day_off_alert_title'),
        description: t('time_tracker:day_off_alert_description'),
      };
    }
    if (hasTimeOff && !isWorkableTimeOff) {
      if (isHoursTimeOff) {
        return {
          title: t('time_tracker:time_off_hours_alert_title', {
            fromTime: truncateTimeToHHMM(todayTimeOff.fromTime ?? ''),
            toTime: truncateTimeToHHMM(todayTimeOff.toTime ?? ''),
          }),
          description: t('time_tracker:time_off_hours_alert_description'),
        };
      }
      if (todayTimeOff.toDate) {
        const formattedDate = format(parseISO(todayTimeOff.toDate), 'PPP', {
          locale,
        });
        return {
          title: t('time_tracker:time_off_alert_title', {
            date: formattedDate,
          }),
          description: t('time_tracker:time_off_alert_description'),
        };
      }
    }
    if (hasHoliday) {
      return {
        title: t('time_tracker:holiday_alert_title'),
        description: t('time_tracker:holiday_description'),
      };
    }
    return null;
  };
  const alertConfig = getAlertConfig();

  const buttonVariant = isClockRunning ? 'error' : 'primary';
  const ButtonIcon = isClockRunning ? IconSquare : IconPlayerPlay;
  const buttonLabel = isClockRunning
    ? t('time_tracker:stop')
    : t('time_tracker:start');

  return (
    <>
      {alertConfig && (
        <Alert
          severity="info"
          hasClose
          title={alertConfig.title}
          description={alertConfig.description}
        />
      )}
      <CardContainer fullWidth>
        <Stack sx={{ gap: 2 }}>
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'center',
              justifyContent: 'space-between',
              gap: 2,
              backgroundColor: ({ palette }) =>
                palette.new.background.layout.default,
              p: theme => theme.spacing(2),
              borderRadius: theme => theme.shape.borderRadiusM,
            }}
          >
            <Stack sx={{ gap: 0.5 }}>
              <Typography
                variant="globalXS"
                sx={{
                  color: theme => theme.palette.new.text.neutral.lighter,
                }}
              >
                {t('timeTracker.title')}
              </Typography>
              <Stack
                sx={{
                  flexDirection: 'row',
                  alignItems: 'baseline',
                  gap: 0.5,
                }}
              >
                <Typography
                  variant="globalXL"
                  sx={{ fontWeight: 'fontWeightBold' }}
                >
                  {workedTime}
                </Typography>
                <Typography
                  variant="globalS"
                  sx={{
                    color: theme => theme.palette.new.text.neutral.lighter,
                  }}
                >
                  {workedSeconds}
                </Typography>
              </Stack>
            </Stack>
            <Button
              variant={buttonVariant}
              size="large"
              startIcon={
                <ButtonIcon color={isClockRunning ? 'error' : undefined} />
              }
              loading={isLoading}
              onClick={handleToggle}
            >
              {buttonLabel}
            </Button>
          </Stack>
          {(schedule || programmedTime || dayStatusPillLabels.length > 0) && (
            <Stack
              sx={{
                flexDirection: 'row',
                alignItems: 'center',
                gap: 2,
              }}
            >
              {schedule && (
                <Stack
                  sx={{ flexDirection: 'row', alignItems: 'center', gap: 1 }}
                >
                  <Typography
                    variant="globalS"
                    sx={{
                      fontWeight: 'fontWeightSemiBold',
                      color: theme => theme.palette.new.text.neutral.lighter,
                    }}
                  >
                    {t('timeTracker.time')}:
                  </Typography>
                  <Pills
                    type="neutral"
                    label={schedule}
                    size="medium"
                    hasIcon={false}
                  />
                </Stack>
              )}
              {programmedTime && (
                <>
                  {schedule && (
                    <Divider
                      orientation="vertical"
                      flexItem
                    />
                  )}
                  <Stack
                    sx={{ flexDirection: 'row', alignItems: 'center', gap: 1 }}
                  >
                    <Typography
                      variant="globalS"
                      sx={{
                        fontWeight: 'fontWeightSemiBold',
                        color: theme => theme.palette.new.text.neutral.lighter,
                      }}
                    >
                      {t('timeTracker.scheduled')}:
                    </Typography>
                    <Pills
                      type="neutral"
                      label={programmedTime}
                      size="medium"
                      hasIcon={false}
                    />
                  </Stack>
                </>
              )}
              {dayStatusPillLabels.map((pillLabel, index) => (
                <Stack
                  key={index}
                  sx={{ flexDirection: 'row', alignItems: 'center', gap: 2 }}
                >
                  {(index === 0 ? schedule || programmedTime : true) && (
                    <Divider
                      orientation="vertical"
                      flexItem
                    />
                  )}
                  <Pills
                    type="info"
                    label={pillLabel}
                    size="medium"
                    hasIcon
                  />
                </Stack>
              ))}
            </Stack>
          )}
        </Stack>
      </CardContainer>
      {drawer}
    </>
  );
};

export default TimeTrack;
