import {
  IconDeviceLaptop,
  IconDeviceMobile,
  IconDevices,
  IconLink,
  IconSettings,
  IconUserEdit,
} from '@material-hu/icons/tabler';

import {
  EntrySource,
  EntryType,
  Incidence,
  type TimeSlot,
  type TimeTrackingEntry,
} from 'src/types/timeTracking';
import { displayHoursAndMinutes, pairEntries } from 'src/utils/timeTracking';

export const searchFirstStart = (entries: TimeTrackingEntry[]) => {
  const sortedStartEntries = entries
    .filter(entry => entry.type === EntryType.START)
    .sort((a, b) => new Date(a.time).getTime() - new Date(b.time).getTime());
  return sortedStartEntries[0];
};

const TO_SECOND = 1000;
const TO_HOUR = 3600;

export const countTimeLate = (
  entries: TimeTrackingEntry[],
  timeSlots: TimeSlot[],
) => {
  const [slotHours, slotMinutes] = timeSlots[0].startTime
    .split(':')
    .map(Number);
  // It's an extreme rare edge case. But this will avoid errors when there is a late incidence and there is no start entry
  if (!searchFirstStart(entries)) {
    return displayHoursAndMinutes(0);
  }
  const firstStartEntryTime = new Date(searchFirstStart(entries).time);
  const referencedSlotDate = new Date(firstStartEntryTime);
  referencedSlotDate.setHours(slotHours);
  referencedSlotDate.setMinutes(slotMinutes);
  const milisecsDifference =
    firstStartEntryTime.getTime() - referencedSlotDate.getTime();
  return displayHoursAndMinutes(
    Math.abs(milisecsDifference / TO_SECOND / TO_HOUR),
  );
};

// Returns the accordion pair ID for the entry pair that generated the incidence.
// Returns null when no specific entry pair is responsible (ABSENT, NOT_CLOCKED_IN).
export const getIncidenceEntryPairId = (
  entries: TimeTrackingEntry[],
  incidenceType: Incidence | null,
): string | null => {
  if (!incidenceType) return null;

  const paired = pairEntries(entries);

  if (incidenceType === Incidence.LATE) {
    // pairEntries returns DESC (newest first); earliest start is the last with a start entry
    const withStart = paired.filter(p => p.start !== undefined);
    return withStart[withStart.length - 1]?.id ?? null;
  }

  if (incidenceType === Incidence.AUTO_CLOSE) {
    // Pair whose END entry was auto-closed by the system
    const autoClosed = paired.find(
      p => p.end && p.end.source === EntrySource.AUTO_CLOSE,
    );
    return autoClosed?.id ?? null;
  }

  if (incidenceType === Incidence.LOCATION_INCIDENCE) {
    // locationIncidence lives on individual start/end entries; find the pair
    // that actually carries the violation (not just the most recent one)
    return (
      paired.find(p => p.start?.locationIncidence || p.end?.locationIncidence)
        ?.id ?? null
    );
  }

  // ABSENT and any unmapped types have no responsible pair
  return null;
};

export const SOURCE_INFO = {
  [EntrySource.APP]: {
    icon: IconDeviceMobile,
    context: EntrySource.APP,
  },
  [EntrySource.KIOSK]: {
    icon: IconDevices,
    context: EntrySource.KIOSK,
  },
  [EntrySource.MANUAL]: {
    icon: IconUserEdit,
    context: EntrySource.MANUAL,
  },
  // TODO: Delete when backend parse this to app
  [EntrySource.USER]: {
    icon: IconUserEdit,
    context: EntrySource.MANUAL,
  },
  [EntrySource.INTEGRATION]: {
    icon: IconLink,
    context: EntrySource.INTEGRATION,
  },
  [EntrySource.SYSTEM]: {
    icon: IconSettings,
    context: EntrySource.SYSTEM,
  },
  [EntrySource.AUTO_CLOSE]: {
    icon: IconSettings,
    context: EntrySource.SYSTEM,
  },
  [EntrySource.DAY_CHANGE]: {
    icon: IconSettings,
    context: EntrySource.SYSTEM,
  },
  [EntrySource.WEB]: {
    icon: IconDeviceLaptop,
    context: EntrySource.WEB,
  },
};
