import { TimeTrackingDaySummary } from '../../models/daySummary';
import { PublicApiAssignedShift, PublicApiShiftInfo, PublicApiShiftTemplate, PublicApiTimeSlot } from '../../models/shiftManagement/publicApiShift';
import { Shift } from '../../models/shiftManagement/shift';
import { ShiftAssignedDay } from '../../models/shiftManagement/shiftAssignedDay';
import { ShiftAssignedShift } from '../../models/shiftManagement/shiftAssignedShift';
import { TimeSlot } from '../../models/timeTracking/scheduleData';
import { ShiftAssignedShiftSource } from '../../types/shiftManagement/source';

const getTimeSlotsForAssociation = (shiftAssoc: ShiftAssignedShift): TimeSlot[] => {
    return shiftAssoc.source === ShiftAssignedShiftSource.INTEGRATION ? shiftAssoc.timeSlots || [] : shiftAssoc.shift?.timeSlots || [];
};

const mapTimeSlots = (timeSlots: TimeSlot[]): PublicApiTimeSlot[] => {
    return timeSlots.map((ts) => new PublicApiTimeSlot({ endTime: ts.endTime, startTime: ts.startTime }));
};

const buildShiftInfo = (shiftAssoc: ShiftAssignedShift, timeSlots: TimeSlot[]): PublicApiShiftInfo => {
    const shift = shiftAssoc.shift;
    return new PublicApiShiftInfo({
        color: shift?.color ?? null,
        description: shift?.description ?? null,
        id: shiftAssoc.id,
        name: shift?.name ?? null,
        templateId: shift?.isTemplate ? shift.id : null,
        timeSlots: mapTimeSlots(timeSlots),
    });
};

const buildShiftsFromAssignedDay = (assignedDay: ShiftAssignedDay | undefined): PublicApiShiftInfo[] => {
    if (!assignedDay) return [];
    return ((assignedDay.shiftAssociations || []) as ShiftAssignedShift[]).map((shiftAssoc) => {
        const timeSlots = getTimeSlotsForAssociation(shiftAssoc);
        return buildShiftInfo(shiftAssoc, timeSlots);
    });
};

export const mapDaySummariesToPublicApiShifts = (
    daySummaries: TimeTrackingDaySummary[],
    shiftAssignedDayMap: Map<number, ShiftAssignedDay>,
    employeeId: string,
): PublicApiAssignedShift[] => {
    return daySummaries.map((daySummary) => {
        const assignedDay = daySummary.shiftAssignedDayId ? shiftAssignedDayMap.get(daySummary.shiftAssignedDayId) : undefined;
        return new PublicApiAssignedShift({
            date: daySummary.dateString,
            employeeId,
            id: daySummary.id,
            shifts: buildShiftsFromAssignedDay(assignedDay),
        });
    });
};

export const mapShiftToPublicApiTemplate = (shift: Shift): PublicApiShiftTemplate => {
    const timeSlots = shift.timeSlots as TimeSlot[];
    return new PublicApiShiftTemplate({
        color: shift.color,
        description: shift.description,
        id: shift.id,
        name: shift.name,
        timeSlots: mapTimeSlots(timeSlots),
    });
};
