// Global state — Supabase backend + React Context
const { createContext, useContext, useReducer, useEffect, useState: useStateStore } = React;

// ── Helpers ──────────────────────────────────────────────────────────────────

function flipProfit(f) {
  if (f.status !== 'sold' || f.sell_price == null) return null;
  return f.sell_price - f.buy_price - (f.fees||0) - (f.shipping||0);
}

function itemEmoji(name) {
  const n = (name||'').toLowerCase();
  if (n.includes('macbook') || n.includes('mac air') || n.includes('mac pro') || n.includes('mac mini')) return '💻';
  if (n.includes('laptop') || n.includes('thinkpad') || n.includes('xps') || n.includes('notebook')) return '💻';
  if (n.includes('iphone') || n.includes('ipad')) return '📱';
  if (n.includes('samsung') || n.includes('pixel') || n.includes('oneplus')) return '📱';
  if (n.includes('phone') && !n.includes('headphone')) return '📱';
  if (n.includes('rtx') || n.includes('gtx') || n.includes('gpu') || n.includes('graphics card')) return '🎮';
  if (n.includes('ps5') || n.includes('ps4') || n.includes('playstation') || n.includes('xbox') || n.includes('nintendo') || n.includes('switch')) return '🕹️';
  if (n.includes('watch') || n.includes('rolex') || n.includes('seiko') || n.includes('omega') || n.includes('datejust') || n.includes('submariner')) return '⌚';
  if (n.includes('jordan') || n.includes('yeezy') || n.includes('dunk') || n.includes('air max') || n.includes('sneaker') || n.includes('kicks')) return '👟';
  if (n.includes('nike') || n.includes('adidas') || n.includes('shoe')) return '👟';
  if (n.includes('hoodie') || n.includes('jacket') || n.includes('shirt') || n.includes('supreme') || n.includes('jeans') || n.includes('collab')) return '👕';
  if (n.includes('camera') || n.includes('canon') || n.includes('nikon') || n.includes('sony a') || n.includes('eos') || n.includes('fuji') || n.includes('lens')) return '📷';
  if (n.includes('wh-') || n.includes('xm5') || n.includes('headphone') || n.includes('airpod') || n.includes('buds')) return '🎧';
  if (n.includes('cpu') || n.includes('ryzen') || n.includes('intel') || n.includes('processor') || n.includes('core i')) return '🔧';
  if (n.includes('ram') || n.includes('ssd') || n.includes('nvme') || n.includes('memory')) return '💾';
  if (n.includes('pc') || n.includes('build') || n.includes('desktop') || n.includes('rig')) return '🖥️';
  if (n.includes('necklace') || n.includes('ring') || n.includes('bracelet') || n.includes('jewelry')) return '💍';
  return '📦';
}

function itemIcon(name) { return itemEmoji(name); }

