'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 AuthLayout from '@/components/layout/layout';
import authBanner from '@/assets/images/AuthImages/timing.png';
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 WeeklyTimeSlots = () => {
  const router = useRouter();
  const { Toast, userInfo } = useGlobalContext();

  const timeSlots = generateTimeSlots();

  const daysOfWeek = [
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday',
    'Sunday'
  ];

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

  // 🔹 Convert API working_day -> local state
  const parseWorkingDays = (workingDays: any[]): DaySettingsState => {
    const state: DaySettingsState = {};
    daysOfWeek.forEach((day) => {
      const apiDay = workingDays.find((d) => d.day === day);
      if (apiDay) {
        state[day] = {
          enabled: !apiDay.is_24_hrs,
          slots:
            apiDay.timing.length > 0
              ? apiDay.timing.map((t: any) => ({
                startTime: formatUTCToLocalTime(t.start_time),
                endTime: formatUTCToLocalTime(t.end_time)
              }))
              : [{ startTime: '09:00', endTime: '23:00' }]
        };
      } else {
        state[day] = {
          enabled: false,
          slots: [{ startTime: '09:00', endTime: '23:00' }]
        };
      }
    });
    return state;
  };


  useEffect(() => {
    const token: any = sessionStorage.getItem('token');
    if (!token) {
      router.replace(`/auth/login`);
      return;
    }

    if (userInfo?.restaurant_id?.working_day) {
      setDaySettings(parseWorkingDays(userInfo.restaurant_id.working_day));
    } else {
      setDaySettings(
        daysOfWeek.reduce(
          (acc, day) => ({
            ...acc,
            [day]: {
              enabled: day === 'Monday',
              slots: [{ startTime: '09:00', endTime: '23:00' }]
            }
          }),
          {} as DaySettingsState
        )
      );
    }
  }, [userInfo, router]);

  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]: {
        ...prev[day],
        enabled: !prev[day].enabled
      }
    }));
  };

  const addTimeSlot = (day: string): void => {
    setDaySettings((prev: DaySettingsState) => {
      const availableSlot = getNextAvailableSlot(prev[day].slots);
      return {
        ...prev,
        [day]: {
          ...prev[day],
          slots: [...prev[day].slots, 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];
      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],
          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'];
      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 workingDays = Object.entries(daySettings).map(([day, data]: any) => {
      const timing = data.enabled
        ? data.slots.map((slot: any) => ({
          start_time: formatTimeToUTC(slot.startTime),
          end_time: formatTimeToUTC(slot.endTime)
        }))
        : [];

      return {
        day,
        day_id: dayIds[day],
        is_24_hrs: timing.length === 0,
        timing
      };
    });

    return { working_day: workingDays };
  };

  const handleSave = async () => {
    const res_id: any = sessionStorage.getItem('resId');
    // Prevent saving if any day has duplicate slots
    for (const day of daysOfWeek) {
      const settings = daySettings[day];
      if (!settings?.enabled) continue;
      const seen = new Set<string>();
      for (const s of settings.slots) {
        const key = `${s.startTime}-${s.endTime}`;
        if (seen.has(key)) {
          Toast.error(`Duplicate time slots found on ${day}`);
          return;
        }
        seen.add(key);
      }
    }

    const formattedData = transformDaySettings(daySettings);
    try {
      const apiRes = await apis.restaurant.update(res_id, formattedData);
      const isFoodDelivery = userInfo?.isFoodDelivery;
      const isDineOut = userInfo?.isDineOut;

      const type = userInfo?.restaurant_id?.type;
      const isDineOutCategory = type === "dine-out";

      if (apiRes) {
        if (userInfo?.restaurant_id?.restaurant_type !== 'home-cooked-meal') {
          sessionStorage.setItem('restaurant', 'complete');
        }

        // Redirect to dineouttimings if isDineOut is enabled and it's not a grocery store
        if (isDineOut && type !== 'grocery') {
          router.replace('/auth/restaurant/dineouttimings');
        } else {
          router.replace(`/auth/complete-profile`);
        }
        Toast.success('Profile updated successfully');
      } else {
        Toast.error(apiRes?.message);
      }
    } catch (error) {
      Toast.error('Failed to update profile');
    }
  };

  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">
      {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-[30vh]">
                      {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-[30vh]">
                      {timeSlots.map((time) => {
                        const isDisabled = isTimeOverlapping(
                          time,
                          daySettings[day].slots,
                          index,
                          false
                        );
                        return (
                          <SelectItem
                            key={time}
                            value={time}
                            disabled={isDisabled}
                          >
                            {time}
                          </SelectItem>
                        );
                      })}
                    </SelectContent>
                  </Select>

                  {daySettings[day].slots.length > 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-gray-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="h-11 w-full"
        variant={'theme'} onClick={handleSave}
      >
        Save
      </Button>
    </div>
  );
};

export default function BankDetails() {
  return (
    <AuthLayout
      title="Vendor delivery Timings"
      des="Set your delivery hours so customers know when they can order"
      image={authBanner.src}
    >
      <WeeklyTimeSlots />
    </AuthLayout>
  );
}
