'use client';
import React, { useEffect, useState } from 'react';
import { ChevronDown, ChevronUp, Plus, Trash2 } from 'lucide-react';
import { Switch } from '@/components/ui/switch';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from '@/components/ui/select';
import { useRouter } from 'next/navigation';
import apis from '@/utils/apis';
import { useGlobalContext } from '@/context/Provider';
import { formatTimeToUTC, formatUTCToLocalTime } from '@/lib/utils';

interface TimeSlotUpdate {
  day: string;
  index: number;
  field: 'startTime' | 'endTime';
  value: string;
}
interface TimeSlot {
  startTime: string;
  endTime: string;
}

interface DaySettings {
  enabled: boolean;
  slots: TimeSlot[];
}

interface DaySettingsState {
  [key: string]: DaySettings;
}

const generateTimeSlots = () => {
  const slots = [];
  for (let hour = 0; hour < 24; hour++) {
    for (let minute = 0; minute < 60; minute += 30) {
      const time = `${hour.toString().padStart(2, '0')}:${minute
        .toString()
        .padStart(2, '0')}`;
      slots.push(time);
    }
  }
  return slots;
};

const EditTimings = () => {
  const router = useRouter();
  const { Toast, userInfo, setUserInfo } = useGlobalContext();
  const timeSlots = generateTimeSlots();
  const daysOfWeek = [
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday',
    'Sunday'
  ];

  const defaultDaySettings: DaySettingsState = daysOfWeek.reduce(
    (acc, day) => ({
      ...acc,
      [day]: {
        enabled: day === 'Monday',
        slots: [{ startTime: '09:00', endTime: '22:00' }]
      }
    }),
    {} as DaySettingsState
  );

  const [expandedDays, setExpandedDays] = useState(['Monday']);
  const [daySettings, setDaySettings] = useState<DaySettingsState>(defaultDaySettings);
  const [copyToAll, setCopyToAll] = useState(false);

  useEffect(() => {
    if (userInfo?.restaurant_id?.working_day && Array.isArray(userInfo.restaurant_id.working_day)) {
      // Transform the working_day array into your state structure
      const updatedSettings = userInfo.restaurant_id.working_day.reduce(
        (acc: DaySettingsState, item: any) => {
          const matchedDay = daysOfWeek.find(
            (d) => d.toLowerCase() === item.day?.toLowerCase()
          ) || item.day;
          if (matchedDay) {
            acc[matchedDay] = {
              enabled: !item.is_24_hrs,
              slots: item.is_24_hrs || !Array.isArray(item.timing) || item.timing.length === 0
                ? [{ startTime: '09:00', endTime: '22:00' }]
                : item.timing.map((timingSlot: any) => ({
                  startTime: formatUTCToLocalTime(timingSlot.start_time),
                  endTime: formatUTCToLocalTime(timingSlot.end_time)
                }))
            };
          }
          return acc;
        },
        { ...defaultDaySettings }
      );
      setDaySettings(updatedSettings);
    }
  }, [userInfo]);

  const toggleDay = (day: string): void => {
    setExpandedDays((prev: string[]) =>
      prev.includes(day)
        ? prev.filter((d: string) => d !== day)
        : [...prev, day]
    );
  };

  const toggleDayEnabled = (day: string): void => {
    setDaySettings((prev: DaySettingsState) => ({
      ...prev,
      [day]: {
        enabled: !prev[day]?.enabled,
        slots: prev[day]?.slots || [{ startTime: '09:00', endTime: '22:00' }]
      }
    }));
  };

  const addTimeSlot = (day: string): void => {
    setDaySettings((prev: DaySettingsState) => {
      const currentSlots = prev[day]?.slots || [];
      const availableSlot = getNextAvailableSlot(currentSlots);
      return {
        ...prev,
        [day]: {
          ...prev[day],
          enabled: prev[day]?.enabled ?? true,
          slots: [...currentSlots, availableSlot]
        }
      };
    });
  };

  const removeTimeSlot = (day: string, index: number): void => {
    setDaySettings((prev: DaySettingsState) => ({
      ...prev,
      [day]: {
        ...prev[day],
        slots: (prev[day]?.slots || []).filter((_, i) => i !== index)
      }
    }));
  };

  const updateTimeSlot = ({
    day,
    index,
    field,
    value
  }: TimeSlotUpdate): void => {
    setDaySettings((prev: DaySettingsState) => {
      const currentSlots = prev[day]?.slots || [];
      const existing = currentSlots[index];
      if (!existing) return prev;
      let updatedSlot: TimeSlot = { ...existing, [field]: value } as TimeSlot;

      // Auto-adjust counterpart to maintain start < end for a smoother UX
      if (updatedSlot.startTime && updatedSlot.endTime) {
        const startIdx = timeSlots.indexOf(updatedSlot.startTime);
        const endIdx = timeSlots.indexOf(updatedSlot.endTime);

        if (field === 'startTime') {
          if (endIdx !== -1 && startIdx !== -1 && startIdx >= endIdx) {
            const nextEnd = timeSlots[startIdx + 1];
            if (nextEnd) {
              updatedSlot.endTime = nextEnd;
            } else {
              Toast.error('No valid end time after selected start time');
              return prev;
            }
          }
        } else if (field === 'endTime') {
          if (endIdx !== -1 && startIdx !== -1 && startIdx >= endIdx) {
            const prevStart = timeSlots[endIdx - 1];
            if (prevStart) {
              updatedSlot.startTime = prevStart;
            } else {
              Toast.error('End time must be after start time');
              return prev;
            }
          }
        }

        const isDuplicate = currentSlots.some(
          (s, i) =>
            i !== index &&
            s.startTime === updatedSlot.startTime &&
            s.endTime === updatedSlot.endTime
        );
        if (isDuplicate) {
          Toast.error('Duplicate time slot is not allowed');
          return prev;
        }
      }

      return {
        ...prev,
        [day]: {
          ...prev[day],
          enabled: prev[day]?.enabled ?? true,
          slots: currentSlots.map((slot: TimeSlot, i: number) =>
            i === index ? updatedSlot : slot
          )
        }
      };
    });
  };

  const handleCopyToAllChange = (checked: boolean): void => {
    setCopyToAll(checked);
    if (checked) {
      const mondaySettings: DaySettings = daySettings['Monday'] || {
        enabled: true,
        slots: [{ startTime: '09:00', endTime: '22:00' }]
      };
      setDaySettings((prev: DaySettingsState) => {
        const newSettings: DaySettingsState = { ...prev };
        daysOfWeek.forEach((day: string) => {
          newSettings[day] = {
            ...mondaySettings,
            enabled: true
          };
        });
        return newSettings;
      });
    }
  };
  const transformDaySettings = (daySettings: any) => {
    const dayIds: { [key: string]: string } = {
      Monday: '1',
      Tuesday: '2',
      Wednesday: '3',
      Thursday: '4',
      Friday: '5',
      Saturday: '6',
      Sunday: '7'
    };

    const formatDateTime = (time: string) => `2024-01-01T${time}:00.000`;

    const workingDays = Object.entries(daySettings).map(([day, data]: any) => {
      const isEnabled = data?.enabled ?? false;
      const slots = data?.slots || [];
      const timing = isEnabled
        ? slots.map((slot: any) => ({
          start_time: formatTimeToUTC(slot.startTime),
          end_time: formatTimeToUTC(slot.endTime)
        }))
        : [];

      return {
        day,
        day_id: dayIds[day] || '1',
        is_24_hrs: timing.length === 0, // Set to true if no timing, false otherwise
        timing
      };
    });

    return { working_day: workingDays };
  };

  const handleSave = async () => {
    const formattedData = transformDaySettings(daySettings);
    try {
      const apiRes = await apis.restaurant.update(
        userInfo?.restaurant_id?._id,
        formattedData
      );
      if (apiRes) {
        Toast.success('Profile updated successfully');
        // setUserInfo(apiRes.data);
        if (apiRes.data) {
          setUserInfo((prev: any) => ({
            ...prev,
            restaurant_id: {
              ...prev.restaurant_id,
              ...apiRes.data
            }
          }));
        }
      } else {
        Toast.error(apiRes?.message);
      }
    } catch (error) {
      Toast.error('Failed to update profile');
    }
    // router.push(`/auth/complete-profile`)
    // Handle save logic here
  };

  const isTimeOverlapping = (
    time: string,
    slots: TimeSlot[] = [],
    indexToIgnore: number,
    isStart: boolean
  ): boolean => {
    return (slots || []).some((slot, index) => {
      if (index === indexToIgnore) return false;
      if (isStart) {
        return time >= slot.startTime && time < slot.endTime;
      } else {
        return time > slot.startTime && time <= slot.endTime;
      }
    });
  };

  const getNextAvailableSlot = (slots: TimeSlot[] = []): TimeSlot => {
    const allTimes = generateTimeSlots();
    for (let i = 0; i < allTimes.length - 1; i++) {
      const candidateStart = allTimes[i];
      const candidateEnd = allTimes[i + 1];
      const isOverlapping = (slots || []).some(
        (slot) =>
          !(candidateEnd <= slot.startTime || candidateStart >= slot.endTime)
      );
      if (!isOverlapping) {
        return { startTime: candidateStart, endTime: candidateEnd };
      }
    }
    return { startTime: '00:00', endTime: '01:00' };
  };

  return (
    <div className="mx-auto max-w-2xl space-y-4 ">
      <span className="text-[16px] font-[400] text-[#000]">
        Set your delivery hours so customers know when they can order.
      </span>
      {daysOfWeek.map((day) => (
        <div key={day} className="rounded-lg border">
          <div
            className="flex cursor-pointer items-center justify-between p-4"
            onClick={() => toggleDay(day)}
          >
            <div className="flex items-center gap-2">
              {expandedDays.includes(day) ? (
                <ChevronUp className="h-5 w-5" />
              ) : (
                <ChevronDown className="h-5 w-5" />
              )}
              <span className="font-medium">{day}</span>
            </div>
            <Switch
              checked={!!daySettings[day]?.enabled}
              onCheckedChange={() => toggleDayEnabled(day)}
            />
          </div>

          {expandedDays.includes(day) && daySettings[day]?.enabled && (
            <div className="space-y-4 border-t p-4">
              {(daySettings[day]?.slots || []).map((slot, index) => (
                <div key={index} className="flex items-center gap-4">
                  <Select
                    value={slot.startTime}
                    onValueChange={(value) =>
                      updateTimeSlot({ day, index, field: 'startTime', value })
                    }
                  >
                    <SelectTrigger className="w-32">
                      <SelectValue placeholder="Start Time" />
                    </SelectTrigger>
                    <SelectContent className="h-[40vh]">
                      {timeSlots.map((time) => {
                        const isDisabled = isTimeOverlapping(
                          time,
                          daySettings[day]?.slots || [],
                          index,
                          true
                        );
                        return (
                          <SelectItem
                            key={time}
                            value={time}
                            disabled={isDisabled}
                          >
                            {time}
                          </SelectItem>
                        );
                      })}
                    </SelectContent>
                  </Select>

                  <Select
                    value={slot.endTime}
                    onValueChange={(value) =>
                      updateTimeSlot({ day, index, field: 'endTime', value })
                    }
                  >
                    <SelectTrigger className="w-32">
                      <SelectValue placeholder="End Time" />
                    </SelectTrigger>
                    <SelectContent className="h-[40vh]">
                      {timeSlots.map((time) => (
                        <SelectItem key={time} value={time}>
                          {time}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>

                  {(daySettings[day]?.slots?.length || 0) > 1 && (
                    <Button
                      variant="ghost"
                      size="icon"
                      onClick={() => removeTimeSlot(day, index)}
                    >
                      <Trash2 className="h-4 w-4 text-red-500" />
                    </Button>
                  )}
                </div>
              ))}

              <Button
                variant="ghost"
                className="flex items-center gap-2 text-blue-500"
                onClick={() => addTimeSlot(day)}
              >
                <Plus className="h-4 w-4" />
                Add time slots
              </Button>

              {day === 'Monday' && (
                <div className="flex items-center gap-2 pt-4">
                  <Checkbox
                    id="copyAll"
                    checked={copyToAll}
                    onCheckedChange={handleCopyToAllChange}
                  />
                  <label htmlFor="copyAll" className="text-sm text-gray-600">
                    Copy above timings for all days
                  </label>
                </div>
              )}
            </div>
          )}
        </div>
      ))}

      <Button
        className="w-full"
        variant={'theme'} onClick={handleSave}
      >
        Save
      </Button>
    </div>
  );
};

// export default WeeklyTimeSlots;

export default EditTimings;
