import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
type Profesor = {
    profesor_clave: string;
    profesor_correo: string;
    profesor_grado: null | string;
    profesor_id: number;
    profesor_nombre: string;
}

type Horario = {
    carrera: string;
    carrera_id: number;
    dia: string;
    duracion: string;
    duracion_id: number;
    facultad: string;
    facultad_id: number;
    fecha_carga: Date;
    horario_dia: number;
    horario_fecha_fin: null;
    horario_fecha_inicio: Date;
    horario_fin: string;
    horario_grupo: string;
    horario_hora: string;
    horario_id: number;
    limite: null;
    materia: string;
    materia_id: number;
    nivel: string;
    nivel_id: number;
    periodo: string;
    periodo_fecha_fin: Date;
    periodo_fecha_inicio: Date;
    periodo_id: number;
    profesor_id: number;
    salon: string;
    salon_id: number;
    bloques: number;
}

type Facultad = {
    clave_dependencia: string;
    facultad_id: number;
    facultad_nombre: string;
    carreras: Carrera[];
}

type Carrera = {
    carrera_id: number;
    carrera_nombre: string;
    clave_carrera: string;
    facultad_id: number;
}



const profesores = reactive({
    data: [] as Profesor[],
    search: null as null | string,
    fetch: async function () {
        const response = await fetch('action/action_profesor.php')
        this.data = await response.json() as Profesor[]
    },
    get clave() {
        const match = this.search.match(/^\((.+)\)/)
        return match ? match[1] : ''
    },
    get current() {
        return this.data.find((profesor: Profesor) => profesor.profesor_clave === profesores.clave)
    },
})

const facultades = reactive({
    data: [] as Facultad[],
    fetch: async function () {
        const facultades = await fetch('action/action_facultad.php').then(response => response.json()) as Facultad[]
        const carreras = await fetch(`action/carrera.php`).then(response => response.json()) as Carrera[]
        this.data = await Promise.all(facultades.map(async facultad => ({
            ...facultad,
            carreras: await Promise.all(carreras.filter((carrera: Carrera) => carrera.facultad_id === facultad.facultad_id).map(async (carrera: Carrera) => {
                const grupos = await fetch(`action/action_grupo.php?carrera_id=${carrera.carrera_id}`).then(response => response.json())
                return {
                    ...carrera,
                    grupos,
                }
            })),
        })))

        this.data = this.data.filter((facultad: Facultad) => facultad.carreras.length > 0)
    }
})

type Structure = {
    sábado: boolean;
    hora_mínima: number;
    hora_máxima: number;
    horas_totales: number;
}

const horarios = reactive({
    data: [] as Horario[],
    fetch: async function (grupo: number | null = null, carrera_id: number | null = null) {
        if (grupo && carrera_id) {
            const response = await fetch(`action/action_horario.php?grupo=${grupo}&carrera_id=${carrera_id}`)
            this.data = await response.json()
        }
        else if (profesores.current) {
            const response = await fetch(`action/action_horario.php?profesor_id=${profesores.current.profesor_id}`)
            this.data = await response.json()
        }
    },
    get structure() {
        if (this.data.length === 0) return null;

        const structure: Structure = {
            sábado: this.data.some((horario: Horario) => horario.horario_dia === 6),
            hora_mínima: Math.min(...this.data.map((horario: Horario) => parseInt(horario.horario_hora.split(':')[0]))),
            hora_máxima: Math.max(...this.data.map((horario: Horario) => {
                const [hour, minute] = horario.horario_fin.split(':').map(Number);
                return hour + Math.ceil(minute / 60);
            })),
            horas_totales: 0
        };

        structure.horas_totales = structure.hora_máxima - structure.hora_mínima;

        return structure;
    },
    get blocks() {
        if (this.data.length === 0) return null;
        return [...Array(this.structure.horas_totales).keys()].flatMap(hora => {
            const baseHour = hora + this.structure.hora_mínima;
            return [0, 15, 30, 45].map(block => ({ hour: baseHour, block }));
        });
    },
    getHorarioData(hour: number, block: number, día: number) {
        const foundHorario = this.data.find((horario: Horario) =>
            parseInt(horario.horario_hora.split(':')[0]) === hour &&
            parseInt(horario.horario_hora.split(':')[1]) === block &&
            horario.horario_dia === día
        );
        return foundHorario;
    },
    isOccupied(hora: number, bloque: number, day: number) {
        if (this.getHorarioData(hora, bloque, day)) {
            return false;
        }
        const currentTimeInMinutes = hora * 60 + bloque;

        for (const item of this.data) {
            if (item.horario_dia !== day) {
                continue; // Skip items that are not on the specified day
            }

            // Split the hour and minute from horario_hora
            const [startHour, startMinute] = item.horario_hora.split(":").map(Number);
            const startTimeInMinutes = startHour * 60 + startMinute;

            // Calculate end time using duracion
            const [durationHours, durationMinutes] = item.duracion.split(":").map(Number);
            const endTimeInMinutes = startTimeInMinutes + (durationHours * 60) + durationMinutes;

            if (currentTimeInMinutes >= startTimeInMinutes && currentTimeInMinutes < endTimeInMinutes) {
                return true;  // The block is occupied
            }
        }

        return false;  // The block is not occupied by any class
    }

})

const app = createApp({
    profesores,
    horarios,
    facultades,
    mounted: async function () {
        await profesores.fetch()
        await facultades.fetch()
    }
}).mount('#app')