"use client"

import { useState, useEffect, useCallback, useMemo } from "react"
import { Box, Typography, Grid, Table, TableBody, TableCell, TableHead, TableRow } from "@mui/material"
import FormField from "@/shared/components/form/form-field"
import type { FormFieldType, ModeType } from "@/shared/types/common"
import { transportFields, studentNamesFields, observationField } from "../utils/attendance-sheet-fields"
import { StyledTableContainer } from "@/shared/theme/css"
import { HeaderCellWidthColor, HeaderRow } from "@/shared/components/form/style"
import { pxToRem } from "@/shared/theme/typography"
import { PresenceStyledRow } from "@/shared/sections/contract/styles"
import { CustomCheckbox } from "@/shared/components/form/custom-checkbox"
import SignatureField from "@/shared/sections/avenant/components/signature-field"
import React from "react"
import { convertMonthToNumber, isEqual } from "../utils/attendance-utils"
import ConditionalComponent from "@/shared/components/table/ConditionalComponent"
import { IAttendanceNotCher } from "@/shared/types/attendance-sheet"
import AttendanceSheetHeader from "./AttendanceSheetHeader"

interface SheetTab {
  id: number
  data: IAttendanceNotCher
  isReadOnly?: boolean
}

export interface AttendanceSheetNotCherProps {
  tabs: SheetTab[]
  tab: SheetTab
  mode?: ModeType
  handleFormChange?: (tabId: number, newData: IAttendanceNotCher) => void
  attendance: Record<string, Record<string, boolean>>
  onAttendanceChange: (attendance: Record<string, Record<string, boolean>>) => void
  onAttendanceUpdate: (passengerId: number, date: string, isAbsent: boolean, tripType?: 'A' | 'R') => Promise<void>
}

