'use client';

import React, { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';
import api from '@/lib/api';
import { useAuth } from './AuthContext';
import { trackAddToCart } from '@/lib/analytics';
import { useResellerCart } from '@/hooks/useResellerCart';

interface CartItem {
  id: number;
  product_id: number;
  variant_id: number | null;
  name: string;
  slug: string;
  sku: string;
  price: number;
  reseller_price?: number;
  quantity: number;
  options: Record<string, string>;
  image_url: string;
  stock: number;
}

interface CartContextType {
  cartItems: CartItem[];
  subtotal: number;
  loading: boolean;
  fetchCart: () => Promise<void>;
  addToCart: (productId: number, variantId: number | null, quantity?: number, silent?: boolean, product?: any) => Promise<any>;
  updateQuantity: (cartItemId: number, quantity: number) => Promise<any>;
  removeItem: (cartItemId: number) => Promise<any>;
  clearCart: () => Promise<void>;
  cartCount: number;
  cartOpen: boolean;
  setCartOpen: (open: boolean) => void;
}

const CartContext = createContext<CartContextType | undefined>(undefined);

const CART_CACHE_KEY = 'sawda_cart_cache';

// ─── Persist helpers ──────────────────────────────────────────────────────────
function readCartCache(): { items: CartItem[]; subtotal: number } | null {
  try {
    const raw = localStorage.getItem(CART_CACHE_KEY);
    if (!raw) return null;
    return JSON.parse(raw);
  } catch { return null; }
}

function writeCartCache(items: CartItem[], subtotal: number) {
  try { localStorage.setItem(CART_CACHE_KEY, JSON.stringify({ items, subtotal })); } catch {}
}

function clearCartCache() {
  try { localStorage.removeItem(CART_CACHE_KEY); } catch {}
}

// ─── Cart Added Toast ─────────────────────────────────────────────────────────
function CartToast({ visible, message }: { visible: boolean; message: string }) {
  return (
    <div
      aria-live="polite"
      style={{
        position: 'fixed',
        bottom: '24px',
        left: '50%',
        transform: `translateX(-50%) translateY(${visible ? '0' : '80px'})`,
        opacity: visible ? 1 : 0,
        transition: 'transform 0.35s cubic-bezier(0.34,1.56,0.64,1), opacity 0.3s ease',
        zIndex: 99999,
        pointerEvents: 'none',
        display: 'flex',
        alignItems: 'center',
        gap: '10px',
        background: 'linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)',
        color: '#ffffff',
        padding: '12px 20px',
        borderRadius: '999px',
        boxShadow: '0 8px 32px rgba(0,0,0,0.28), 0 2px 8px rgba(0,0,0,0.18)',
        minWidth: '220px',
        maxWidth: '90vw',
        whiteSpace: 'nowrap',
      }}
    >
      <span
        style={{
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          width: '26px', height: '26px', borderRadius: '50%',
          background: '#22c55e', flexShrink: 0,
          boxShadow: '0 0 0 3px rgba(34,197,94,0.2)',
          animation: visible ? 'cart-toast-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)' : 'none',
        }}
      >
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
          <path d="M2.5 7.5L5.5 10.5L11.5 4" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </span>

      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" style={{ flexShrink: 0, opacity: 0.8 }}>
        <path d="M6 2L3 6v14a2 2 0 002 2h14a2 2 0 002-2V6l-3-4z" stroke="var(--color-secondary)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
        <line x1="3" y1="6" x2="21" y2="6" stroke="var(--color-secondary)" strokeWidth="2" strokeLinecap="round"/>
        <path d="M16 10a4 4 0 01-8 0" stroke="var(--color-secondary)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>

      <span style={{ fontSize: '13px', fontWeight: 700, letterSpacing: '0.01em' }}>{message}</span>

      <style>{`
        @keyframes cart-toast-pop {
          0%   { transform: scale(0.4); }
          70%  { transform: scale(1.2); }
          100% { transform: scale(1); }
        }
      `}</style>
    </div>
  );
}

// ─── Helper ───────────────────────────────────────────────────────────────────
function computeSubtotal(items: CartItem[]): number {
  return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}

// ─── Provider ─────────────────────────────────────────────────────────────────
export const CartProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const cached = typeof window !== 'undefined' ? readCartCache() : null;

  const [cartItems, setCartItems] = useState<CartItem[]>(cached?.items ?? []);
  const [subtotal, setSubtotal] = useState(cached?.subtotal ?? 0);
  const [loading, setLoading] = useState(!cached);
  const [cartOpen, setCartOpen] = useState(false);
  const { user } = useAuth();
  const isReseller = user?.role === 'reseller';
  const resellerCart = useResellerCart();

  // Keep a ref that always mirrors the current cartItems for synchronous reads
  const cartItemsRef = useRef<CartItem[]>(cached?.items ?? []);

  // Toast state
  const [toastVisible, setToastVisible] = useState(false);
  const [toastMessage, setToastMessage] = useState('কার্টে যোগ হয়েছে!');
  const toastTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const syncTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const showToast = (msg = 'কার্টে যোগ হয়েছে!') => {
    setToastMessage(msg);
    setToastVisible(true);
    if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
    toastTimerRef.current = setTimeout(() => setToastVisible(false), 3000);
  };

  // ── Commit new items array → state + ref + cache, all in one shot ─────────
  const commitCart = useCallback((next: CartItem[]) => {
    const sub = computeSubtotal(next);
    cartItemsRef.current = next;   // synchronous ref update
    setCartItems(next);            // React state (triggers re-render)
    setSubtotal(sub);
    writeCartCache(next, sub);
  }, []);

  // ── Server sync ───────────────────────────────────────────────────────────
  const syncCartFromServer = useCallback(async () => {
    try {
      const res = await api.get('/api/cart');
      commitCart(res.data.cart_items || []);
    } catch (err) {
      console.error('Background cart sync failed', err);
    }
  }, [commitCart]);

  const debouncedSync = useCallback(() => {
    if (syncTimerRef.current) clearTimeout(syncTimerRef.current);
    syncTimerRef.current = setTimeout(() => syncCartFromServer(), 1000);
  }, [syncCartFromServer]);

  const fetchCart = useCallback(async () => {
    try {
      const res = await api.get('/api/cart');
      commitCart(res.data.cart_items || []);
    } catch (err) {
      console.error('Failed to fetch cart', err);
    } finally {
      setLoading(false);
    }
  }, [commitCart]);

  useEffect(() => {
    fetchCart();
  }, [user, fetchCart]);

  // ── addToCart — fully synchronous optimistic update ───────────────────────
  const addToCart = async (
    productId: number,
    variantId: number | null,
    quantity = 1,
    silent = false,
    product: any = null,
  ) => {
    // RESELLER MODE
    if (isReseller) {
      try {
        const res = await api.get(`/api/reseller/products?product_id=${productId}`);
        const items: any[] = res.data.data?.data || [];
        const match = items.find((p: any) => p.id === productId);
        if (match) {
          resellerCart.addItem({ ...match, quantity });
          if (!silent) showToast('Reseller cart-এ যোগ হয়েছে!');
          if (product) trackAddToCart(product, quantity);
        } else {
          if (!silent) showToast('এই product reseller catalog-এ নেই');
        }
      } catch { if (!silent) showToast('Reseller cart update failed'); }
      return;
    }

    // Snapshot for rollback
    const snapshot = cartItemsRef.current;
    const snapshotSub = subtotal;

    // Build placeholder with real product data
    const placeholder: CartItem = {
      id: -Date.now(),
      product_id: productId,
      variant_id: variantId,
      name: product?.name ?? '...',
      slug: product?.slug ?? '',
      sku: product?.sku ?? '',
      price: product?.sale_price ?? product?.price ?? 0,
      quantity,
      options: {},
      image_url: product?.image_url ?? '/images/placeholder.jpg',
      stock: product?.stock ?? 9999,
    };

    // Read current items from ref (synchronous, no stale closure)
    const current = cartItemsRef.current;
    const existing = current.find(
      (i) => i.product_id === productId && i.variant_id === variantId,
    );

    const next = existing
      ? current.map((i) =>
          i.product_id === productId && i.variant_id === variantId
            ? { ...i, quantity: i.quantity + quantity }
            : i,
        )
      : [...current, placeholder];

    // Commit instantly — badge, subtotal, and drawer all update in the same tick
    commitCart(next);
    if (!silent) showToast('কার্টে যোগ হয়েছে!');
    if (product) trackAddToCart(product, quantity);

    // Background API
    try {
      const res = await api.post('/api/cart/add', { product_id: productId, variant_id: variantId, quantity });
      debouncedSync();
      return res.data;
    } catch (err: any) {
      // Rollback
      cartItemsRef.current = snapshot;
      setCartItems(snapshot);
      setSubtotal(snapshotSub);
      writeCartCache(snapshot, snapshotSub);
      throw err.response?.data || err;
    }
  };

  // ── Per-item debounce timers ───────────────────────────────────────────────
  const qtyTimersRef = useRef<Record<number, ReturnType<typeof setTimeout>>>({});
  const serverQtyRef = useRef<Record<number, number>>({});

  // ── updateQuantity — synchronous optimistic + debounced API ──────────────
  const updateQuantity = async (cartItemId: number, quantity: number) => {
    if (isReseller) { resellerCart.updateQty(cartItemId, quantity); return; }

    const current = cartItemsRef.current;
    const item = current.find(i => i.id === cartItemId);
    if (item && serverQtyRef.current[cartItemId] === undefined) {
      serverQtyRef.current[cartItemId] = item.quantity;
    }

    const next = quantity <= 0
      ? current.filter(i => i.id !== cartItemId)
      : current.map(i => i.id === cartItemId ? { ...i, quantity } : i);

    commitCart(next);

    if (qtyTimersRef.current[cartItemId]) clearTimeout(qtyTimersRef.current[cartItemId]);

    return new Promise<any>((resolve, reject) => {
      qtyTimersRef.current[cartItemId] = setTimeout(async () => {
        try {
          const res = await api.post('/api/cart/update', { cart_item_id: cartItemId, quantity });
          delete serverQtyRef.current[cartItemId];
          resolve(res.data);
        } catch (err: any) {
          const rollbackQty = serverQtyRef.current[cartItemId];
          if (rollbackQty !== undefined) {
            const rolled = cartItemsRef.current.map(i =>
              i.id === cartItemId ? { ...i, quantity: rollbackQty } : i
            );
            commitCart(rolled);
          }
          delete serverQtyRef.current[cartItemId];
          reject(err.response?.data || err);
        }
      }, 400);
    });
  };

  // ── removeItem — synchronous optimistic ──────────────────────────────────
  const removeItem = async (cartItemId: number) => {
    if (isReseller) { resellerCart.removeItem(cartItemId); return; }

    if (qtyTimersRef.current[cartItemId]) {
      clearTimeout(qtyTimersRef.current[cartItemId]);
      delete qtyTimersRef.current[cartItemId];
    }
    delete serverQtyRef.current[cartItemId];

    const snapshot = cartItemsRef.current;
    const snapshotSub = subtotal;

    commitCart(snapshot.filter(i => i.id !== cartItemId));

    try {
      const res = await api.post('/api/cart/remove', { cart_item_id: cartItemId });
      return res.data;
    } catch (err: any) {
      cartItemsRef.current = snapshot;
      setCartItems(snapshot);
      setSubtotal(snapshotSub);
      writeCartCache(snapshot, snapshotSub);
      throw err.response?.data || err;
    }
  };

  const clearCart = async () => {
    if (isReseller) { resellerCart.clearCart(); return; }

    const snapshot = cartItemsRef.current;
    const snapshotSub = subtotal;

    commitCart([]);
    clearCartCache();

    try {
      await api.post('/api/cart/clear');
    } catch {
      cartItemsRef.current = snapshot;
      setCartItems(snapshot);
      setSubtotal(snapshotSub);
      writeCartCache(snapshot, snapshotSub);
    }
  };

  const activeCartItems = isReseller
    ? resellerCart.cart.map((item) => ({
        id: item.product_id, product_id: item.product_id, variant_id: null,
        name: item.name, slug: '', sku: item.sku, price: item.price,
        reseller_price: item.wholesale_price, wholesale_price: item.wholesale_price,
        quantity: item.quantity, options: {}, image_url: item.image, stock: 9999,
      }))
    : cartItems;

  const activeSubtotal = isReseller ? resellerCart.totalRetail : subtotal;
  const activeCartCount = isReseller
    ? resellerCart.cartCount
    : cartItems.reduce((acc, item) => acc + item.quantity, 0);

  return (
    <CartContext.Provider
      value={{
        cartItems: activeCartItems, subtotal: activeSubtotal, loading,
        fetchCart, addToCart, updateQuantity, removeItem, clearCart,
        cartCount: activeCartCount, cartOpen, setCartOpen,
      }}
    >
      {children}
      <CartToast visible={toastVisible} message={toastMessage} />
    </CartContext.Provider>
  );
};

export const useCart = () => {
  const context = useContext(CartContext);
  if (context === undefined) throw new Error('useCart must be used within a CartProvider');
  return context;
};
