/**
 * Utilitaires pour la gestion de l'attendance
 */

// Types pour l'attendance
export type SimpleAttendance = Record<string, Record<string, boolean>>
export type MultiTabAttendance = Record<number, Record<string, Record<string, boolean>>>
export type AttendanceUnion = SimpleAttendance | MultiTabAttendance

/**
 * Fonction d'égalité profonde pour comparer les objets
 */
export const isEqual = (obj1: any, obj2: any): boolean => {
    if (obj1 === obj2) return true
    if (!obj1 || !obj2) return false

    const keys1 = Object.keys(obj1)
    const keys2 = Object.keys(obj2)

    if (keys1.length !== keys2.length) return false

    for (const key of keys1) {
        const val1 = obj1[key]
        const val2 = obj2[key]

        if (typeof val1 === "object" && typeof val2 === "object") {
            if (!isEqual(val1, val2)) return false
        } else if (val1 !== val2) {
            return false
        }
    }

    return true
}

/**
 * Génère les dates pour un mois donné (format NotCher)
 */
export const generateDatesNotCher = (mois?: string, annee?: string) => {
    const month = Number.parseInt(mois || new Date().getMonth().toString()) + 1
    const year = Number.parseInt(annee || new Date().getFullYear().toString())
    const daysInMonth = new Date(year, month + 1, 0).getDate()

    const firstDayOfMonth = new Date(year, month, 1).getDay()
    const firstDayIndex = firstDayOfMonth === 0 ? 6 : firstDayOfMonth - 1

    const weeks = []
    let currentDay = 1

    while (currentDay <= daysInMonth) {
        const weekDays = []
        const startIndex = weeks.length === 0 ? firstDayIndex : 0

        for (let i = 0; i < 7; i++) {
            if (weeks.length === 0 && i < startIndex) {
                weekDays.push(null)
            } else if (currentDay <= daysInMonth) {
                weekDays.push({
                    date: new Date(year, month, currentDay),
                    dayNumber: currentDay,
                })
                currentDay++
            } else {
                weekDays.push(null)
            }
        }

        if (weekDays.some((day) => day !== null)) {
            weeks.push(weekDays)
        }
    }

    return weeks
}

/**
 * Génère les dates pour un mois donné (format Cher)
 */
export const generateDatesCher = (mois?: string, annee?: string) => {
    const month = Number.parseInt(mois || new Date().getMonth().toString()) - 1
    const year = Number.parseInt(annee || new Date().getFullYear().toString())
    const daysInMonth = new Date(year, month + 1, 0).getDate()

    const dates = []
    for (let i = 0; i < 4; i++) {
        const startDay = i * 7 + 1
        const endDay = Math.min(startDay + 6, daysInMonth)
        if (startDay <= daysInMonth) {
            dates.push({
                start: new Date(year, month, startDay),
                end: new Date(year, month, endDay),
            })
        }
    }
    return dates
}

/**
 * Vérifie si un jour est un jour de vacances (NotCher)
 */
export const isVacationDay = (dayKey: string, weekIndex: number): boolean => {
    const staticVacationDays = ["Mercredi-0", "Jeudi-0", "Lundi-2"]

    const parts = dayKey.split("-")
    const dayWeekKey = `${parts[0]}-${weekIndex}`

    return staticVacationDays.includes(dayWeekKey)
}

/**
 * Constantes communes
 */
export const WEEKDAYS_NOTCHER = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"]
export const WEEKDAYS_CHER = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi"]

/**
 * Formate une date en français
 */
export const formatDateFrench = (mois?: string, annee?: string): string => {
    if (mois && annee) {
        return new Date(
            Number.parseInt(annee),
            Number.parseInt(mois) - 1,
            1,
        ).toLocaleString("fr-FR", { month: "long", year: "numeric" })
    }
    return new Date().toLocaleString("fr-FR", { month: "long", year: "numeric" })
}