function AttendanceSheetNotCher({
  tabs,
  tab,
  mode = "edit",
  handleFormChange,
  attendance,
  onAttendanceChange,
  onAttendanceUpdate
}: AttendanceSheetNotCherProps) {
  const [localAttendance, setLocalAttendance] = useState<Record<string, Record<string, boolean>>>(attendance || {})
  const [isInitialized, setIsInitialized] = useState(false)
  const isReadOnly = tab.isReadOnly || mode === "view"
  const getPassengerPresenceStatus = useCallback((passengerStatuses: any, passengerId: number) => {
    const status = passengerStatuses?.[passengerId]

    if (status && typeof status === 'object') {
      return {
        outbound: status.outbound !== undefined ? status.outbound : true,
        return: status.return !== undefined ? status.return : true
      }
    }
    return {
      outbound: true,
      return: true
    }
  }, [])
  const days = useMemo(() => {
    const calendarDays = tab.data.calendar?.days || []
    return calendarDays.filter(day =>
      day &&
      typeof day.dayOfMonth === 'number' &&
      day.dayOfMonth > 0 &&
      day.dayOfMonth <= 31
    )
  }, [tab.data.calendar?.days])

  const passengers = useMemo(() => tab.data.passengers || [], [tab.data.passengers])
  const hasPassengers = passengers.length > 0
  const mappedData = useMemo(() => {
    const data = { ...tab.data }
    const studentFields = {
      eleveA: '',
      eleveB: '',
      eleveC: '',
      eleveD: '',
      eleveE: '',
    }

    passengers.forEach((passenger, index) => {
      const fieldName = `eleve${String.fromCharCode(65 + index)}` as keyof typeof studentFields
      if (fieldName in studentFields) {
        studentFields[fieldName] = `${passenger.firstName} ${passenger.lastName}`
      }
    })

    return {
      ...data,
      ...studentFields
    }
  }, [tab.data, passengers])
  const fieldsReadOnly = true;
  const tableReadOnly = mode === "view";
  useEffect(() => {
    if (!isInitialized && days.length > 0 && passengers.length > 0) {
      const initialAttendance: Record<string, Record<string, boolean>> = {}
      days.forEach(day => {
        if (!day.weekend && day.dayOfMonth) {
          initialAttendance[`${day.dayOfMonth}`] = {}
          passengers.forEach(passenger => {
            const { outbound: isOutboundPresent, return: isReturnPresent } = getPassengerPresenceStatus(
              day.passengerStatuses,
              passenger.id
            )

            initialAttendance[`${day.dayOfMonth}`][`${passenger.id}-A`] = isOutboundPresent
            initialAttendance[`${day.dayOfMonth}`][`${passenger.id}-R`] = isReturnPresent
          })
        }
      })

      setLocalAttendance(initialAttendance)
      setIsInitialized(true)
      if (Object.keys(attendance || {}).length === 0) {
        onAttendanceChange(initialAttendance)
      }

      if (handleFormChange) {
        const totalDays = days.filter(d => !d.weekend && d.dayOfMonth).length
        const totalPassengers = passengers.length
        const presentCount = Object.values(initialAttendance).reduce((count, dayData) => {
          return count + Object.values(dayData).filter(value => value).length
        }, 0)

        handleFormChange(tab.id, {
          ...tab.data,
          joursPresence: presentCount.toString(),
          joursAbsence: (totalDays * totalPassengers * 2 - presentCount).toString()
        })
      }
    }
  }, [days, passengers, isInitialized, attendance, onAttendanceChange, handleFormChange, tab.id, tab.data, getPassengerPresenceStatus])
  useEffect(() => {
    if (isInitialized && attendance && !isEqual(attendance, localAttendance)) {
      setLocalAttendance(attendance)
    }
  }, [attendance, isInitialized])

const handleAttendanceChange = useCallback(
  async (dayOfMonth: number, passengerId: number, tripType: 'A' | 'R') => {
    if (!dayOfMonth || dayOfMonth <= 0) {
      console.error('dayOfMonth invalide:', dayOfMonth)
      return
    }

    const dayKey = `${dayOfMonth}`
    const attendanceKey = `${passengerId}-${tripType}`

    try {
      const day = days.find(d => d.dayOfMonth === dayOfMonth)
      const { outbound, return: ret } = getPassengerPresenceStatus(day?.passengerStatuses, passengerId)
      const defaultValue = tripType === 'A' ? outbound : ret

      const currentValue = localAttendance[dayKey]?.[attendanceKey] ?? defaultValue
      const newValue = !currentValue

      const monthStr = typeof tab.data.month === 'string' ? tab.data.month : String(tab.data.month)
      const monthNumber = convertMonthToNumber(monthStr)
      const date = `${tab.data.year}-${monthNumber}-${String(dayOfMonth).padStart(2, '0')}`
      const isAbsent = !newValue

      await onAttendanceUpdate(passengerId, date, isAbsent, tripType)

      setLocalAttendance(prev => {
        const dayAttendance = prev[dayKey] || {}
        const newDayAttendance = {
          ...dayAttendance,
          [attendanceKey]: newValue
        }

        const newAttendance = {
          ...prev,
          [dayKey]: newDayAttendance
        }

        requestAnimationFrame(() => {
          onAttendanceChange(newAttendance)
        })

        if (handleFormChange) {
          const presentCount = Object.values(newAttendance).reduce((count, dayData) => {
            return count + Object.values(dayData).filter(value => value).length
          }, 0)

          const totalDays = days.filter(d => !d.weekend && d.dayOfMonth).length
          const totalPassengers = passengers.length

          requestAnimationFrame(() => {
            handleFormChange(tab.id, {
              ...tab.data,
              joursPresence: presentCount.toString(),
              joursAbsence: (totalDays * totalPassengers * 2 - presentCount).toString()
            })
          })
        }

        return newAttendance
      })
    } catch (error) {
      console.error('Erreur lors de la mise à jour du statut de présence:', error)
    }
  },
  [days, passengers.length, onAttendanceChange, handleFormChange, tab.id, tab.data, localAttendance, onAttendanceUpdate, getPassengerPresenceStatus]
)
  const renderField = useCallback(
    (field: FormFieldType<IAttendanceNotCher>) => (
      <FormField
        key={field.name}
        field={field}
        value={mappedData[field.name] || ''}
        onChange={() => void 0}
        isReadOnly={fieldsReadOnly}
        isDrawerElement={true}
      />
    ),
    [mappedData, fieldsReadOnly]
  )
  const EmptyStateComponent = useMemo(() => (
    <Box sx={{
      display: 'flex',
      justifyContent: 'center',
      alignItems: 'center',
      height: '200px',
      backgroundColor: 'background.paper',
      borderRadius: 1,
      p: 3
    }}>
      <Typography variant="h6" color="text.secondary">
        Aucun élève n&apos;est disponible pour cette feuille de présence
      </Typography>
    </Box>
  ), [])

  return (
    <Box sx={{ p: 4, pr: 0, bgcolor: "white" }}>
      <AttendanceSheetHeader data={tabs[0].data} />
      <Typography
        variant="h6"
        align="center"
        sx={{
          fontWeight: "bold",
          mb: 2,
          color: "primary.main",
          textTransform: "uppercase",
        }}
      >
        ATTESTATION
        <br />
        DE PRÉSENCES DES ÉLÈVES
      </Typography>

      <Grid container spacing={2}>
        {transportFields.map((field) => (
          <Grid item xs={12} sm={4} key={field.name}>
            {renderField(field)}
          </Grid>
        ))}

        <Grid item xs={12}>
          <Typography
            sx={{
              fontSize: pxToRem(18),
              color: "primary.main",
              fontWeight: (theme) => theme.typography.fontWeightBold,
            }}
          >
            {"Informations des élèves"}
          </Typography>
        </Grid>

        <ConditionalComponent
          isValid={hasPassengers}
          defaultComponent={EmptyStateComponent}
        >
          <Grid container spacing={2} sx={{ p: 2 }}>
            {studentNamesFields.slice(0, passengers.length).map((field) => (
              <Grid item xs={12} sm={4} key={field.name}>
                {renderField(field)}
              </Grid>
            ))}

            <Grid item xs={12}>
              <StyledTableContainer>
                <Table size="small">
                  <TableHead>
                    <TableRow>
                      <HeaderCellWidthColor sx={{ borderTopLeftRadius: "10px" }} colSpan={2}></HeaderCellWidthColor>
                      {passengers.map((passenger) => (
                        <HeaderCellWidthColor
                          key={passenger.id}
                          colSpan={2}
                          align="center"
                        >
                          {`${passenger.firstName} ${passenger.lastName}`}
                        </HeaderCellWidthColor>
                      ))}
                    </TableRow>
                    <TableRow>
                      <HeaderCellWidthColor sx={{ borderBottomLeftRadius: "10px" }} colSpan={2}></HeaderCellWidthColor>
                      {passengers.map((_, index) => (
                        <React.Fragment key={`ar-${index}`}>
                          <HeaderCellWidthColor align="center">A</HeaderCellWidthColor>
                          <HeaderCellWidthColor align="center">R</HeaderCellWidthColor>
                        </React.Fragment>
                      ))}
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {days.map((day, index) => {
                      const uniqueKey = `day-${day.dayOfMonth}-${index}`

                      return (
                        <PresenceStyledRow key={uniqueKey}>
                          <HeaderRow sx={{ pr: 0 }}>{day.dayOfWeek || 'N/A'}</HeaderRow>
                          <HeaderRow sx={{ px: 1 }} align="center">
                            {day.dayOfMonth || 'N/A'}
                          </HeaderRow>
                          {passengers.map((passenger, passengerIndex) => {
                            const { outbound: isOutboundPresent, return: isReturnPresent } = getPassengerPresenceStatus(
                              day.passengerStatuses,
                              passenger.id
                            )


                            const attendanceKey = `attendance-${passenger.id}-${day.dayOfMonth}-${passengerIndex}`

                            return (
                              <React.Fragment key={attendanceKey}>
                                <TableCell align="center">
                                  {!day.weekend && day.dayOfMonth && (
                                    <CustomCheckbox
                                      checked={
                                        localAttendance[`${day.dayOfMonth}`]?.[`${passenger.id}-A`] ?? isOutboundPresent
                                      }
                                      onChange={() => handleAttendanceChange(day.dayOfMonth, passenger.id, 'A')}
                                      disabled={isReadOnly}
                                    />
                                  )}
                                </TableCell>
                                <TableCell align="center">
                                  {!day.weekend && day.dayOfMonth && (
                                    <CustomCheckbox
                                      checked={
                                        localAttendance[`${day.dayOfMonth}`]?.[`${passenger.id}-R`] ?? isReturnPresent
                                      }
                                      onChange={() => handleAttendanceChange(day.dayOfMonth, passenger.id, 'R')}
                                      disabled={isReadOnly}
                                    />
                                  )}
                                </TableCell>
                              </React.Fragment>
                            )
                          })}
                        </PresenceStyledRow>
                      )
                    })}
                  </TableBody>
                </Table>
              </StyledTableContainer>
            </Grid>
          </Grid>
        </ConditionalComponent>

        <Grid item xs={12}>
          {renderField(observationField)}
        </Grid>
        <Grid item xs={12} sm={6}>
          <SignatureField
            isReadOnly={true}
            hasSignature={false}
            title="Signature et Cachet de l'etablissement scolaire"
          />
        </Grid>
        <Grid item xs={12} sm={6}>
          <SignatureField
            isReadOnly={true}
            hasSignature={false}
            title="Signature et Cachet du transporteur"
          />
        </Grid>
      </Grid>
    </Box>
  )
}

export default React.memo(AttendanceSheetNotCher)