'use client';

import React, { useState } from 'react';
import {
  Box,
  Card,
  CardContent,
  Typography,
  Grid,
  Chip,
  useTheme,
} from '@mui/material';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { fr } from 'date-fns/locale';
import { format, parse, isValid } from 'date-fns';
import {
  WorkSchedule,
  WeeklySchedule,
  DaySchedule,
} from '@/shared/types/client';
import { ModeType } from '@/shared/types/common';
import {
  Schedule,
  Visibility,
} from '@mui/icons-material';
import DayScheduleCard from './components/DayScheduleCard';
import ScheduleSummary from './components/ScheduleSummary';

interface WorkScheduleFormProps {
  schedule?: WorkSchedule;
  mode: ModeType;
  isReadOnly?: boolean;
  onChange: (schedule: WorkSchedule) => void;
  errors?: any;
  touched?: any;
  onBlur?: (fieldPath: string) => void;
}

const DAYS_OF_WEEK = [
  { key: 'monday', label: 'Lundi', shortLabel: 'Lun' },
  { key: 'tuesday', label: 'Mardi', shortLabel: 'Mar' },
  { key: 'wednesday', label: 'Mercredi', shortLabel: 'Mer' },
  { key: 'thursday', label: 'Jeudi', shortLabel: 'Jeu' },
  { key: 'friday', label: 'Vendredi', shortLabel: 'Ven' },
  { key: 'saturday', label: 'Samedi', shortLabel: 'Sam' },
  { key: 'sunday', label: 'Dimanche', shortLabel: 'Dim' },
];

const groupDaysInPairs = () => {
  const pairs = [] as typeof DAYS_OF_WEEK[];
  for (let i = 0; i < DAYS_OF_WEEK.length; i += 2) {
    const pair = DAYS_OF_WEEK.slice(i, i + 2);
    pairs.push(pair);
  }
  return pairs;
};

const DEFAULT_DAY_SCHEDULE: DaySchedule = {
  id: null,
  isWorkingDay: false,
  startTime: null,
  endTime: null,
  breakStartTime: null,
  breakEndTime: null,
  createdAt: null,
  updatedAt: null,
};

const DEFAULT_WEEKLY_SCHEDULE: WeeklySchedule = {
  id: null,
  monday: { ...DEFAULT_DAY_SCHEDULE, isWorkingDay: true },
  tuesday: { ...DEFAULT_DAY_SCHEDULE, isWorkingDay: true },
  wednesday: { ...DEFAULT_DAY_SCHEDULE, isWorkingDay: true },
  thursday: { ...DEFAULT_DAY_SCHEDULE, isWorkingDay: true },
  friday: { ...DEFAULT_DAY_SCHEDULE, isWorkingDay: true },
  saturday: { ...DEFAULT_DAY_SCHEDULE, isWorkingDay: false },
  sunday: { ...DEFAULT_DAY_SCHEDULE, isWorkingDay: false },
  createdAt: null,
  updatedAt: null,
};

