import { type FC } from 'react';

import Stack from '@material-hu/mui/Stack';
import { type Theme, useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

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

import {
  type DayDetailResponse,
  type DaySummary,
  type EntryFormFields,
  type EntrySource,
  type EntryType,
  Incidence,
  type SiteCoordinates,
  type SiteLocation,
  type UserSite,
  UserTrackingStatus,
} from 'src/types/timeTracking';
import { useLokaliseTranslation } from 'src/utils/i18n';
import {
  formatCompleteDecimalHours,
  parseDayScheduleStatus,
} from 'src/utils/timeTracking';

import { countTimeLate } from '../../EmployeeTimesheet/utils';
import HuIncidenceTag from '../Incidences/IncidenceTag';
import ProgressBar from '../ProgressBar';

import CategorizedHoursSection from './components/CategorizedHoursSection';
import Entries from './components/Entries';
import ProgressIndicator from './components/ProgressIndicator';
import RestDayCard from './components/RestDayCard';
import ScheduleSection from './components/ScheduleSection';
import TimeOffHolidaysSection from './components/TimeOffHolidaysSection';
import { checkIsRestDay, getSubRowParts } from './utils';

type Props = {
  dayInfo: DaySummary;
  dayDetail?: DayDetailResponse;
  isCurrentDay: boolean;
  userStatus: UserTrackingStatus;
  loadingSummaries: boolean;
  userSites: UserSite[];
  onSiteClick?: (
    siteId: number | null,
    siteName: string,
    location: SiteLocation,
    markingLocation: SiteCoordinates | null,
    entrySource: EntrySource,
    entryType: EntryType,
  ) => void;
  onSelectedSiteChange: (siteId: number, entryType: EntryType) => void;
  onFormValuesChange?: (
    formValues: EntryFormFields,
    entryPairId: string,
    siteIds: { start: { siteId: number }; end: { siteId: number } },
  ) => void;
  onCloseMap: (newOpenAccordion?: string) => void;
  onOpenMap: (openAccordion?: string) => void;
  defaultOpenAccordion?: string;
  isDeactivated?: boolean;
  enableRemoteWork?: boolean;
};

const textSecondarySx = {
  color: ({ palette }: Theme) => palette.new.text.neutral.lighter,
};

const PeriodDetailDrawer: FC<Props> = props => {
  const {
    dayInfo,
    dayDetail,
    isCurrentDay,
    userStatus,
    loadingSummaries,
    userSites,
    onSiteClick,
    onSelectedSiteChange,
    onFormValuesChange,
    onCloseMap,
    onOpenMap,
    defaultOpenAccordion,
    isDeactivated,
    enableRemoteWork,
  } = props;
  const { t } = useLokaliseTranslation('time_tracker');
  const { palette } = useTheme();

  const userIsMarking =
    isCurrentDay && userStatus === UserTrackingStatus.ACTIVE;

  const incidenceCount: Partial<Record<Incidence, () => number | string>> = {
    [Incidence.LATE]: () =>
      countTimeLate(dayInfo.timeTrackingEntries, dayInfo.timeSlots || []),
    [Incidence.ABSENT]: () => 0,
  };

  const tagIncidences = dayInfo.incidences.filter(
    i => i === Incidence.ABSENT || i === Incidence.LATE,
  );

  const { holiday, isScheduledDayOff } = parseDayScheduleStatus({
    holidays: dayInfo.holidays,
    isWorkday: dayInfo.isWorkday,
    scheduleSource: dayInfo.scheduleSource,
    timeOffRequests: dayInfo.timeOffRequests,
  });

  const isDayOffOrHoliday =
    (isScheduledDayOff || Boolean(holiday?.name)) &&
    dayInfo.estimatedHours === 0;

  const hasCategorizedHours =
    dayDetail && dayDetail.categorizedHours.length > 0;

  const isRestDay = dayDetail && checkIsRestDay(dayDetail);

  const isNonWorkableHoliday =
    dayDetail && !dayDetail.isWorkday && dayDetail.holidays.length > 0;

  const hasTimeOffOrHolidays =
    dayDetail &&
    (dayDetail.timeOffRequests.length > 0 || dayDetail.holidays.length > 0);

  const showScheduleSection = dayDetail && !isRestDay && !isNonWorkableHoliday;

  const showDaySummaryTitle = isRestDay && hasCategorizedHours;

  const subRow = dayDetail ? getSubRowParts(dayDetail, t) : null;

  const estimatedTimeFallback =
    dayInfo.estimatedHours % 1 === 0
      ? t('programmed_hour', { count: dayInfo.estimatedHours })
      : t('programmed_time', {
          time: formatCompleteDecimalHours(dayInfo.estimatedHours),
        });

  const subRowText = subRow
    ? [subRow.programmedText, subRow.contextText].filter(Boolean).join(' | ')
    : estimatedTimeFallback;

  return (
    <Stack sx={{ gap: 2 }}>
      {hasCategorizedHours && (
        <Alert
          severity="info"
          hasClose
          title={t('categorized_hours_alert_title', {
            name: dayDetail.categorizedHours[0].category.name,
          })}
          description={dayDetail.categorizedHours[0].category.description}
        />
      )}
      {isDeactivated && (
        <Alert
          severity="info"
          loading={loadingSummaries}
          title={t('general:deactivated_collaborator')}
          hasClose
          description={t('general:deactivated_collaborator_alert_description')}
        />
      )}
      {showDaySummaryTitle && (
        <Typography
          variant="globalS"
          sx={{ fontWeight: 'bold' }}
        >
          {t('day_summary_title')}
        </Typography>
      )}
      <HuCardContainer
        sx={{
          backgroundColor: palette.new.background.layout.default,
          border: 'none',
        }}
        fullWidth
      >
        <Typography
          variant="globalL"
          sx={{ mb: 1 }}
        >
          {formatCompleteDecimalHours(dayInfo.workedHours)}
        </Typography>
        <ProgressBar
          worked={dayInfo.workedHours}
          estimated={dayInfo.estimatedHours}
          extra={dayInfo.extraHours}
          isDayOffOrHoliday={isDayOffOrHoliday}
        />
        <Stack
          sx={{
            alignItems: 'center',
            flexDirection: 'row',
            gap: 1,
            mt: 1,
          }}
        >
          <Typography
            variant="globalXXS"
            sx={textSecondarySx}
          >
            {subRowText}
          </Typography>
          {!loadingSummaries && userIsMarking && (
            <ProgressIndicator
              date={dayInfo.date}
              isCurrentDate={isCurrentDay}
              status={userStatus}
              estimatedHours={dayInfo.estimatedHours}
              workedHours={dayInfo.workedHours}
              extraHours={dayInfo.extraHours}
              scheduleSource={dayInfo.scheduleSource}
              isWorkday={dayInfo.isWorkday}
            />
          )}
          {!loadingSummaries &&
            tagIncidences.length > 0 &&
            tagIncidences.map(incidence => (
              <HuIncidenceTag
                key={incidence}
                type={incidence}
                count={incidenceCount[incidence]?.() ?? 0}
                hideCount={incidence !== Incidence.LATE}
                disableTooltip
              />
            ))}
        </Stack>
        {hasCategorizedHours && (
          <Stack
            sx={{
              borderTop: ({ palette: p }) =>
                `1px solid ${p.new.border.neutral.divider}`,
              mt: 2,
              pt: 2,
            }}
          >
            <CategorizedHoursSection
              categorizedHours={dayDetail.categorizedHours}
            />
          </Stack>
        )}
      </HuCardContainer>
      {showScheduleSection && (
        <ScheduleSection
          schedule={dayDetail.schedule}
          hours={dayDetail.hours}
          timeSlots={dayDetail.timeSlots}
        />
      )}
      {isRestDay && <RestDayCard />}
      {dayDetail && hasTimeOffOrHolidays && (
        <TimeOffHolidaysSection
          timeOffRequests={dayDetail.timeOffRequests}
          holidays={dayDetail.holidays}
          isWorkday={dayDetail.isWorkday}
        />
      )}
      <Entries
        autoCloseMode={dayInfo.autoCloseMode}
        entries={dayInfo.timeTrackingEntries}
        userIsMarking={userIsMarking}
        summaryId={dayInfo.id}
        userId={dayInfo.userId}
        summaryDay={dayInfo.dateString}
        loadingSummaries={loadingSummaries}
        enableNightShift={dayInfo.nightShift}
        userSites={userSites}
        onSiteClick={
          onSiteClick ||
          (() => {
            return;
          })
        }
        onSelectedSiteChange={onSelectedSiteChange}
        onFormValuesChange={onFormValuesChange}
        onCloseMap={onCloseMap}
        onOpenMap={onOpenMap}
        defaultOpenAccordion={defaultOpenAccordion}
        isDeactivated={isDeactivated}
        enableRemoteWork={enableRemoteWork}
      />
    </Stack>
  );
};

export default PeriodDetailDrawer;
