"use client"

import { useState, useEffect, useCallback, useMemo } from "react"
import React from "react"
import { Box, Typography, Grid, Table, TableBody, TableCell, TableHead } from "@mui/material"
import FormField from "@/shared/components/form/form-field"
import type { FormFieldType, ModeType } from "@/shared/types/common"
import { studentFields, schoolFields, summaryFields, signatureFields } 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 { BaseStyledRow, PresenceStyledRow } from "@/shared/sections/contract/styles"
import { CustomCheckbox } from "@/shared/components/form/custom-checkbox"
import SignatureField from "@/shared/sections/avenant/components/signature-field"
import { convertMonthToNumber, formatDateFrench, isEqual, WEEKDAYS_CHER } from "../utils/attendance-utils"
import ConditionalComponent from "@/shared/components/table/ConditionalComponent"
import { IAttendanceSheetCher } from "@/shared/types/attendance-sheet"
import { format } from 'date-fns'
import AttendanceSheetHeader from "./AttendanceSheetHeader"

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

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

function AttendanceSheetCher({
  tabs,
  tab,
  mode = "edit",
  handleFormChange,
  attendance,
  onAttendanceChange,
  onAttendanceUpdate
}: AttendanceSheetProps) {
  const [localAttendance, setLocalAttendance] = useState<Record<number, Record<string, Record<string, boolean>>>>(
    attendance || {}
  )
  const [isInitialized, setIsInitialized] = useState(false)
  const isReadOnly = tab.isReadOnly || mode === "view"
  const fieldsReadOnly = true;
  const tableReadOnly = mode === "view";
  const today = format(new Date(), 'yyyy-MM-dd')
  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 passenger = useMemo(() => passengers[0], [passengers])
  const hasPassengers = passengers.length > 0
  const weeklyDates = useMemo(() => {
    const weeks = []
    for (let i = 0; i < days.length; i += 7) {
      const weekDays = days.slice(i, i + 7)
      if (weekDays.length > 0) {
        weeks.push({
          start: weekDays[0]?.dayOfMonth || 0,
          end: weekDays[weekDays.length - 1]?.dayOfMonth || 0
        })
      }
    }
    return weeks
  }, [days])

  const stats = useMemo(() => {
    const totalDays = days.filter(d => !d.weekend && d.dayOfMonth).length
    const tabAttendance = localAttendance[tab.id] || {}
    const presentCount = Object.values(tabAttendance).reduce((count, dayData) => {
      return count + Object.values(dayData).filter(value => value).length
    }, 0)
    const totalPossiblePresences = WEEKDAYS_CHER.length * weeklyDates.length * 2

    return {
      joursClasse: totalDays.toString(),
      joursPresence: presentCount.toString(),
      joursAbsence: (totalPossiblePresences - presentCount).toString(),
      transportAR: (totalDays * 2).toString()
    }
  }, [days, localAttendance, tab.id, weeklyDates.length])

  const mappedData = useMemo(() => {
    if (!passenger) return tab.data

    const establishment = tab.data.establishment

    return {
      ...tab.data,
      nom: passenger.lastName,
      prenom: passenger.firstName,
      etablissement: establishment?.establishmentName || '',
      adresse: establishment?.address ?
        `${establishment.address.street}, ${establishment.address.zipCode} ${establishment.address.city}` : '',
      telephone: establishment?.fax || '',
      circuit: tab.data.circuit,
      departement: tab.data.departement,
      completionDate: today,
      ...stats
    }
  }, [tab.data, passenger, stats, today])
  useEffect(() => {
    if (!isInitialized && days.length > 0 && weeklyDates.length > 0 && passenger) {
      const initialAttendance: Record<number, Record<string, Record<string, boolean>>> = {
        [tab.id]: {}
      }

      WEEKDAYS_CHER.forEach(weekday => {
        initialAttendance[tab.id][weekday] = {}
        weeklyDates.forEach((_, weekIndex) => {
          const weekDayIndex = WEEKDAYS_CHER.indexOf(weekday)
          const dayIndex = weekIndex * 7 + weekDayIndex
          const currentDay = days[dayIndex]

          if (currentDay && passenger) {

            const passengerStatus = currentDay.passengerStatuses?.[passenger.id] as any

            let isOutboundPresent = true
            let isReturnPresent = true

            if (passengerStatus && typeof passengerStatus === 'object') {
              isOutboundPresent = passengerStatus.outbound !== undefined ? passengerStatus.outbound : true
              isReturnPresent = passengerStatus.return !== undefined ? passengerStatus.return : true
            }

            initialAttendance[tab.id][weekday][`${weekIndex}-0`] = isOutboundPresent
            initialAttendance[tab.id][weekday][`${weekIndex}-1`] = isReturnPresent
          } else {
            initialAttendance[tab.id][weekday][`${weekIndex}-0`] = true
            initialAttendance[tab.id][weekday][`${weekIndex}-1`] = true
          }
        })
      })

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

      if (handleFormChange) {
        handleFormChange(tab.id, {
          ...tab.data,
          ...stats
        })
      }
    }
  }, [days, weeklyDates, passenger, isInitialized, attendance, onAttendanceChange, handleFormChange, tab.id, tab.data, stats])
  useEffect(() => {
    if (isInitialized && attendance && !isEqual(attendance, localAttendance)) {
      setLocalAttendance(attendance)
    }
  }, [attendance, isInitialized])
  const handleAttendanceChange = useCallback(
    async (tabId: number, weekday: string, colIndex: number, row: number) => {
      try {
        if (colIndex < 0 || row < 0 || !weekday) {
          console.error('Paramètres invalides:', { tabId, weekday, colIndex, row })
          return
        }

        const weekDayIndex = WEEKDAYS_CHER.indexOf(weekday)
        if (weekDayIndex === -1) {
          console.error('Jour de la semaine invalide:', weekday)
          return
        }

        const dayIndex = colIndex * 7 + weekDayIndex
        const currentDay = days[dayIndex]

        if (!currentDay || !passenger) {
          console.error('Jour ou passager invalide:', { currentDay, passenger })
          return
        }
        let defaultValue = true
        const passengerStatus = currentDay.passengerStatuses?.[passenger.id] as any
        if (passengerStatus && typeof passengerStatus === 'object') {
          defaultValue = row === 0
            ? (passengerStatus.outbound !== undefined ? passengerStatus.outbound : true)
            : (passengerStatus.return !== undefined ? passengerStatus.return : true)
        }

        const attendanceKey = `${colIndex}-${row}`
        const currentValue = localAttendance[tabId]?.[weekday]?.[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(currentDay.dayOfMonth).padStart(2, '0')}`

        const isAbsent = !newValue
        const tripType = row === 0 ? 'A' : 'R'

        await onAttendanceUpdate(passenger.id, date, isAbsent, tripType)

        setLocalAttendance(prev => {
          const newAttendance = {
            ...prev,
            [tabId]: {
              ...prev[tabId],
              [weekday]: {
                ...prev[tabId]?.[weekday],
                [attendanceKey]: newValue
              }
            }
          }

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

          if (handleFormChange) {
            requestAnimationFrame(() => {
              handleFormChange(tabId, {
                ...tab.data,
                ...stats
              })
            })
          }

          return newAttendance
        })
      } catch (error) {
        console.error('Erreur lors de la mise à jour du statut de présence:', error)
      }
    },
    [days, passenger, localAttendance, tab.data, stats, onAttendanceChange, handleFormChange, onAttendanceUpdate]
  )
  const renderField = useCallback(
    (field: FormFieldType<IAttendanceSheetCher>) => (
      <FormField
        key={field.name}
        field={field}
        value={mappedData[field.name as keyof typeof mappedData] || ''}
        onChange={() => void 0}
        isReadOnly={fieldsReadOnly}
        isDrawerElement={true}
      />
    ),
    [mappedData, fieldsReadOnly]
  )

  const tabAttendance = useMemo(() => localAttendance[tab.id] || {}, [localAttendance, tab.id])

  const getCheckedValue = useCallback((weekday: string, colIndex: number, row: number) => {
    const weekDayIndex = WEEKDAYS_CHER.indexOf(weekday)
    const dayIndex = colIndex * 7 + weekDayIndex
    const currentDay = days[dayIndex]

    if (currentDay && passenger) {
      const passengerStatus = currentDay.passengerStatuses?.[passenger.id] as any

      let defaultValue = true

      if (passengerStatus && typeof passengerStatus === 'object') {
        defaultValue = row === 0 ?
          (passengerStatus.outbound !== undefined ? passengerStatus.outbound : true) :
          (passengerStatus.return !== undefined ? passengerStatus.return : true)
      }
      return tabAttendance[weekday]?.[`${colIndex}-${row}`] ?? defaultValue
    }
    return tabAttendance[weekday]?.[`${colIndex}-${row}`] ?? true
  }, [days, passenger, tabAttendance])
  const EmptyStudentsComponent = useMemo(() => (
    <Box sx={{
      display: 'flex',
      justifyContent: 'center',
      alignItems: 'center',
      height: '200px',
      backgroundColor: 'background.paper',
      borderRadius: 1,
      p: 3,
      border: '1px dashed',
      borderColor: 'divider'
    }}>
      <Typography variant="h6" color="text.secondary" textAlign="center">
        Aucun élève n&apos;est disponible pour cette feuille de présence
      </Typography>
    </Box>
  ), []);
  return (
    <Box sx={{ p: 3, 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} sx={{ mb: 3 }}>
        {schoolFields.map((field) => (
          <Grid item xs={12} sm={6} key={field.name}>
            {renderField(field)}
          </Grid>
        ))}

        <Grid item xs={12}>
          <Typography
            sx={{
              fontSize: pxToRem(18),
              color: "primary.main",
              fontWeight: (theme) => theme.typography.fontWeightBold,
            }}
          >
            {"Informations d'élève"}
          </Typography>
        </Grid>
        <ConditionalComponent
          isValid={hasPassengers}
          defaultComponent={EmptyStudentsComponent}
        >
          <>
            {studentFields.map((field) => (
              <Grid item xs={12} sm={6} key={field.name}>
                {renderField(field)}
              </Grid>
            ))}
          </>
        </ConditionalComponent>
      </Grid>

      <Box sx={{ mb: 3 }}>
        <Typography
          sx={{
            mb: 1,
            fontSize: pxToRem(16),
            color: "primary.main",
            fontWeight: 500,
            display: "flex",
            justifyContent: "center",
          }}
        >
          {tab.data.month} {tab.data.year}
        </Typography>

        <StyledTableContainer>
          <Table size="small">
            <TableHead>
              <BaseStyledRow>
                <HeaderCellWidthColor></HeaderCellWidthColor>
                {weeklyDates.map((dateRange, index) => (
                  <HeaderCellWidthColor
                    align="center"
                    key={`date-range-${index}-${dateRange.start}-${dateRange.end}`}
                    colSpan={2}
                  >
                    Date Du: {dateRange.start} Au {dateRange.end}
                  </HeaderCellWidthColor>
                ))}
              </BaseStyledRow>
            </TableHead>
            <TableBody>
              {WEEKDAYS_CHER.map((weekday) => (
                <PresenceStyledRow key={`weekday-${weekday}`}>
                  <HeaderRow>{weekday}</HeaderRow>
                  {weeklyDates.map((_, colIndex) => (
                    <React.Fragment key={`fragment-${weekday}-${colIndex}`}>
                      <TableCell key={`cell-${weekday}-${colIndex}-0`} align="center">
                        <CustomCheckbox
                          checked={getCheckedValue(weekday, colIndex, 0)}
                          onChange={() => handleAttendanceChange(tab.id, weekday, colIndex, 0)}
                          disabled={isReadOnly}
                        />
                      </TableCell>
                      <TableCell key={`cell-${weekday}-${colIndex}-1`} align="center">
                        <CustomCheckbox
                          checked={getCheckedValue(weekday, colIndex, 1)}
                          onChange={() => handleAttendanceChange(tab.id, weekday, colIndex, 1)}
                          disabled={isReadOnly}
                        />
                      </TableCell>
                    </React.Fragment>
                  ))}
                </PresenceStyledRow>
              ))}
            </TableBody>
          </Table>
        </StyledTableContainer>
      </Box>

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

        {signatureFields.map((field) => (
          <Grid item xs={12} sm={6} key={field.name}>
            {renderField(field)}
          </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(AttendanceSheetCher)