import React, { createContext, useContext, useReducer, useEffect, ReactNode } from 'react';

export interface Bakery {
  id: string;
  name: string;
  logo?: string;
  role: 'owner' | 'manager' | 'baker' | 'staff';
  status: 'active' | 'inactive';
  address?: string;
  description?: string;
  settings?: {
    timezone: string;
    currency: string;
    language: string;
  };
  permissions?: string[];
}

interface BakeryState {
  bakeries: Bakery[];
  currentBakery: Bakery | null;
  isLoading: boolean;
  error: string | null;
}

type BakeryAction =
  | { type: 'SET_LOADING'; payload: boolean }
  | { type: 'SET_ERROR'; payload: string | null }
  | { type: 'SET_BAKERIES'; payload: Bakery[] }
  | { type: 'SET_CURRENT_BAKERY'; payload: Bakery }
  | { type: 'ADD_BAKERY'; payload: Bakery }
  | { type: 'UPDATE_BAKERY'; payload: { id: string; updates: Partial<Bakery> } }
  | { type: 'REMOVE_BAKERY'; payload: string };

const initialState: BakeryState = {
  bakeries: [],
  currentBakery: null,
  isLoading: false,
  error: null,
};

// Mock bakeries data
const mockBakeries: Bakery[] = [
  {
    id: '1',
    name: 'Panadería San Miguel',
    logo: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=100&h=100&fit=crop&crop=center',
    role: 'owner',
    status: 'active',
    address: 'Calle Mayor 123, Madrid, 28013',
    description: 'Panadería tradicional familiar con más de 30 años de experiencia.',
    settings: {
      timezone: 'Europe/Madrid',
      currency: 'EUR',
      language: 'es',
    },
    permissions: ['*'],
  },
  {
    id: '2',
    name: 'Panadería La Artesana',
    logo: 'https://images.unsplash.com/photo-1509440159596-0249088772ff?w=100&h=100&fit=crop&crop=center',
    role: 'manager',
    status: 'active',
    address: 'Avenida de la Paz 45, Barcelona, 08001',
    description: 'Panadería artesanal especializada en panes tradicionales catalanes.',
    settings: {
      timezone: 'Europe/Madrid',
      currency: 'EUR',
      language: 'ca',
    },
    permissions: ['inventory:*', 'production:*', 'sales:*', 'reports:read'],
  },
  {
    id: '3',
    name: 'Pan y Masa',
    logo: 'https://images.unsplash.com/photo-1524704654690-b56c05c78a00?w=100&h=100&fit=crop&crop=center',
    role: 'baker',
    status: 'active',
    address: 'Plaza Central 8, Valencia, 46001',
    description: 'Panadería moderna con enfoque en productos orgánicos.',
    settings: {
      timezone: 'Europe/Madrid',
      currency: 'EUR',
      language: 'es',
    },
    permissions: ['production:*', 'inventory:read', 'inventory:update'],
  },
  {
    id: '4',
    name: 'Horno Dorado',
    role: 'staff',
    status: 'inactive',
    address: 'Calle del Sol 67, Sevilla, 41001',
    description: 'Panadería tradicional andaluza.',
    settings: {
      timezone: 'Europe/Madrid',
      currency: 'EUR',
      language: 'es',
    },
    permissions: ['inventory:read', 'sales:read'],
  },
];

function bakeryReducer(state: BakeryState, action: BakeryAction): BakeryState {
  switch (action.type) {
    case 'SET_LOADING':
      return { ...state, isLoading: action.payload };
    
    case 'SET_ERROR':
      return { ...state, error: action.payload, isLoading: false };
    
    case 'SET_BAKERIES':
      return { 
        ...state, 
        bakeries: action.payload, 
        currentBakery: state.currentBakery || action.payload[0] || null,
        isLoading: false,
        error: null 
      };
    
    case 'SET_CURRENT_BAKERY':
      // Save to localStorage for persistence
      localStorage.setItem('selectedBakery', action.payload.id);
      return { ...state, currentBakery: action.payload };
    
    case 'ADD_BAKERY':
      return { 
        ...state, 
        bakeries: [...state.bakeries, action.payload] 
      };
    
    case 'UPDATE_BAKERY':
      return {
        ...state,
        bakeries: state.bakeries.map(bakery =>
          bakery.id === action.payload.id 
            ? { ...bakery, ...action.payload.updates }
            : bakery
        ),
        currentBakery: state.currentBakery?.id === action.payload.id
          ? { ...state.currentBakery, ...action.payload.updates }
          : state.currentBakery
      };
    
    case 'REMOVE_BAKERY':
      const remainingBakeries = state.bakeries.filter(b => b.id !== action.payload);
      return {
        ...state,
        bakeries: remainingBakeries,
        currentBakery: state.currentBakery?.id === action.payload 
          ? remainingBakeries[0] || null 
          : state.currentBakery
      };
    
    default:
      return state;
  }
}

interface BakeryContextType extends BakeryState {
  selectBakery: (bakery: Bakery) => void;
  addBakery: (bakery: Omit<Bakery, 'id'>) => Promise<void>;
  updateBakery: (id: string, updates: Partial<Bakery>) => Promise<void>;
  removeBakery: (id: string) => Promise<void>;
  refreshBakeries: () => Promise<void>;
  hasPermission: (permission: string) => boolean;
  canAccess: (resource: string, action: string) => boolean;
}

