import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { tripPlacesApi } from '@/db/api';
import { useToast } from '@/hooks/use-toast';
import { assignTimeBlocks, type TimeBlock } from '@/lib/time-blocks';
import { TimelineBlock, TripDay, TripPlace } from '@/types/trip-ui';
import { TripDataContext } from './TripDataContext';

interface TripTimelineContextType {
  activeDayId: string | null;
  activeDay: TripDay | null;
  activeDayPlaces: TripPlace[];
  activeDayTimelineBlocks: TimelineBlock[];
  setActiveDayId: (dayId: string | null) => void;
  reorderPlaces: (dayId: string, places: TripPlace[]) => Promise<void>;
}

export const TripTimelineContext = createContext<TripTimelineContextType | undefined>(undefined);

export const TripTimelineProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const { trip, loadTrip } = useContext(TripDataContext) || {};
  const { toast } = useToast();
  const [activeDayId, setActiveDayIdState] = useState<string | null>(null);

  const setActiveDayId = useCallback((dayId: string | null) => {
    setActiveDayIdState(dayId);
    if (trip?.id) {
      if (dayId) {
        localStorage.setItem(`trip_active_day_${trip.id}`, dayId);
      } else {
        localStorage.removeItem(`trip_active_day_${trip.id}`);
      }
    }
  }, [trip?.id]);

  useEffect(() => {
    if (!trip || !trip.days || trip.days.length === 0) {
      if (activeDayId) setActiveDayIdState(null);
      return;
    }

    const storedDayId = localStorage.getItem(`trip_active_day_${trip.id}`);
    const isCurrentValid = trip.days.some(day => day.id === activeDayId);
    const isStoredValid = trip.days.some(day => day.id === storedDayId);

    if (!activeDayId || !isCurrentValid) {
      if (storedDayId && isStoredValid) {
        setActiveDayIdState(storedDayId);
      } else if (trip.days.length > 0) {
        setActiveDayId(trip.days[0].id);
      }
    }
  }, [trip, activeDayId, setActiveDayId]);

  const activeDay = useMemo(() => {
    if (!trip || !activeDayId) return null;
    return trip.days.find(day => day.id === activeDayId) || null;
  }, [trip, activeDayId]);

  const activeDayPlaces = useMemo(() => {
    return activeDay?.places || [];
  }, [activeDay]);

  const activeDayTimelineBlocks = useMemo((): TimelineBlock[] => {
    if (!activeDayPlaces.length) return [];
    
    const timeBlockMap = assignTimeBlocks(activeDayPlaces);
    const blockGroups = new Map<TimeBlock, TripPlace[]>();
    
    activeDayPlaces.forEach(place => {
      const placeKey = place.tripPlaceId || place.id;
      const blockInfo = timeBlockMap.get(placeKey);
      if (blockInfo) {
        const existing = blockGroups.get(blockInfo.timeBlock) || [];
        blockGroups.set(blockInfo.timeBlock, [...existing, { ...place, ...blockInfo }]);
      }
    });
    
    const blocks: TimelineBlock[] = [];
    const blockOrder: TimeBlock[] = ['dawn', 'morning', 'afternoon', 'evening'];
    
    blockOrder.forEach(timeBlock => {
      const places = blockGroups.get(timeBlock);
      if (places && places.length > 0) {
        blocks.push({ timeBlock, places });
      }
    });
    
    return blocks;
  }, [activeDayPlaces]);

  const reorderPlaces = useCallback(async (dayId: string, places: TripPlace[]) => {
    if (!trip) return;
    try {
      const updates = places.map((place, index) => ({
        tripPlaceId: place.tripPlaceId,
        orderIndex: index,
      }));

      await tripPlacesApi.updatePlacesOrder(dayId, updates);
      await loadTrip!(trip.id);
    } catch (error) {
      toast({
        title: 'Hata',
        description: 'Sıralama güncellenemedi: ' + (error instanceof Error ? error.message : 'Bilinmeyen hata'),
        variant: 'destructive',
      });
    }
  }, [trip, loadTrip, toast]);

  return (
    <TripTimelineContext.Provider value={{
      activeDayId,
      activeDay,
      activeDayPlaces,
      activeDayTimelineBlocks,
      setActiveDayId,
      reorderPlaces
    }}>
      {children}
    </TripTimelineContext.Provider>
  );
};
