import React, { useEffect } from 'react';
import { Table, TableHead, TableBody, TableCell, Typography } from '@mui/material';
import FontAwesome from '@/shared/components/fontawesome';
import { faCheck, faClock } from '@fortawesome/free-solid-svg-icons';
import { Box } from '@mui/system';
import {
  HeaderCell,
  HeaderCellWidthColor,
  HeaderRow,
  SensARCheckbox,
  StyledEstablishmentRow,
  StyledFirstRow,
  StyledSecondRow,
  StyledSubTableRow,
  StyledTableRow,
} from './style';
import { StyledTableContainer } from '@/shared/theme/css';
import { pxToRem } from '@/shared/theme/typography';
import { DaysOfWeek } from '@/shared/types/passenger';
import { WEEKDAYS_NOTCHER } from '@/shared/sections/establishment/attendance/utils/attendance-utils';
import { DAYS_OF_WEEK_FR } from '@/shared/sections/usager/components/usager-form/avenants-horaires/utils/converters';
import ConditionalComponent from '../table/ConditionalComponent';

export interface ScheduleHoursDTO {
  id?: number;
  dayOfWeek: DaysOfWeek;
  morningOpeningTime: string;
  eveningClosingTime: string;
  weekType?: 'pair' | 'impair';
}

interface ScheduleTableProps {
  onMultipleSelectionChange?: (args: { week: 'pair' | 'impair'; checked: boolean }) => void;
  title: string;
  defaultTime?: string;
  mode: 'time' | 'checkbox';
  scheduleData?: ScheduleHoursDTO[];
  onSelectionChange?: (selection: {
    week: 'pair' | 'impair';
    day: string;
    type: 'all' | 'ret';
    checked: boolean;
  }) => void;
  selectedDays?: {
    pair: { [key: string]: { all: boolean; ret: boolean } };
    impair: { [key: string]: { all: boolean; ret: boolean } };
  };
  isInEstablishment?: boolean;
  isRepresentative?: boolean;
  secoundaryColor?: boolean;
  actionButton?: React.ReactNode;
}

export const DAY_MAPPING: { [key: string]: DaysOfWeek } = {
  Lundi: DaysOfWeek.MONDAY,
  Mardi: DaysOfWeek.TUESDAY,
  Mercredi: DaysOfWeek.WEDNESDAY,
  Jeudi: DaysOfWeek.THURSDAY,
  Vendredi: DaysOfWeek.FRIDAY,
  Samedi: DaysOfWeek.SATURDAY,
  Dimanche: DaysOfWeek.SUNDAY,
};