const BakeryContext = createContext<BakeryContextType | undefined>(undefined);

interface BakeryProviderProps {
  children: ReactNode;
}

export function BakeryProvider({ children }: BakeryProviderProps) {
  const [state, dispatch] = useReducer(bakeryReducer, initialState);

  // Load bakeries on mount
  useEffect(() => {
    loadBakeries();
  }, []);

  // Load saved bakery selection
  useEffect(() => {
    if (state.bakeries.length > 0 && !state.currentBakery) {
      const savedBakeryId = localStorage.getItem('selectedBakery');
      const savedBakery = savedBakeryId 
        ? state.bakeries.find(b => b.id === savedBakeryId)
        : null;
      
      if (savedBakery) {
        dispatch({ type: 'SET_CURRENT_BAKERY', payload: savedBakery });
      } else if (state.bakeries[0]) {
        dispatch({ type: 'SET_CURRENT_BAKERY', payload: state.bakeries[0] });
      }
    }
  }, [state.bakeries, state.currentBakery]);

  const loadBakeries = async () => {
    try {
      dispatch({ type: 'SET_LOADING', payload: true });
      
      // Simulate API call delay
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      // In a real app, this would be an API call
      dispatch({ type: 'SET_BAKERIES', payload: mockBakeries });
    } catch (error) {
      dispatch({ 
        type: 'SET_ERROR', 
        payload: error instanceof Error ? error.message : 'Error loading bakeries' 
      });
    }
  };

  const selectBakery = (bakery: Bakery) => {
    dispatch({ type: 'SET_CURRENT_BAKERY', payload: bakery });
  };

  const addBakery = async (bakeryData: Omit<Bakery, 'id'>) => {
    try {
      dispatch({ type: 'SET_LOADING', payload: true });
      
      // Simulate API call
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      const newBakery: Bakery = {
        ...bakeryData,
        id: Date.now().toString(), // In real app, this would come from the API
      };
      
      dispatch({ type: 'ADD_BAKERY', payload: newBakery });
      dispatch({ type: 'SET_LOADING', payload: false });
    } catch (error) {
      dispatch({ 
        type: 'SET_ERROR', 
        payload: error instanceof Error ? error.message : 'Error adding bakery' 
      });
    }
  };

  const updateBakery = async (id: string, updates: Partial<Bakery>) => {
    try {
      dispatch({ type: 'SET_LOADING', payload: true });
      
      // Simulate API call
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      dispatch({ type: 'UPDATE_BAKERY', payload: { id, updates } });
      dispatch({ type: 'SET_LOADING', payload: false });
    } catch (error) {
      dispatch({ 
        type: 'SET_ERROR', 
        payload: error instanceof Error ? error.message : 'Error updating bakery' 
      });
    }
  };

  const removeBakery = async (id: string) => {
    try {
      dispatch({ type: 'SET_LOADING', payload: true });
      
      // Simulate API call
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      dispatch({ type: 'REMOVE_BAKERY', payload: id });
      dispatch({ type: 'SET_LOADING', payload: false });
    } catch (error) {
      dispatch({ 
        type: 'SET_ERROR', 
        payload: error instanceof Error ? error.message : 'Error removing bakery' 
      });
    }
  };

  const refreshBakeries = async () => {
    await loadBakeries();
  };

  const hasPermission = (permission: string): boolean => {
    if (!state.currentBakery) return false;
    
    const permissions = state.currentBakery.permissions || [];
    
    // Admin/owner has all permissions
    if (permissions.includes('*')) return true;
    
    return permissions.includes(permission);
  };

  const canAccess = (resource: string, action: string): boolean => {
    if (!state.currentBakery) return false;
    
    // Check specific permission
    if (hasPermission(`${resource}:${action}`)) return true;
    
    // Check wildcard permissions
    if (hasPermission(`${resource}:*`)) return true;
    
    // Role-based access fallback
    switch (state.currentBakery.role) {
      case 'owner':
        return true;
      case 'manager':
        return ['inventory', 'production', 'sales', 'reports'].includes(resource);
      case 'baker':
        return ['production', 'inventory'].includes(resource) && 
               ['read', 'update'].includes(action);
      case 'staff':
        return ['inventory', 'sales'].includes(resource) && 
               action === 'read';
      default:
        return false;
    }
  };

  const value: BakeryContextType = {
    ...state,
    selectBakery,
    addBakery,
    updateBakery,
    removeBakery,
    refreshBakeries,
    hasPermission,
    canAccess,
  };

  return (
    <BakeryContext.Provider value={value}>
      {children}
    </BakeryContext.Provider>
  );
}

export function useBakery(): BakeryContextType {
  const context = useContext(BakeryContext);
  if (context === undefined) {
    throw new Error('useBakery must be used within a BakeryProvider');
  }
  return context;
}

// Convenience hooks
export const useCurrentBakery = () => {
  const { currentBakery } = useBakery();
  return currentBakery;
};

export const useBakeries = () => {
  const { bakeries } = useBakery();
  return bakeries;
};

export const useBakeryPermissions = () => {
  const { hasPermission, canAccess } = useBakery();
  return { hasPermission, canAccess };
};