import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { RootState } from '../store';

// Define the type for a box item
export interface BoxItem {
  id: string;
  name: string;
  price: number;
  image: string;
  quantity: number;
  variantId?: string;
  color?: string;
  compositeKey?: string;
}

// Define the type for the box state
interface BoxState {
  items: BoxItem[];
  total: number;
  editingBoxGroupId?: string;
  isInitialized: boolean;
}

// Helper function to load state from localStorage
const loadState = (): BoxState | undefined => {
  try {
    // Check if we're in a browser environment
    if (typeof window === 'undefined') {
      return undefined;
    }
    
    const serializedState = localStorage.getItem('boxState');
    if (serializedState === null) {
      return undefined;
    }
    return JSON.parse(serializedState);
  } catch (err) {
    console.error('Error loading box state from localStorage', err);
    return undefined;
  }
};

// Helper function to save state to localStorage
const saveState = (state: BoxState) => {
  if (typeof window === 'undefined') {
    return;
  }
  
  try {
    const serializedState = JSON.stringify(state);
    localStorage.setItem('boxState', serializedState);
  } catch (err) {
    console.error('Error saving box state to localStorage', err);
  }
};

// Initial state without loading from localStorage to avoid hydration mismatch
const initialState: BoxState = {
  items: [],
  total: 0,
  editingBoxGroupId: undefined,
  isInitialized: false
};

// Helper to generate a unique key for an item based on ID and color
const generateItemKey = (item: { id: string; color?: string }): string => {
  return `${item.id}-${item.color || 'no-color'}`;
};

export const boxSlice = createSlice({
  name: 'box',
  initialState,
  reducers: {
    // Initialize state from localStorage (to be called in useEffect)
    initializeState: (state) => {
      // Skip if already initialized
      if (state.isInitialized) return;
      
      try {
        const savedState = loadState();
        if (savedState) {
          state.items = savedState.items || [];
          state.total = savedState.total || 0;
          state.editingBoxGroupId = savedState.editingBoxGroupId;
        }
      } catch (error) {
        console.error('Error initializing state from localStorage', error);
      }
      
      state.isInitialized = true;
    },
    
    // Add an item to the box
    addToBox: (state, action: PayloadAction<BoxItem>) => {
      const newItem = { ...action.payload };
      
      // Check if the variantId should be used as a color
      if (newItem.variantId && !newItem.color) {
        newItem.color = newItem.variantId;
      }
      
      // Generate composite key
      const compositeKey = generateItemKey(newItem);
      newItem.compositeKey = compositeKey;
      
      const existingItemIndex = state.items.findIndex(
        item => generateItemKey(item) === compositeKey
      );

      if (existingItemIndex >= 0 && state.items[existingItemIndex]) {
        // If item with the same key exists, increment quantity
        const quantity = newItem.quantity || 1;
        state.items[existingItemIndex].quantity += quantity;
      } else {
        // Otherwise add the new item (or item with a different color)
        state.items.push({ 
          ...newItem, 
          quantity: newItem.quantity || 1,
          compositeKey
        });
      }

      // Recalculate total
      state.total = state.items.reduce(
        (sum, item) => sum + item.price * item.quantity, 0
      );
      
      // Save to localStorage
      saveState(state);
    },
    
    // Update item quantity
    updateQuantity: (state, action: PayloadAction<{ id: string; color?: string; quantity: number }>) => {
      const { id, color, quantity } = action.payload;
      const itemKey = generateItemKey({ id, color });
      const item = state.items.find(item => generateItemKey(item) === itemKey);
      
      if (item) {
        item.quantity = quantity;
        
        // Recalculate total
        state.total = state.items.reduce(
          (sum, item) => sum + item.price * item.quantity, 0
        );
      }
      
      // Save to localStorage
      saveState(state);
    },
    
    // Remove an item from the box
    removeFromBox: (state, action: PayloadAction<{ id: string; color?: string }>) => {
      const { id, color } = action.payload;
      const itemKeyToRemove = generateItemKey({ id, color });
      state.items = state.items.filter(item => generateItemKey(item) !== itemKeyToRemove);
      
      // Recalculate total
      state.total = state.items.reduce(
        (sum, item) => sum + item.price * item.quantity, 0
      );
      
      // Save to localStorage
      saveState(state);
    },
    
    // Clear the entire box
    clearBox: (state) => {
      state.items = [];
      state.total = 0;
      state.editingBoxGroupId = undefined;
      
      // Save to localStorage
      saveState(state);
    },
    
    // Load a box for editing
    loadBoxForEditing: (state) => {
      try {
        if (typeof window === 'undefined') {
          return;
        }
        
        const boxStateString = localStorage.getItem('lastBoxState');
        if (!boxStateString) {
          return;
        }
        
        const boxState = JSON.parse(boxStateString);
        
        // Spremi originalni boxGroupId ako postoji
        if (boxState && boxState.originalBoxGroupId) {
          state.editingBoxGroupId = boxState.originalBoxGroupId;
        }
        
        if (boxState && boxState.boxItems && boxState.productItems) {
          // Reset current state
          state.items = [];
          
          // Add box items
          boxState.boxItems.forEach((item: BoxItem) => {
            state.items.push(item);
          });
          
          // Add product items
          boxState.productItems.forEach((item: BoxItem) => {
            state.items.push(item);
          });
          
          // Recalculate total
          state.total = state.items.reduce(
            (sum, item) => sum + item.price * item.quantity, 0
          );
          
          // Save to localStorage
          saveState(state);
        }
      } catch (error) {
        console.error('Error loading box for editing', error);
      }
    },
  },
});

// Export actions
export const { initializeState, addToBox, updateQuantity, removeFromBox, clearBox, loadBoxForEditing } = boxSlice.actions;

// Selectors
export const selectBoxItems = (state: RootState) => state.box.items;
export const selectBoxTotal = (state: RootState) => state.box.total;
export const selectBoxItemsCount = (state: RootState) => 
  state.box.items.reduce((total, item) => total + item.quantity, 0);
export const selectEditingBoxGroupId = (state: RootState) => state.box.editingBoxGroupId;

export default boxSlice.reducer; 