import { createContext, useContext, useState, useEffect } from 'react';

// Context
const AppsContext = createContext(null);

// API endpoint (uses server cache in production, falls back to direct HF API in dev)
const API_ENDPOINT = '/api/apps';
const FALLBACK_HF_API = 'https://huggingface.co/api/spaces';
const FALLBACK_OFFICIAL_URL = 'https://huggingface.co/datasets/pollen-robotics/reachy-mini-official-app-store/raw/main/app-list.json';
// Note: HF API doesn't support pagination with filter=, so we use a high limit
const FALLBACK_LIMIT = 1000;

// Fallback: fetch directly from HuggingFace API (for dev mode)
async function fetchAppsDirectFromHF() {
  console.log('[AppsContext] Fallback: fetching directly from HuggingFace API');
  
  // Fetch official app IDs
  const officialResponse = await fetch(FALLBACK_OFFICIAL_URL);
  let officialIdList = [];
  if (officialResponse.ok) {
    officialIdList = await officialResponse.json();
  }
  const officialSet = new Set(officialIdList.map(id => id.toLowerCase()));

  // Fetch all spaces
  // Note: HF API doesn't support pagination with filter=, so we use a high limit
  const spacesResponse = await fetch(`${FALLBACK_HF_API}?filter=reachy_mini&full=true&limit=${FALLBACK_LIMIT}`);
  if (!spacesResponse.ok) {
    throw new Error(`HF API returned ${spacesResponse.status}`);
  }
  const allSpaces = await spacesResponse.json();

  // Build apps list
  const allApps = allSpaces.map(space => {
    const spaceId = space.id || '';
    const tags = space.tags || [];
    const isOfficial = officialSet.has(spaceId.toLowerCase());
    const isPythonApp = tags.includes('reachy_mini_python_app');
    
    return {
      id: spaceId,
      name: spaceId.split('/').pop(),
      description: space.cardData?.short_description || '',
      cardData: space.cardData || {},
      likes: space.likes || 0,
      lastModified: space.lastModified,
      author: spaceId.split('/')[0],
      isOfficial,
      isPythonApp,
      tags,
    };
  });

  // Sort: official first, then by likes
  allApps.sort((a, b) => {
    if (a.isOfficial !== b.isOfficial) {
      return a.isOfficial ? -1 : 1;
    }
    return (b.likes || 0) - (a.likes || 0);
  });

  return allApps;
}

// Provider component
export function AppsProvider({ children }) {
  const [apps, setApps] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [hasFetched, setHasFetched] = useState(false);

  useEffect(() => {
    // Only fetch once
    if (hasFetched) return;

    async function fetchApps() {
      setLoading(true);
      setError(null);

      try {
        let allApps;

        // Try server cache first
        try {
          const response = await fetch(API_ENDPOINT);
          if (response.ok) {
            const data = await response.json();
            allApps = data.apps;
            console.log(`[AppsContext] Fetched ${allApps.length} apps from server cache (age: ${data.cacheAge}s)`);
          } else {
            throw new Error('Server API not available');
          }
        } catch (serverErr) {
          // Fallback to direct HF API (for dev mode or if server fails)
          console.log('[AppsContext] Server cache unavailable, using direct API');
          allApps = await fetchAppsDirectFromHF();
          console.log(`[AppsContext] Fetched ${allApps.length} apps directly from HuggingFace`);
        }

        setApps(allApps);
        setHasFetched(true);
      } catch (err) {
        console.error('Failed to fetch apps:', err);
        setError('Failed to load apps. Please try again later.');
      } finally {
        setLoading(false);
      }
    }

    fetchApps();
  }, [hasFetched]);

  return (
    <AppsContext.Provider value={{ apps, loading, error }}>
      {children}
    </AppsContext.Provider>
  );
}

// Hook to use the apps context
export function useApps() {
  const context = useContext(AppsContext);
  if (!context) {
    throw new Error('useApps must be used within an AppsProvider');
  }
  return context;
}

