"use client"

import { useState, useCallback, useEffect } from "react"
import { CircularProgress, Grid, Typography } from "@mui/material"
import type { FormFieldType } from "@/shared/types/common"
import DuplicableField from "@/shared/components/form/duplicable-field"
import { getLabel } from "@/shared/_mock"
import { type FieldType, useMultipleFields } from "@/hooks/use-multiple-fields"
import TransportScheduleField from "./transport-schedule-field"
import type { DaysOfWeek, WeekType } from "@/shared/types/passenger"
import type { PeriodOfDay } from "@/shared/types/ammendment-passenger"
import type { IBaseEntity } from "@/shared/types/client"

export interface DaySchedule extends IBaseEntity {
    dayOfWeek: DaysOfWeek
    periodOfDay: PeriodOfDay
}

export interface WeekSchedule extends IBaseEntity {
    weekType: WeekType
    schedules: DaySchedule[]
}

export interface EstablishmentSchedule extends IBaseEntity {
    idEstablishment: number
    establishmentName: string
    dayScheduleEstablishments: WeekSchedule[]
}

const getDefaultSchedule = (): EstablishmentSchedule => ({
    id: "",
    idEstablishment: 0,
    establishmentName: "",
    dayScheduleEstablishments: [],
})

interface EtablissementJoursFieldProps {
    field: FormFieldType<any>
    values: {
        establishmentTransportSchedules: EstablishmentSchedule[]
    }
    errors: (index: number) => string | undefined
    isReadOnly: boolean
    etablissementsOptions: { value: string; label: string }[]
    onFieldChange: (field: string, value: any) => void
    handleFieldBlur: (index: number) => void
}

export default function EtablissementJoursField({
    field,
    values,
    errors,
    isReadOnly,
    etablissementsOptions,
    onFieldChange,
    handleFieldBlur,
}: EtablissementJoursFieldProps) {
    const [establishmentSchedules, setEstablishmentSchedules] = useState<EstablishmentSchedule[]>(
        values?.establishmentTransportSchedules.length > 0
            ? values?.establishmentTransportSchedules
            : [getDefaultSchedule()],
    )

    const { fields, handleAdd, handleDelete, handleChange, reset } = useMultipleFields({
        initialValues: {
            etablissement: establishmentSchedules.map((schedule) => schedule?.idEstablishment?.toString() || ""),
        },
        onChange: (type, newValues) => {
            if (type === "etablissement") {
                try {
                    const updatedSchedules = newValues.map((establishmentId: string, index: number) => {
                        const existingSchedule = establishmentSchedules[index] || getDefaultSchedule()

                        const establishment = etablissementsOptions.find((opt) => opt.value === establishmentId)

                        return {
                            ...existingSchedule,
                            idEstablishment: Number.parseInt(establishmentId) || 0,
                            establishmentName: establishment?.label || "",
                        }
                    })

                    setEstablishmentSchedules(updatedSchedules)
                    onFieldChange("establishmentTransportSchedules", updatedSchedules)
                } catch (error) {
                    console.error("Error in onChange:", error)
                }
            }
        },
        isReadOnly,
    })

    useEffect(() => {
        if (values?.establishmentTransportSchedules?.length === 0) {
            setEstablishmentSchedules([getDefaultSchedule()])
            reset({ etablissement: [""] })
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [values?.establishmentTransportSchedules])

    const handleAddEtablissement = useCallback(() => {
        try {
            const newSchedule = getDefaultSchedule()

            const updatedSchedules = [...establishmentSchedules, newSchedule]
            setEstablishmentSchedules(updatedSchedules)
            handleAdd("etablissement")
            onFieldChange("establishmentTransportSchedules", updatedSchedules)
        } catch (error) {
            console.error("Error in handleAddEtablissement:", error)
        }
    }, [establishmentSchedules, handleAdd, onFieldChange])

    const handleDeleteEtablissement = useCallback(
        (type: FieldType, index: number) => {
            try {
                const updatedSchedules = establishmentSchedules.filter((_, i) => i !== index)
                setEstablishmentSchedules(updatedSchedules)
                onFieldChange("establishmentTransportSchedules", updatedSchedules)
                handleDelete("etablissement", index)
            } catch (error) {
                console.error("Error in handleDeleteEtablissement:", error)
            }
        },
        [establishmentSchedules, onFieldChange, handleDelete],
    )

    const handleScheduleChange = useCallback(
        (index: number, updatedSchedules: WeekSchedule[]) => {
            try {
                const updatedEstablishmentSchedules = establishmentSchedules.map((schedule, idx) => {
                    if (idx === index) {
                        return {
                            ...schedule,
                            dayScheduleEstablishments: updatedSchedules,
                        }
                    }
                    return schedule
                })

                setEstablishmentSchedules(updatedEstablishmentSchedules)
                onFieldChange("establishmentTransportSchedules", updatedEstablishmentSchedules)
            } catch (error) {
                console.error("Error in handleScheduleChange:", error)
            }
        },
        [establishmentSchedules, onFieldChange],
    )



    if (!fields || !fields.etablissement) {
        return <CircularProgress />
    }

    return (
        <>
            {fields.etablissement.map((value, index) => (
                <>
                    <DuplicableField
                        formData={values}
                        key={`etablissement-${index}`}
                        fieldType={"etablissement"}
                        field={field}
                        index={index}
                        value={value}
                        isReadOnly={isReadOnly}
                        onChange={handleChange}
                        onAdd={handleAddEtablissement}
                        onDelete={handleDeleteEtablissement}
                        sx={{ mt: 3 }}
                        error={errors(index)}
                        onBlur={() => handleFieldBlur(index)}
                    />
                    <Grid
                        item
                        xs={12}
                        md={5}
                        sx={{
                            "@media (min-width: 1850px)": {
                                flexBasis: "33.333%",
                                maxWidth: "33.333%",
                            },
                        }}
                        key={`jours-${index}`}
                    >
                        <Typography sx={{ color: (theme) => theme.palette.primary.main }}>
                            {`Jours (${getLabel(value, etablissementsOptions) || `Établissement ${index + 1}`})`}
                        </Typography>
                        <TransportScheduleField
                            initialSchedules={establishmentSchedules[index]?.dayScheduleEstablishments || []}
                            otherSchedules={establishmentSchedules
                                .filter((_, idx) => idx !== index)
                                .map((schedule) => schedule?.dayScheduleEstablishments || [])}
                            onChange={(updatedSchedules) => handleScheduleChange(index, updatedSchedules)}
                            isReadOnly={isReadOnly}
                        />
                    </Grid>
                </>
            ))}
        </>
    )
}