export default function ScheduleTable({
  onMultipleSelectionChange,
  title,
  defaultTime = '08:00 AM',
  mode = 'time',
  onSelectionChange,
  scheduleData = [],
  selectedDays = {
    pair: {},
    impair: {},
  },
  isInEstablishment,
  isRepresentative,
  secoundaryColor,
  actionButton,
}: ScheduleTableProps) {
  const WEEKDAYS = mode === 'time' ? WEEKDAYS_NOTCHER : DAYS_OF_WEEK_FR;

  const formatTime = (timeString: string): string => {
    if (!timeString) return defaultTime;

    try {
      const timeParts = timeString.split(':');
      if (timeParts.length >= 2) {
        const hours = Number.parseInt(timeParts[0]);
        const minutes = timeParts[1];
        const ampm = hours >= 12 ? 'PM' : 'AM';
        const displayHours = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
        return `${displayHours.toString().padStart(2, '0')}:${minutes} ${ampm}`;
      }
      return timeString;
    } catch (error) {
      return defaultTime;
    }
  };

  const getScheduleForDay = (day: string, week?: 'pair' | 'impair'): ScheduleHoursDTO | null => {
    const dayOfWeek = DAY_MAPPING[day];

    if (isInEstablishment) {
      return scheduleData.find((schedule) => schedule.dayOfWeek === dayOfWeek) || null;
    } else {
      return (
        scheduleData.find(
          (schedule) => schedule.dayOfWeek === dayOfWeek && schedule.weekType === week
        ) || null
      );
    }
  };

  const renderCell = (week: 'pair' | 'impair', day: string, type: 'all' | 'ret') => {
    if (mode === 'time') {
      const daySchedule = getScheduleForDay(day, week);
      let displayTime = defaultTime;

      if (daySchedule) {
        if (isInEstablishment) {
          if (type === 'all') {
            displayTime = formatTime(daySchedule.morningOpeningTime);
          } else {
            displayTime = formatTime(daySchedule.eveningClosingTime);
          }
        } else {
          if (type === 'all') {
            displayTime = formatTime(daySchedule.morningOpeningTime);
          } else {
            displayTime = formatTime(daySchedule.eveningClosingTime);
          }
        }
      }

      return (
        <TableCell>
          <Box sx={{ whiteSpace: 'nowrap' }} display="flex" alignItems="center">
            <FontAwesome icon={faClock} color="primary.main" width={12} sx={{ mr: 1 }} />
            <Typography variant="caption">{displayTime}</Typography>
          </Box>
        </TableCell>
      );
    }

    const isChecked = selectedDays[week]?.[day]?.[type] || false;
    const cellSize = isRepresentative ? '16px' : '20px';
    return (
      <TableCell sx={{ p: isRepresentative ? '4px' : '8px' }} align="center">
        <Box sx={{ position: 'relative' }}>
          <SensARCheckbox
            checked={isChecked}
            sx={{ width: cellSize, height: cellSize }}
            onChange={(e) => {
              onSelectionChange?.({
                week,
                day,
                type,
                checked: e.target.checked,
              });
            }}
            size="small"
          />

          <FontAwesome
            sx={{
              color: 'white',
              position: 'absolute',
              top: isRepresentative ? '58%' : '50%',
              left: '50%',
              transform: 'translate(-50%, -50%)',
            }}
            width={isRepresentative ? 12 : 16}
            icon={faCheck}
          />
        </Box>
      </TableCell>
    );
  };

  const CellComponent = isInEstablishment && !secoundaryColor ? HeaderCell : HeaderCellWidthColor;
  const FirstRow = isInEstablishment && !secoundaryColor ? StyledEstablishmentRow : StyledFirstRow;
  const periods = isInEstablishment ? ['Matin', 'Soir'] : ['All', 'Ret'];
  const fontSize = isRepresentative ? pxToRem(13) : undefined;

  const isWeekFullySelected = (week: 'pair' | 'impair') =>
    WEEKDAYS.filter((item) => !['samedi', 'dimanche'].includes(item)).every(
      (day) => !!selectedDays?.[week]?.[day]?.all && !!selectedDays?.[week]?.[day]?.ret
    );

  return (
    <>
      <Box display="flex" justifyContent="space-between" alignItems="center">
        <Typography
          variant={isRepresentative ? 'h6' : 'h5'}
          sx={{
            mt: isInEstablishment ? 0 : 3,
            mb: 1,
            color: 'primary.main',
            fontWeight: (theme) => theme.typography.fontWeightBold,
          }}
        >
          {title}
        </Typography>
        {actionButton}
      </Box>
      <StyledTableContainer>
        <Table stickyHeader sx={{ mt: 1 }}>
          <TableHead>
            <StyledTableRow>
              <CellComponent
                sx={{ textAlign: 'left', px: 2, fontSize: fontSize }}
                applySecondaryColor={!isInEstablishment}
                rowSpan={2}
              >
                {isInEstablishment ? 'Jours' : 'Semaines'}
              </CellComponent>
              {WEEKDAYS.map((day) => (
                <CellComponent
                  sx={{ fontSize: fontSize }}
                  key={day}
                  colSpan={2}
                  applySecondaryColor={!isInEstablishment}
                >
                  {day}
                </CellComponent>
              ))}
            </StyledTableRow>
            <StyledSubTableRow>
              {WEEKDAYS.map((day) => (
                <React.Fragment key={`${day}-subheaders`}>
                  {periods.map((period) => (
                    <CellComponent
                      sx={{ fontSize: fontSize, px: '4px' }}
                      key={`${day}-${period}`}
                      applySecondaryColor={!isInEstablishment}
                    >
                      {period}
                    </CellComponent>
                  ))}
                </React.Fragment>
              ))}
            </StyledSubTableRow>
          </TableHead>
          <TableBody>
            <FirstRow>
              <HeaderRow sx={{ fontSize: fontSize, pl: 1, pr: 0 }} highlighted={!isInEstablishment}>
                <Box display="flex" alignItems="center" gap={1}>
                  <ConditionalComponent isValid={!isInEstablishment}>
                    <SensARCheckbox
                      checked={isWeekFullySelected('pair')}
                      onChange={(e) => {
                        onMultipleSelectionChange?.({ week: 'pair', checked: e.target.checked });
                      }}
                      size="small"
                    />
                  </ConditionalComponent>

                  <ConditionalComponent isValid={isInEstablishment as boolean}>
                    Horaires
                  </ConditionalComponent>

                  <ConditionalComponent isValid={!(isInEstablishment as boolean)}>
                    <>Semaine Paire</>
                  </ConditionalComponent>
                </Box>
              </HeaderRow>
              {WEEKDAYS.map((day) => (
                <React.Fragment key={`pair-${day}`}>
                  {renderCell('pair', day, 'all')}
                  {renderCell('pair', day, 'ret')}
                </React.Fragment>
              ))}
            </FirstRow>

            <ConditionalComponent isValid={!(isInEstablishment as boolean)}>
              <StyledSecondRow>
                <HeaderRow
                  sx={{ fontSize: fontSize, pl: 1, pr: 0 }}
                  highlighted={!isInEstablishment}
                >
                  <Box display="flex" alignItems="center" gap={1}>
                    <ConditionalComponent isValid={!isInEstablishment}>
                      <SensARCheckbox
                        checked={isWeekFullySelected('impair')}
                        onChange={(e) =>
                          onMultipleSelectionChange?.({ week: 'impair', checked: e.target.checked })
                        }
                        size="small"
                      />
                    </ConditionalComponent>
                    <>Semaine Impaire</>
                  </Box>
                </HeaderRow>
                {WEEKDAYS.map((day) => (
                  <React.Fragment key={`impair-${day}`}>
                    {renderCell('impair', day, 'all')}
                    {renderCell('impair', day, 'ret')}
                  </React.Fragment>
                ))}
              </StyledSecondRow>
            </ConditionalComponent>
          </TableBody>
        </Table>
      </StyledTableContainer>
    </>
  );
}
