"use client"

import { useEffect, useState } from "react"
import { Typography, Grid, IconButton, Button } from "@mui/material"
import FontAwesome from "../../../../../components/fontawesome/fontawesome"
import { faClock, faCopy, faPlus, faRotateRight, faTimes } from "@fortawesome/free-solid-svg-icons"
import { alpha, Box } from "@mui/system"
import { StyledTimePicker } from "@/shared/theme/css"
import CustomTooltip from "@/shared/components/tooltips/tooltip-custom"
import { LocalizationProvider } from "@mui/x-date-pickers"
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"
import dayjs from "dayjs"
import "dayjs/locale/fr"
import { DAYS } from "@/shared/_mock/_usagers"
import { TimeValue } from "@/shared/types/usager"
import { MOCKED_SCHEDULE_DATA } from "@/shared/_mock/_avenants"
import ConditionalComponent from "@/shared/components/table/ConditionalComponent"
import { ScheduleDTO } from "@/shared/types/amendment"

export interface WeeklyScheduleType {
  pair: {
    [key: string]: {
      morning: { aller: TimeValue; retour?: TimeValue }
      evening: { aller?: TimeValue; retour: TimeValue }
    }
  }
  impair: {
    [key: string]: {
      morning: { aller: TimeValue; retour?: TimeValue }
      evening: { aller?: TimeValue; retour: TimeValue }
    }
  }
}

interface WeekScheduleProps {
  type: "pair" | "impair"
  values: {
    [key: string]: {
      morning: { aller: TimeValue; retour?: TimeValue }
      evening: { aller?: TimeValue; retour: TimeValue }
    }
  }
  onChange: (day: string, period: 'morning' | 'evening', type: "aller" | "retour", value: TimeValue) => void
  onCopy: () => void
  onReset: (periodType: 'morning' | 'evening') => void
  isReadOnly: boolean
}

interface HorairesSpecifiqueTabsProps {
  isReadOnly: boolean
  withData: boolean
  title: string
  schedules?: ScheduleDTO[]
}

dayjs.locale("fr")

const CustomTimeIcon = () => <FontAwesome icon={faClock} sx={{ color: "primary.main" }} />

