import { AmendmentCircuit } from "@/shared/types/ammendment-circuit";
import { AmendmentPassengerScheduleDTO, PassengerScheduleWeekDTO, PeriodOfDay } from "@/shared/types/ammendment-passenger";
import { ICircuit } from "@/shared/types/circuit";
import { FormikAmendmentCircuitDetails } from "../components/avenant-horaire";
import { WeeklyScheduleType } from "@/shared/sections/usager/components/usager-form/avenants-horaires/types/formik-types";
import { DaysOfWeek, SensTrip } from "@/shared/types/passenger";
import { createDefaultWeekSchedule, DAY_MAPPING, extractTime, REVERSE_DAY_MAPPING } from "@/shared/sections/usager/components/usager-form/avenants-horaires/utils/converters";
import dayjs from "dayjs";

  export const convertFromFormikValues = (
    formikValues: FormikAmendmentCircuitDetails,
    existingWeekIds?: { pair?: string | null; impair?: string | null },
  ): AmendmentCircuit => {
    const passengerScheduleWeeks: PassengerScheduleWeekDTO[] = []
  
    const pairSchedules = processWeekData(formikValues.weeklySchedules.pair)
    if (pairSchedules.length > 0) {
      passengerScheduleWeeks.push({
        id: existingWeekIds?.pair || null,
        weekType: "EVEN",
        amendmentPassengerSchedule: pairSchedules,
      })
    }
  
    const impairSchedules = processWeekData(formikValues.weeklySchedules.impair)
    if (impairSchedules.length > 0) {
      passengerScheduleWeeks.push({
        id: existingWeekIds?.impair || null,
        weekType: "ODD",
        amendmentPassengerSchedule: impairSchedules,
      })
    }

  
    const { weeklySchedules, ...restFormikValues } = formikValues
  
    return {
      ...restFormikValues,
      passengerScheduleWeeks,
    }
  }
  function processWeekData(weekData: WeeklyScheduleType["pair"] | WeeklyScheduleType["impair"]): AmendmentPassengerScheduleDTO[] {
    const schedules: AmendmentPassengerScheduleDTO[] = []
  
    Object.entries(weekData).forEach(([dayKey, dayData]) => {
      const dayOfWeek = REVERSE_DAY_MAPPING[dayKey]
      if (!dayOfWeek) return
  
      if (dayData.morning?.aller) {
        schedules.push({
          sensTrip: SensTrip.DEPARTURE,
          dayOfWeek: dayOfWeek as DaysOfWeek,
          periodOfDay: PeriodOfDay.MORNING,
          scheduledTime: extractTime(dayData.morning.aller.toISOString()),
        })
      }
  
      if (dayData.morning?.retour) {
        schedules.push({
          sensTrip: SensTrip.RETURN,
          dayOfWeek: dayOfWeek as DaysOfWeek,
          periodOfDay: PeriodOfDay.MORNING,
          scheduledTime: extractTime(dayData.morning.retour.toISOString()),
        })
      }
  
      if (dayData.evening?.aller) {
        schedules.push({
          sensTrip: SensTrip.DEPARTURE,
          dayOfWeek: dayOfWeek as DaysOfWeek,
          periodOfDay: PeriodOfDay.EVENING,
          scheduledTime: extractTime(dayData.evening.aller.toISOString()),
        })
      }
  
      if (dayData.evening?.retour) {
        schedules.push({
          sensTrip: SensTrip.RETURN,
          dayOfWeek: dayOfWeek as DaysOfWeek,
          periodOfDay: PeriodOfDay.EVENING,
          scheduledTime: extractTime(dayData.evening.retour.toISOString()),
        })
      }
    })
  
    return schedules
  }

  export const convertToFormikValues = (amendment: AmendmentCircuit): FormikAmendmentCircuitDetails => {
    const weeklySchedules: WeeklyScheduleType = {
      pair: createDefaultWeekSchedule(),
      impair: createDefaultWeekSchedule(),
    }
  
    if (amendment.passengerScheduleWeeks?.length > 0) {
      amendment.passengerScheduleWeeks.forEach((week) => {
          const weekType = week.weekType === "EVEN" ? "pair" : "impair"
  
          week.amendmentPassengerSchedule?.forEach((schedule) => {
            const dayKey = DAY_MAPPING[schedule.dayOfWeek]?.toLowerCase()
            if (!dayKey) return
  
            const time = dayjs(schedule.scheduledTime, "HH:mm:ss")
            const isAller = schedule.sensTrip === SensTrip.DEPARTURE
  
            if (!weeklySchedules[weekType][dayKey]) {
              weeklySchedules[weekType][dayKey] = {
                morning: { aller: dayjs().hour(8).minute(0) },
                evening: { retour: dayjs().hour(18).minute(0) },
              }
            }
  
            if (schedule.periodOfDay === PeriodOfDay.MORNING) {
              if (isAller) {
                weeklySchedules[weekType][dayKey].morning.aller = time
              } else {
                weeklySchedules[weekType][dayKey].morning.retour = time
              }
            } else {
              if (isAller) {
                weeklySchedules[weekType][dayKey].evening.aller = time
              } else {
                weeklySchedules[weekType][dayKey].evening.retour = time
              }
            }
          })
        })
    }
  
    const { passengerScheduleWeeks, ...restAmendment } = amendment
  
    return {
      ...restAmendment,
      weeklySchedules,
    }
  }

  export const extractExistingWeekIds = (amendment: AmendmentCircuit): { pair?: string | null; impair?: string | null } => {
    const existingWeekIds: { pair?: string | null; impair?: string | null } = {}
  
    if (amendment.passengerScheduleWeeks?.length > 0) {
      amendment.passengerScheduleWeeks.forEach((week) => {
          const weekType = week.weekType === "EVEN" ? "pair" : "impair"
          
          if (weekType === "pair") {
            existingWeekIds.pair = week.id
          } else {
            existingWeekIds.impair = week.id
          }
        })
    }
  
    return existingWeekIds
  }