export default function WorkScheduleForm({
  schedule,
  mode,
  isReadOnly = false,
  onChange,
  errors,
  touched,
  onBlur,
}: WorkScheduleFormProps) {
  const theme = useTheme();
  const [weeklySchedule, setWeeklySchedule] = useState<WeeklySchedule>(
    schedule?.weeklySchedule || DEFAULT_WEEKLY_SCHEDULE
  );

  const isViewMode = mode === 'view' || isReadOnly;

  const handleDayToggle = (dayKey: keyof WeeklySchedule) => {
    if (isViewMode) return;

    const daySchedule = weeklySchedule[dayKey];
    if (!daySchedule || typeof daySchedule === 'string') return;

    const updatedSchedule = {
      ...weeklySchedule,
      [dayKey]: {
        ...daySchedule,
        isWorkingDay: !daySchedule.isWorkingDay,
      },
    };

    setWeeklySchedule(updatedSchedule);
    onChange({
      id: schedule?.id,
      collaboratorId: schedule?.collaboratorId,
      weeklySchedule: updatedSchedule,
      createdAt: schedule?.createdAt,
      updatedAt: schedule?.updatedAt,
    });
  };

  const handleTimeChange = (
    dayKey: keyof WeeklySchedule,
    field: keyof DaySchedule,
    value: Date | null
  ) => {
    if (isViewMode) return;
  
    const daySchedule = weeklySchedule[dayKey];
    if (!daySchedule || typeof daySchedule === 'string') return;

    const timeString = value && isValid(value) ? format(value, 'HH:mm') : null;
    const updatedSchedule = {
      ...weeklySchedule,
      [dayKey]: {
        ...daySchedule,
        [field]: timeString,
      },
    };
  
    setWeeklySchedule(updatedSchedule);
    onChange({
      id: schedule?.id,
      collaboratorId: schedule?.collaboratorId,
      weeklySchedule: updatedSchedule,
      createdAt: schedule?.createdAt,
      updatedAt: schedule?.updatedAt,
    });
  };

  // notes non gérées ici

  const parseTimeString = (timeString: string | null): Date | null => {
    if (!timeString) return null;
    try {
      const parsed = parse(timeString, 'HH:mm', new Date());
      return isValid(parsed) ? parsed : null;
    } catch {
      return null;
    }
  };

  const getFieldError = (dayKey: string, fieldName: string): string | undefined => {
    const weeklyErrors = errors?.schedule?.weeklySchedule;
    if (!weeklyErrors) return undefined;

    const dayErrors = weeklyErrors[dayKey];
    if (!dayErrors) return undefined;

    if (typeof dayErrors === 'object' && dayErrors[fieldName]) {
      return dayErrors[fieldName];
    }

    if (typeof dayErrors === 'string') {
      const message: string = dayErrors;
      const messageLower = message.toLowerCase();
      const isPauseMessage = messageLower.includes('pause');

      if (isPauseMessage) {
        const dayData = weeklySchedule[dayKey as keyof WeeklySchedule] as DaySchedule | string | undefined;
        if (dayData && typeof dayData !== 'string') {
          const start = parseTimeString(dayData.startTime || null);
          const end = parseTimeString(dayData.endTime || null);
          const bStart = parseTimeString(dayData.breakStartTime || null);
          const bEnd = parseTimeString(dayData.breakEndTime || null);

          const isBreakOrderMsg = messageLower.includes('fin de pause') && messageLower.includes('début de pause');
          if (isBreakOrderMsg && fieldName === 'breakEndTime') return message;

          if (start && bStart && bStart < start && fieldName === 'breakStartTime') return message;
          if (end && bEnd && bEnd > end && fieldName === 'breakEndTime') return message;
        }
        return undefined;
      }

      if (fieldName === 'endTime') return message;
      return undefined;
    }

    return undefined;
  };

  // util non utilisé

  const handleFieldBlur = (dayKey: string, fieldName: string) => {
    if (onBlur) {
      onBlur(`schedule.weeklySchedule.${dayKey}.${fieldName}`);
    }
  };

  const getWorkingDaysCount = () => {
    return DAYS_OF_WEEK.reduce((count, d) => {
      const day = weeklySchedule[d.key as keyof WeeklySchedule];
      if (day && typeof day !== 'string' && (day as DaySchedule).isWorkingDay) {
        return count + 1;
      }
      return count;
    }, 0);
  };

  const getTotalWorkingHours = () => {
    let totalHours = 0;
    DAYS_OF_WEEK.forEach((d) => {
      const day = weeklySchedule[d.key as keyof WeeklySchedule];
      if (!day || typeof day === 'string') return;
      if (day.isWorkingDay && day.startTime && day.endTime) {
        const start = parseTimeString(day.startTime);
        const end = parseTimeString(day.endTime);
        if (start && end) {
          const diffMs = end.getTime() - start.getTime();
          const diffHours = diffMs / (1000 * 60 * 60);
          totalHours += diffHours;
        }
      }
    });
    return totalHours;
  };
  // rendu des journées délégué à DayScheduleCard

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={fr}>
      <Card
        elevation={2}
        sx={{
          width: '100%',
          borderRadius: 2,
          border: `1px solid ${theme.palette.divider}`,
          '&:hover': {
            boxShadow: theme.shadows[4],
          },
        }}
      >
        
        <CardContent sx={{ p: 3 }}>
          <Box sx={{ display: 'flex', alignItems: 'center', mb: 3 }}>
            <Schedule
              sx={{
                color: theme.palette.primary.main,
                mr: 1,
                fontSize: 28,
              }}
            />
            <Typography variant="h6" fontWeight="600" color="primary">
              Emploi du temps
            </Typography>
            {isViewMode && (
              <Chip
                icon={<Visibility />}
                label="Lecture seule"
                size="small"
                color="info"
                sx={{ ml: 2 }}
              />
            )}
          </Box>

          {errors?.schedule?.weeklySchedule && typeof errors.schedule.weeklySchedule === 'string' && (
            <Box sx={{ mb: 2 }}>
              <Typography color="error" variant="body2">
                {errors.schedule.weeklySchedule}
              </Typography>
            </Box>
          )}

          <ScheduleSummary
            workingDaysCount={getWorkingDaysCount()}
            totalWorkingHours={getTotalWorkingHours()}
          />

          <Grid container spacing={2}>
            {groupDaysInPairs().map((dayPair, pairIndex) => (
              <Grid item xs={12} key={`pair-${pairIndex}`}>
                <Grid container spacing={2}>
                  {dayPair.map((day) => {
                    const daySchedule = weeklySchedule[day.key as keyof WeeklySchedule];
                    if (!daySchedule || typeof daySchedule === 'string') return null;
                    return (
                      <Grid item xs={12} md={6} key={day.key}>
                        <DayScheduleCard
                          day={day as any}
                          daySchedule={daySchedule as DaySchedule}
                          isViewMode={isViewMode}
                          onToggle={handleDayToggle}
                          onTimeChange={handleTimeChange}
                          getFieldError={getFieldError}
                          onFieldBlur={handleFieldBlur}
                        />
                      </Grid>
                    );
                  })}
                </Grid>
              </Grid>
            ))}
          </Grid>
        </CardContent>
      </Card>
    </LocalizationProvider>
  );
}