function WeekSchedule({ type, values, onChange, onCopy, onReset, isReadOnly }: WeekScheduleProps) {
  const handleAddField = (day: string, period: 'morning' | 'evening', field: 'aller' | 'retour') => {
    const defaultTime = dayjs().hour(8).minute(0);
    onChange(day, period, field, defaultTime);
    if (period === 'morning' && field === 'retour') {
      onChange(day, 'evening', 'aller', defaultTime);
    }
  }

  const handleRemoveField = (day: string, period: 'morning' | 'evening', field: 'aller' | 'retour') => {
    if ((period === 'morning' && field === 'retour') || (period === 'evening' && field === 'aller')) {
      onChange(day, 'morning', 'retour', null);
      onChange(day, 'evening', 'aller', null);
    } else {
      onChange(day, period, field, null);
    }
  }

  return (
    <Grid spacing={6} sx={{ mx: "5%", mt: 4 }}>
      <Box sx={{ display: "flex", gap: 1 }}>
        <Typography
          variant="h5"
          sx={{
            color: "primary.main",
            fontWeight: (theme) => theme.typography.fontWeightBold,
          }}
        >
          {`Semaine ${type === "pair" ? "paire" : "impaire"}`}
        </Typography>
        <CustomTooltip title="Dupliquer la semaine" arrow>
          <IconButton onClick={onCopy} size="small">
            <FontAwesome color={"primary.main"} icon={faCopy} width={18} />
          </IconButton>
        </CustomTooltip>
      </Box>

      <Grid container spacing={"5%"}>
        {(['morning', 'evening'] as const).map((period) => (
          <Grid item xs={12} md={6} key={period}>
            <Box sx={{ mb: 2, display: 'flex', alignItems: 'center', gap: 1 }}>
              <Typography variant="h6" color={(theme) => alpha(theme.palette.text.secondary, 0.8)}>
                {period === 'morning' ? 'Matin' : 'Soir'}
              </Typography>
              <CustomTooltip title={`Réinitialiser le ${period === 'morning' ? 'matin' : 'soir'}`} arrow>
                <IconButton onClick={() => onReset(period)} size="small">
                  <FontAwesome color={(theme) => alpha(theme.palette.text.secondary, 0.8)} icon={faRotateRight} width={18} />
                </IconButton>
              </CustomTooltip>
            </Box>
            {DAYS.map((day) => {
              const dayKey = day.toLowerCase()
              const periodData = values[dayKey]?.[period]

              return (
                <Box key={`${dayKey}-${period}`} sx={{ mb: (!periodData?.retour && period === 'morning') ? '3.1px' : 4 }}>
                  <ConditionalComponent isValid={period === 'morning'}
                    defaultComponent={
                      <Box sx={{ display: periodData?.aller ? 'flex' : 'block', gap: 1, width: '100%' }}>
                        <ConditionalComponent isValid={!!periodData?.aller}>

                          <LocalizationProvider dateAdapter={AdapterDayjs}>
                            <StyledTimePicker
                              label={day + " (Aller)"}
                              value={periodData?.aller}
                              onChange={(v) => onChange(dayKey, period, 'aller', v)}
                              readOnly={isReadOnly}
                              slots={{ openPickerIcon: CustomTimeIcon }}
                              slotProps={{
                                textField: { fullWidth: true, placeholder: "Sélectionner l'heure" },
                              }}
                              views={['hours', 'minutes']}
                              format="HH:mm"
                            />
                          </LocalizationProvider>
                        </ConditionalComponent>

                        <LocalizationProvider dateAdapter={AdapterDayjs}>
                          <StyledTimePicker
                            label={day + " (Retour)"}
                            value={periodData?.retour || null}
                            onChange={(v) => onChange(dayKey, period, 'retour', v)}
                            readOnly={isReadOnly}
                            slots={{ openPickerIcon: CustomTimeIcon }}
                            slotProps={{
                              textField: { fullWidth: true, placeholder: "Sélectionner l'heure" },
                            }}
                            views={['hours', 'minutes']}
                            format="HH:mm"
                          />
                        </LocalizationProvider>


                      </Box>
                    }
                  >
                    <Box sx={{ display: periodData?.retour ? 'flex' : 'block', gap: 1, width: '100%' }}>
                      <Box sx={{ flex: 1 }}>
                        <LocalizationProvider dateAdapter={AdapterDayjs}>
                          <StyledTimePicker
                            label={day + " (Aller)"}
                            value={periodData?.aller || null}
                            onChange={(v) => onChange(dayKey, period, 'aller', v)}
                            readOnly={isReadOnly}
                            slots={{ openPickerIcon: CustomTimeIcon }}
                            slotProps={{
                              textField: { fullWidth: true, placeholder: "Sélectionner l'heure" },
                            }}
                            views={['hours', 'minutes']}
                            format="HH:mm"
                          />
                        </LocalizationProvider>
                        <ConditionalComponent isValid={!periodData?.retour}>
                          <Button
                            startIcon={<FontAwesome width={14} icon={faPlus} />}
                            onClick={() => handleAddField(dayKey, period, 'retour')}
                            sx={{ color: (theme) => theme.palette.primary.main, fontSize: "12px" }}
                            size="small"
                          >
                            Ajouter retour
                          </Button>
                        </ConditionalComponent>
                      </Box>

                      <ConditionalComponent isValid={!!periodData?.retour}>
                        <Box sx={{ display: 'flex', gap: 1, flex: 1, alignItems: 'center' }}>
                          <LocalizationProvider dateAdapter={AdapterDayjs}>
                            <StyledTimePicker
                              label={day + " (Retour)"}
                              value={periodData?.retour}
                              onChange={(v) => onChange(dayKey, period, 'retour', v)}
                              readOnly={isReadOnly}
                              slots={{ openPickerIcon: CustomTimeIcon }}
                              slotProps={{
                                textField: { fullWidth: true, placeholder: "Sélectionner l'heure" },
                              }}
                              views={['hours', 'minutes']}
                              format="HH:mm"
                            />
                          </LocalizationProvider>
                          <IconButton
                            onClick={() => handleRemoveField(dayKey, period, 'retour')}
                            sx={{ color: (theme) => theme.palette.error.main, p: 0 }}
                          >
                            <FontAwesome icon={faTimes} />
                          </IconButton>
                        </Box>
                      </ConditionalComponent>
                    </Box>
                  </ConditionalComponent>
                </Box>
              )
            })}
          </Grid>
        ))}
      </Grid>
    </Grid>
  )
}