function fmt(n, decimals=0) {
  if (n == null) return '—';
  return '$' + Math.abs(n).toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

function fmtSigned(n, decimals=0) {
  if (n == null) return '—';
  return (n >= 0 ? '↑ ' : '↓ ') + fmt(n, decimals);
}

function todayStr() {
  const d = new Date();
  const pad = n => String(n).padStart(2,'0');
  return d.getFullYear() + '-' + pad(d.getMonth()+1) + '-' + pad(d.getDate());
}

function daysBetween(dateStr, toStr) {
  const a = new Date(dateStr + 'T00:00:00');
  const b = toStr ? new Date(toStr + 'T00:00:00') : new Date();
  return Math.max(0, Math.round((b - a) / 86400000));
}

function catIconBg(category) {
  const map = {
    'PC Parts':'#e8eeff','PC Builds':'#e8eeff','Laptops':'#ede8ff',
    'Phones':'#e8f7ff','Gaming':'#f3e8ff','Sneakers':'#fff0e8',
    'Clothes':'#ffe8f4','Watches':'#fff8e8','Cameras':'#ffe8e8',
    'Jewelry':'#fff8e0','Audio':'#e8fff8','Other':'#f0f0f0',
  };
  return map[category] || '#f0f0f0';
}

function catIconGradient(category) {
  const map = {
    'PC Parts':'linear-gradient(135deg,#1a3a8a,#4a7aec)',
    'PC Builds':'linear-gradient(135deg,#1a3a8a,#4a7aec)',
    'Laptops':'linear-gradient(135deg,#312e81,#818cf8)',
    'Phones':'linear-gradient(135deg,#0f4c75,#22d3ee)',
    'Gaming':'linear-gradient(135deg,#6d28d9,#a855f7)',
    'Sneakers':'linear-gradient(135deg,#c2410c,#fb923c)',
    'Clothes':'linear-gradient(135deg,#9d174d,#f472b6)',
    'Watches':'linear-gradient(135deg,#78350f,#f59e0b)',
    'Cameras':'linear-gradient(135deg,#7f1d1d,#f87171)',
    'Jewelry':'linear-gradient(135deg,#713f12,#fbbf24)',
    'Audio':'linear-gradient(135deg,#134e4a,#2dd4bf)',
    'Other':'linear-gradient(135deg,#374151,#9ca3af)',
  };
  return map[category] || 'linear-gradient(135deg,#374151,#9ca3af)';
}

// ── Demo Data ─────────────────────────────────────────────────────────────

const DEMO_FLIPS = [
  { id:'d1', item_name:'RTX 4070 Ti', buy_price:480, buy_date:'2026-02-10', sell_price:635, sell_date:'2026-03-01', platform:'eBay', fees:63, shipping:18, status:'sold', category:'PC Parts', hours_spent:3, source:'Facebook Marketplace', repair_cost:0, created_at:'2026-02-10' },
  { id:'d2', item_name:'MacBook Air M2', buy_price:720, buy_date:'2026-02-14', sell_price:940, sell_date:'2026-03-10', platform:'Facebook Marketplace', fees:0, shipping:0, status:'sold', category:'Laptops', hours_spent:2, source:'Craigslist', repair_cost:0, created_at:'2026-02-14' },
  { id:'d3', item_name:'Jordan 4 Retro', buy_price:190, buy_date:'2026-03-01', sell_price:360, sell_date:'2026-03-20', platform:'eBay', fees:36, shipping:16, status:'sold', category:'Sneakers', hours_spent:1, source:'Local', repair_cost:0, created_at:'2026-03-01' },
  { id:'d4', item_name:'iPhone 15 Pro', buy_price:820, buy_date:'2026-03-15', sell_price:1020, sell_date:'2026-04-02', platform:'eBay', fees:102, shipping:14, status:'sold', category:'Phones', hours_spent:1, source:'Facebook Marketplace', repair_cost:0, created_at:'2026-03-15' },
  { id:'d5', item_name:'PS5 Slim', buy_price:390, buy_date:'2026-04-01', sell_price:null, sell_date:null, platform:null, fees:0, shipping:0, status:'open', category:'Gaming', hours_spent:0, source:'Local', repair_cost:0, created_at:'2026-04-01' },
];

const DEMO_OVERHEAD = [
  { id:'o1', description:'eBay Store subscription', amount:21.95, date:'2026-03-01', category:'Platform', created_at:'2026-03-01' },
  { id:'o2', description:'Bubble wrap & packing tape', amount:12.50, date:'2026-03-05', category:'Supplies', created_at:'2026-03-05' },
];

// ── Store Context ─────────────────────────────────────────────────────────────

const StoreContext = createContext(null);

function StoreProvider({ children }) {
  const [flips, setFlips] = useStateStore([]);
  const [overhead, setOverhead] = useStateStore([]);
  const [loading, setLoading] = useStateStore(true);
  const [demoMode, setDemoMode] = useStateStore(false);
  const [isAnonymous, setIsAnonymous] = useStateStore(false);

  // Get current user id
  function getUserId() {
    return supabaseClient.auth.getUser().then(r => r.data?.user?.id);
  }

  // Load all data on mount and set up real-time subscriptions
  useEffect(() => {
    let flipsSubscription = null;
    let overheadSubscription = null;

    async function load() {
      // If demo mode, load demo data and exit
      if (sessionStorage.getItem('fliptaxy_demo') === 'true') {
        setFlips(DEMO_FLIPS);
        setOverhead(DEMO_OVERHEAD);
        setDemoMode(true);
        setLoading(false);
        return;
      }

      const { data: { user } } = await supabaseClient.auth.getUser();
      if (!user) { setLoading(false); return; }

      // Check if user is anonymous
      if (user.is_anonymous === true) {
        setIsAnonymous(true);
        localStorage.setItem('fliptaxy_is_demo', 'true');
      }

      // Try to load from cache first
      const cacheKey = `fliptaxy_cache_${user.id}`;
      const cachedData = localStorage.getItem(cacheKey);
      if (cachedData) {
        try {
          const { flips: cachedFlips, overhead: cachedOverhead } = JSON.parse(cachedData);
          setFlips(cachedFlips || []);
          setOverhead(cachedOverhead || []);
        } catch (e) {
          console.error('Failed to parse cached data:', e);
        }
      }

      try {
        const [{ data: flipsData }, { data: ohData }] = await Promise.all([
          supabaseClient.from('flips').select('*').eq('user_id', user.id).order('created_at', { ascending: false }),
          supabaseClient.from('overhead').select('*').eq('user_id', user.id).order('created_at', { ascending: false }),
        ]);

        setFlips(flipsData || []);
        setOverhead(ohData || []);

        // Cache the fresh data
        localStorage.setItem(cacheKey, JSON.stringify({
          flips: flipsData || [],
          overhead: ohData || [],
          timestamp: Date.now()
        }));

        // Set up real-time subscriptions
        flipsSubscription = supabaseClient
          .channel('flips_changes')
          .on('postgres_changes', 
            { event: '*', schema: 'public', table: 'flips', filter: `user_id=eq.${user.id}` },
            (payload) => {
              if (payload.eventType === 'INSERT') {
                setFlips(prev => {
                  const updated = [payload.new, ...prev];
                  updateCache(user.id, updated, null);
                  return updated;
                });
              } else if (payload.eventType === 'UPDATE') {
                setFlips(prev => {
                  const updated = prev.map(f => f.id === payload.new.id ? payload.new : f);
                  updateCache(user.id, updated, null);
                  return updated;
                });
              } else if (payload.eventType === 'DELETE') {
                setFlips(prev => {
                  const updated = prev.filter(f => f.id !== payload.old.id);
                  updateCache(user.id, updated, null);
                  return updated;
                });
              }
            }
          )
          .subscribe();

        overheadSubscription = supabaseClient
          .channel('overhead_changes')
          .on('postgres_changes',
            { event: '*', schema: 'public', table: 'overhead', filter: `user_id=eq.${user.id}` },
            (payload) => {
              if (payload.eventType === 'INSERT') {
                setOverhead(prev => {
                  const updated = [payload.new, ...prev];
                  updateCache(user.id, null, updated);
                  return updated;
                });
              } else if (payload.eventType === 'DELETE') {
                setOverhead(prev => {
                  const updated = prev.filter(o => o.id !== payload.old.id);
                  updateCache(user.id, null, updated);
                  return updated;
                });
              }
            }
          )
          .subscribe();
      } catch (error) {
        console.error('Failed to load from Supabase, using cached data:', error);
        // If network fails, we'll continue with cached data
      }

      setLoading(false);
    }

    load();

    // Cleanup subscriptions on unmount
    return () => {
      if (flipsSubscription) flipsSubscription.unsubscribe();
      if (overheadSubscription) overheadSubscription.unsubscribe();
    };
  }, []);

  // Helper function to update cache
  function updateCache(userId, flipsData, overheadData) {
    const cacheKey = `fliptaxy_cache_${userId}`;
    const currentCache = localStorage.getItem(cacheKey);
    let cache = { flips: [], overhead: [], timestamp: Date.now() };
    
    if (currentCache) {
      try {
        cache = JSON.parse(currentCache);
      } catch (e) {
        console.error('Failed to parse cache for update:', e);
      }
    }
    
    if (flipsData !== null) cache.flips = flipsData;
    if (overheadData !== null) cache.overhead = overheadData;
    
    localStorage.setItem(cacheKey, JSON.stringify(cache));
  }

  // ── Actions ──

  async function addFlip(flipData) {
    // Check if anonymous and at limit
    if (isAnonymous && flips.length >= 5) {
      window._showDemoModal && window._showDemoModal();
      return;
    }

    const userId = await getUserId();
    const row = {
      user_id: userId,
      item_name: flipData.item_name,
      buy_price: flipData.buy_price,
      buy_date: flipData.buy_date,
      status: 'open',
      category: flipData.category || null,
      hours_spent: flipData.hours_spent || 0,
      source: flipData.source || null,
      repair_cost: flipData.repair_cost || 0,
      fees: 0,
      shipping: 0,
    };
    const { data, error } = await supabaseClient.from('flips').insert(row).select().single();
    if (!error && data) {
      setFlips(prev => {
        const updated = [data, ...prev];
        updateCache(userId, updated, null);
        return updated;
      });
    }
  }

  async function sellFlip(id, sellData) {
    const userId = await getUserId();
    const { data, error } = await supabaseClient.from('flips').update({
      sell_price: sellData.sell_price,
      sell_date: sellData.sell_date,
      platform: sellData.platform,
      fees: sellData.fees || 0,
      shipping: sellData.shipping || 0,
      status: 'sold',
    }).eq('id', id).select().single();
    if (!error && data) {
      setFlips(prev => {
        const updated = prev.map(f => f.id === id ? data : f);
        updateCache(userId, updated, null);
        return updated;
      });
    }
  }

  async function updateFlip(id, updateData) {
    const userId = await getUserId();
    const { data, error } = await supabaseClient.from('flips').update(updateData).eq('id', id).select().single();
    if (!error && data) {
      setFlips(prev => {
        const updated = prev.map(f => f.id === id ? data : f);
        updateCache(userId, updated, null);
        return updated;
      });
    }
  }

  async function deleteFlip(id) {
    const userId = await getUserId();
    const { error } = await supabaseClient.from('flips').delete().eq('id', id);
    if (!error) {
      setFlips(prev => {
        const updated = prev.filter(f => f.id !== id);
        updateCache(userId, updated, null);
        return updated;
      });
    }
  }

  async function addOverhead(item) {
    const userId = await getUserId();
    const row = {
      user_id: userId,
      description: item.description,
      amount: item.amount,
      date: item.date,
      category: item.category || null,
    };
    const { data, error } = await supabaseClient.from('overhead').insert(row).select().single();
    if (!error && data) {
      setOverhead(prev => {
        const updated = [data, ...prev];
        updateCache(userId, null, updated);
        return updated;
      });
    }
  }

  async function deleteOverhead(id) {
    const userId = await getUserId();
    const { error } = await supabaseClient.from('overhead').delete().eq('id', id);
    if (!error) {
      setOverhead(prev => {
        const updated = prev.filter(o => o.id !== id);
        updateCache(userId, null, updated);
        return updated;
      });
    }
  }

  // Keep dispatch-style API so existing screens don't need changes
  function dispatch(action) {
    if (demoMode) {
      switch (action.type) {
        case 'ADD_FLIP': {
          if (flips.length >= 5) {
            window._showDemoModal && window._showDemoModal();
            return;
          }
          const newFlip = {
            ...action.flip,
            id: 'demo_' + Date.now(),
            status: 'open',
            sell_price: null,
            sell_date: null,
            platform: null,
            fees: 0,
            shipping: 0,
            created_at: new Date().toISOString(),
          };
          setFlips(prev => [newFlip, ...prev]);
          return;
        }
        case 'SELL_FLIP':
          setFlips(prev => prev.map(f => f.id === action.id ? { ...f, ...action.data, status: 'sold' } : f));
          return;
        case 'UPDATE_FLIP':
          setFlips(prev => prev.map(f => f.id === action.id ? { ...f, ...action.data } : f));
          return;
        case 'DELETE_FLIP':
          setFlips(prev => prev.filter(f => f.id !== action.id));
          return;
        case 'ADD_OVERHEAD': {
          const newOh = { ...action.item, id: 'demo_oh_' + Date.now(), created_at: new Date().toISOString() };
          setOverhead(prev => [newOh, ...prev]);
          return;
        }
        case 'DELETE_OVERHEAD':
          setOverhead(prev => prev.filter(o => o.id !== action.id));
          return;
      }
      return;
    }
    switch (action.type) {
      case 'ADD_FLIP':    return addFlip(action.flip);
      case 'SELL_FLIP':   return sellFlip(action.id, action.data);
      case 'UPDATE_FLIP': return updateFlip(action.id, action.data);
      case 'DELETE_FLIP': return deleteFlip(action.id);
      case 'ADD_OVERHEAD':    return addOverhead(action.item);
      case 'DELETE_OVERHEAD': return deleteOverhead(action.id);
    }
  }

  const state = { flips, overhead };

  return React.createElement(StoreContext.Provider, { value: { state, dispatch, loading, demoMode, isAnonymous } }, children);
}

function useStore() { return useContext(StoreContext); }

Object.assign(window, {
  StoreProvider, useStore, flipProfit,
  itemEmoji, itemIcon, fmt, fmtSigned,
  todayStr, daysBetween, catIconGradient, catIconBg,
  supabaseClient
});
