import { createContext, useContext, useState, useEffect, type ReactNode } from 'react';
import defaultFBOContent from '../data/fbo-content.json';

// Types
export interface FBOProduct {
  id: string;
  reference: string;
  name: string;
  category: string;
  price: number;
  currency: string;
  image: string;
  composition: string;
  description: string;
  dosage: string;
  benefits: string[];
  inStock: boolean;
  featured: boolean;
}

export interface FBOCategory {
  id: string;
  name: string;
}

export interface FBOBenefit {
  icon: string;
  title: string;
  description: string;
}

export interface FBOContent {
  site: {
    name: string;
    logo: string;
    favicon: string;
  };
  hero: {
    title: string;
    subtitle: string;
    cta: string;
    image: string;
  };
  about: {
    title: string;
    body: string;
    stats: { value: string; label: string }[];
  };
  benefits: {
    title: string;
    items: FBOBenefit[];
  };
  categories: FBOCategory[];
  products: FBOProduct[];
  contact: {
    title: string;
    body: string;
    cta: string;
    email: string;
    phone: string;
  };
}

interface FBOCartItem extends FBOProduct {
  quantity: number;
}

interface FBOContentContextType {
  content: FBOContent;
  cart: FBOCartItem[];
  addToCart: (product: FBOProduct, quantity?: number) => void;
  removeFromCart: (productId: string) => void;
  updateCartQuantity: (productId: string, quantity: number) => void;
  clearCart: () => void;
  getCartTotal: () => number;
  getCartCount: () => number;
  getProductsByCategory: (categoryId: string) => FBOProduct[];
  getFeaturedProducts: () => FBOProduct[];
  getProductById: (id: string) => FBOProduct | undefined;
  updateContent: (section: keyof FBOContent, data: any) => void;
  updateProduct: (productId: string, data: Partial<FBOProduct>) => void;
  addProduct: (product: FBOProduct) => void;
  removeProduct: (productId: string) => void;
  resetContent: () => void;
  isLoading: boolean;
}

const FBOContentContext = createContext<FBOContentContextType | undefined>(undefined);

const FBO_STORAGE_KEY = 'fbo_content';
const FBO_CART_KEY = 'fbo_cart';

export function FBOContentProvider({ children }: { children: ReactNode }) {
  const [content, setContent] = useState<FBOContent>(defaultFBOContent as FBOContent);
  const [cart, setCart] = useState<FBOCartItem[]>([]);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    // Load content from localStorage on mount
    const stored = localStorage.getItem(FBO_STORAGE_KEY);
    if (stored) {
      try {
        const parsed = JSON.parse(stored);
        setContent(parsed);
      } catch (e) {
        console.error('Failed to parse stored FBO content:', e);
      }
    }
    
    // Load cart from localStorage
    const storedCart = localStorage.getItem(FBO_CART_KEY);
    if (storedCart) {
      try {
        setCart(JSON.parse(storedCart));
      } catch (e) {
        console.error('Failed to parse stored cart:', e);
      }
    }
    
    setIsLoading(false);
  }, []);

  useEffect(() => {
    // Save to localStorage whenever content changes
    if (!isLoading) {
      localStorage.setItem(FBO_STORAGE_KEY, JSON.stringify(content));
    }
  }, [content, isLoading]);

  useEffect(() => {
    // Save cart to localStorage
    localStorage.setItem(FBO_CART_KEY, JSON.stringify(cart));
  }, [cart]);

  const addToCart = (product: FBOProduct, quantity = 1) => {
    setCart(prev => {
      const existing = prev.find(item => item.id === product.id);
      if (existing) {
        return prev.map(item =>
          item.id === product.id
            ? { ...item, quantity: item.quantity + quantity }
            : item
        );
      }
      return [...prev, { ...product, quantity }];
    });
  };

  const removeFromCart = (productId: string) => {
    setCart(prev => prev.filter(item => item.id !== productId));
  };

  const updateCartQuantity = (productId: string, quantity: number) => {
    if (quantity <= 0) {
      removeFromCart(productId);
      return;
    }
    setCart(prev =>
      prev.map(item =>
        item.id === productId ? { ...item, quantity } : item
      )
    );
  };

  const clearCart = () => {
    setCart([]);
  };

  const getCartTotal = () => {
    return cart.reduce((total, item) => total + item.price * item.quantity, 0);
  };

  const getCartCount = () => {
    return cart.reduce((count, item) => count + item.quantity, 0);
  };

  const getProductsByCategory = (categoryId: string) => {
    if (categoryId === 'all') return content.products;
    return content.products.filter(p => p.category === categoryId);
  };

  const getFeaturedProducts = () => {
    return content.products.filter(p => p.featured);
  };

  const getProductById = (id: string) => {
    return content.products.find(p => p.id === id);
  };

  const updateContent = (section: keyof FBOContent, data: any) => {
    setContent(prev => ({
      ...prev,
      [section]: { ...prev[section], ...data }
    }));
  };

  const updateProduct = (productId: string, data: Partial<FBOProduct>) => {
    setContent(prev => ({
      ...prev,
      products: prev.products.map(p =>
        p.id === productId ? { ...p, ...data } : p
      )
    }));
  };

  const addProduct = (product: FBOProduct) => {
    setContent(prev => ({
      ...prev,
      products: [...prev.products, product]
    }));
  };

  const removeProduct = (productId: string) => {
    setContent(prev => ({
      ...prev,
      products: prev.products.filter(p => p.id !== productId)
    }));
  };

  const resetContent = () => {
    setContent(defaultFBOContent as FBOContent);
    localStorage.removeItem(FBO_STORAGE_KEY);
  };

  return (
    <FBOContentContext.Provider value={{
      content,
      cart,
      addToCart,
      removeFromCart,
      updateCartQuantity,
      clearCart,
      getCartTotal,
      getCartCount,
      getProductsByCategory,
      getFeaturedProducts,
      getProductById,
      updateContent,
      updateProduct,
      addProduct,
      removeProduct,
      resetContent,
      isLoading
    }}>
      {children}
    </FBOContentContext.Provider>
  );
}

export function useFBOContent() {
  const context = useContext(FBOContentContext);
  if (context === undefined) {
    throw new Error('useFBOContent must be used within a FBOContentProvider');
  }
  return context;
}