// Function to map ScheduleDTO[] to WeeklyScheduleType
const mapSchedulesToWeeklySchedule = (schedules: ScheduleDTO[]): WeeklyScheduleType => {
  const weeklySchedule: WeeklyScheduleType = {
    pair: {},
    impair: {},
  };

  // Day mapping from English to French
  const dayMapping: Record<string, string> = {
    'MONDAY': 'lundi',
    'TUESDAY': 'mardi',
    'WEDNESDAY': 'mercredi',
    'THURSDAY': 'jeudi',
    'FRIDAY': 'vendredi',
    'SATURDAY': 'samedi',
    'SUNDAY': 'dimanche'
  };

  schedules.forEach(schedule => {
    const dayKey = dayMapping[schedule.day];
    if (!dayKey) return;

    // Parse time strings to dayjs objects
    const departureTime = dayjs(schedule.departureTime, 'HH:mm');
    const arrivalTime = dayjs(schedule.arrivalTime, 'HH:mm');

    // Determine if it's morning or evening based on time
    const isMorning = departureTime.hour() < 12;
    const period = isMorning ? 'morning' : 'evening';

    // Determine if it's aller or retour based on direction
    const isAller = schedule.direction === 'OUTBOUND';
    const type = isAller ? 'aller' : 'retour';

    // For now, we'll put all schedules in both pair and impair weeks
    // In a real implementation, you might want to differentiate based on some criteria
    ['pair', 'impair'].forEach(weekType => {
      if (!weeklySchedule[weekType as keyof WeeklyScheduleType][dayKey]) {
        weeklySchedule[weekType as keyof WeeklyScheduleType][dayKey] = {
          morning: { aller: null },
          evening: { retour: null }
        };
      }

      if (period === 'morning') {
        weeklySchedule[weekType as keyof WeeklyScheduleType][dayKey].morning[type as 'aller'] = departureTime;
      } else {
        weeklySchedule[weekType as keyof WeeklyScheduleType][dayKey].evening[type as 'retour'] = arrivalTime;
      }
    });
  });

  return weeklySchedule;
};

export default function HorairesSpecifiqueTabs({ isReadOnly, title, withData, schedules }: HorairesSpecifiqueTabsProps) {
  const [selectedDays, setSelectedDays] = useState<WeeklyScheduleType>({
    pair: {},
    impair: {},
  })

  useEffect(() => {
    if (withData) {
      if (schedules) {
        setSelectedDays(mapSchedulesToWeeklySchedule(schedules))
      } else {
        setSelectedDays(MOCKED_SCHEDULE_DATA)
      }
    }
  }, [withData, schedules])

  const handleChange = (
    weekType: "pair" | "impair",
    day: string,
    period: 'morning' | 'evening',
    type: "aller" | "retour",
    value: TimeValue
  ) => {
    setSelectedDays(prev => ({
      ...prev,
      [weekType]: {
        ...prev[weekType],
        [day]: {
          ...(prev[weekType][day] || { morning: { aller: null }, evening: { retour: null } }),
          [period]: {
            ...(prev[weekType][day]?.[period] || {}),
            [type]: value
          }
        }
      }
    }))
  }

  const handleCopy = (fromType: "pair" | "impair") => {
    setSelectedDays(prev => ({
      ...prev,
      [fromType === "pair" ? "impair" : "pair"]: prev[fromType]
    }))
  }

  const handleReset = (weekType: "pair" | "impair", period: 'morning' | 'evening') => {
    setSelectedDays(prev => {
      const updatedDays = Object.entries(prev[weekType]).reduce((acc, [day, data]) => ({
        ...acc,
        [day]: {
          ...data,
          [period]: period === "morning" ? { aller: null, retour: data[period].retour } : { aller: data[period].aller, retour: null }
        }
      }), {})

      return {
        ...prev,
        [weekType]: updatedDays
      }
    })
  }

  return (
    <Box>
      <Typography
        variant="h5"
        sx={{
          color: "primary.main",
          fontWeight: "bold",
          mb: 4,
        }}
      >
        {title}
      </Typography>
      <WeekSchedule
        type="pair"
        values={selectedDays.pair}
        onChange={(day, period, type, value) => handleChange("pair", day, period, type, value)}
        onCopy={() => handleCopy("pair")}
        onReset={(period) => handleReset("pair", period)}
        isReadOnly={isReadOnly}
      />

      <WeekSchedule
        type="impair"
        values={selectedDays.impair}
        onChange={(day, period, type, value) => handleChange("impair", day, period, type, value)}
        onCopy={() => handleCopy("impair")}
        onReset={(period) => handleReset("impair", period)}
        isReadOnly={isReadOnly}
      />
    </Box>
  )
}
