import { type FC } from 'react';

import { type TOptions } from 'i18next';

import CardContainer from '@material-hu/components/design-system/CardContainer';
import Title from '@material-hu/components/design-system/Title';

import {
  type DaySummary,
  ScheduleSource,
  type TimeOffRequest,
} from 'src/types/timeTracking';
import { useLokaliseTranslation } from 'src/utils/i18n';
import {
  type TimeSlotWithEntries,
  displayHoursAndMinutes,
  getAdjustedTimeSpan,
  getTimeSlotName,
  shouldShowTimeSlotInfo,
  sliceTimeToHoursAndMinutes,
  stringTimeToMinutes,
} from 'src/utils/timeTracking';

type Props = {
  timeSlotWithEntries: TimeSlotWithEntries;
  dayInfo: DaySummary;
};

type TimeOffRequestConsumptionType = NonNullable<
  TimeOffRequest['consumptionType']
>;

const timeOffBadgeLabel = (
  timeOffRequest: TimeOffRequest,
): Record<TimeOffRequestConsumptionType, [string, TOptions?]> => ({
  HALF_DAY: ['time_tracking_common:time_offs_permits.half_day'],
  HOURS: [
    'time_tracking_common:time_offs_permits.hour_range',
    {
      startHour: sliceTimeToHoursAndMinutes(timeOffRequest.fromTime),
      endHour: sliceTimeToHoursAndMinutes(timeOffRequest.toTime),
    },
  ],
  FULL_DAY: ['time_tracking_common:time_offs_permits.full_day'],
});

const shouldShowTimeOffRequestBadge = (
  dayInfo: DaySummary,
  timeSlotWithEntries: TimeSlotWithEntries,
) => {
  if (dayInfo.timeOffRequests.length === 0) {
    return false;
  }

  const timeOffRequest = dayInfo.timeOffRequests[0];

  // Show badge if time of request is hours and timeslots overlap with the time of request
  if (timeOffRequest.consumptionType === 'HOURS') {
    // For now we are not considering night shifts (in that case we should add a whole day to the end times)
    const timeOffStartTime = stringTimeToMinutes(timeOffRequest.fromTime);
    const timeOffEndTime = stringTimeToMinutes(timeOffRequest.toTime);
    const timeSlotStartTime = stringTimeToMinutes(
      timeSlotWithEntries.startTime,
    );
    const timeSlotEndTime = stringTimeToMinutes(timeSlotWithEntries.endTime);

    return (
      (timeOffStartTime < timeSlotEndTime &&
        timeOffEndTime > timeSlotStartTime) ||
      timeOffStartTime === timeSlotStartTime ||
      timeOffEndTime === timeSlotEndTime
    );
  }

  // Case for full_day or half_day
  return true;
};

const TimeSlotInfo: FC<Props> = props => {
  const { timeSlotWithEntries, dayInfo } = props;
  const { t } = useLokaliseTranslation('time_tracker');

  const timeSlotNamePlaceholder =
    dayInfo.scheduleSource === ScheduleSource.SHIFT
      ? t('UNNAMED_SHIFT')
      : t('UNNAMED_SCHEDULE');
  const timeSlotName = getTimeSlotName(dayInfo, timeSlotWithEntries);

  const hasProgrammedHours = timeSlotWithEntries.timeSpan !== null;
  const missingTimeSlots =
    timeSlotWithEntries.startTime === null &&
    timeSlotWithEntries.endTime === null;

  // Don't show time slot info if conditions aren't met or if slots are missing
  if (!shouldShowTimeSlotInfo(dayInfo) || missingTimeSlots) {
    return null;
  }

  const parseTimeOffBadge = (timeOffRequest: TimeOffRequest) => {
    if (timeOffRequest.consumptionType) {
      const [key, options] =
        timeOffBadgeLabel(timeOffRequest)[timeOffRequest.consumptionType];
      return t(key, options);
    }
    return t('time_tracking_common:time_offs_permits.full_day');
  };

  return (
    <CardContainer
      {...(shouldShowTimeOffRequestBadge(dayInfo, timeSlotWithEntries) && {
        badge: {
          hasIcon: false,
          label: parseTimeOffBadge(dayInfo.timeOffRequests[0]),
          type: 'highlight',
        },
      })}
      sx={{
        backgroundColor: ({ palette }) => palette.new.background.layout.default,
        maxWidth: '85%',
        p: 0,
        border: 'none',
      }}
    >
      <Title
        variant="S"
        copetin={
          hasProgrammedHours
            ? t('PROGRAMMED_HOURS', {
                hours: displayHoursAndMinutes(
                  getAdjustedTimeSpan(timeSlotWithEntries, dayInfo) || 0,
                  false,
                  true,
                ),
                count: dayInfo.scheduledHours || 0,
              })
            : ''
        }
        title={timeSlotName || timeSlotNamePlaceholder}
        description={
          hasProgrammedHours
            ? `${timeSlotWithEntries.startTime} - ${timeSlotWithEntries.endTime}`
            : ''
        }
        overflow="tooltip"
        sx={{
          minWidth: 0,
          overflow: 'hidden',
          '& .MuiTypography-globalS': {
            overflow: 'hidden',
            textOverflow: 'ellipsis',
            whiteSpace: 'nowrap',
          },
        }}
        withEllipsis
      />
    </CardContainer>
  );
};

export default TimeSlotInfo;
