"use client";

import { useState, useEffect, useCallback, useRef } from 'react';
import { productApi } from '@/lib/services/productService';
import { cache, cacheKeys, cacheTTL } from '@/lib/cache';
import type { ApiProduct, ApiProductsResponse } from '@/types/api';

interface UseProductsOptions {
  search?: string;
  category_id?: number;
  page?: number;
  sort_by?: 'created_at' | 'name' | 'base_price' | 'updated_at';
  sort_order?: 'asc' | 'desc';
  autoFetch?: boolean;
  enableCache?: boolean;
  ttl?: number;
}

export function useProducts(options: UseProductsOptions = {}) {
  const [products, setProducts] = useState<ApiProduct[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [pagination, setPagination] = useState<ApiProductsResponse['meta']>();
  const [fromCache, setFromCache] = useState(false);
  
  const abortControllerRef = useRef<AbortController | null>(null);

  const { 
    search, 
    category_id, 
    page = 1,
    sort_by,
    sort_order,
    autoFetch = true,
    enableCache = true,
    ttl = cacheTTL.products
  } = options;

  // Auto-fetch effect - only run when dependencies actually change
  useEffect(() => {
    if (!autoFetch) return;

    const fetchProducts = async () => {
      console.log('useProducts: Starting to fetch products with options:', { search, category_id, page, sort_by, sort_order });
      
      // Cancel previous request
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
      
      const abortController = new AbortController();
      abortControllerRef.current = abortController;
      
      setLoading(true);
      setError(null);
      setFromCache(false);
      
      try {
        const cacheKey = cacheKeys.products({ search, category_id, page, sort_by, sort_order });
        
        // Try to get from cache first if enabled
        if (enableCache) {
          const cachedData = cache.get<ApiProductsResponse>(cacheKey);
          if (cachedData) {
            console.log('useProducts: Retrieved from cache:', cachedData);
            setProducts(cachedData.data);
            setPagination(cachedData.meta);
            setFromCache(true);
            setLoading(false);
            return;
          }
        }
        
        // Fetch from API
        const response = await productApi.getProducts({
          search,
          category_id,
          page,
          sort_by,
          sort_order,
        });
        
        // Check if request was aborted
        if (abortController.signal.aborted) {
          return;
        }
        
        console.log('useProducts: Products fetched successfully:', response);
        
        // Cache the response if caching is enabled
        if (enableCache) {
          cache.set(cacheKey, response, { ttl });
        }
        
        setProducts(response.data);
        setPagination(response.meta);
      } catch (err) {
        if (err instanceof Error && err.name === 'AbortError') {
          console.log('useProducts: Request aborted');
          return;
        }
        
        const errorMessage = err instanceof Error ? err.message : 'Failed to fetch products';
        console.error('useProducts: Error fetching products:', err);
        setError(errorMessage);
      } finally {
        if (!abortController.signal.aborted) {
          setLoading(false);
          console.log('useProducts: Fetch completed');
        }
      }
    };

    fetchProducts();
    
    // Cleanup function
    return () => {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
    };
  }, [search, category_id, page, sort_by, sort_order, autoFetch, enableCache, ttl]);

  // Manual fetch function
  const fetchProducts = useCallback(async (forceRefresh = false) => {
    console.log('useProducts: Starting to fetch products with options:', { search, category_id, page, sort_by, sort_order, forceRefresh });
    
    // Cancel previous request
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }
    
    const abortController = new AbortController();
    abortControllerRef.current = abortController;
    
    setLoading(true);
    setError(null);
    setFromCache(false);
    
    try {
      const cacheKey = cacheKeys.products({ search, category_id, page, sort_by, sort_order });
      
      // Try to get from cache first if enabled and not forcing refresh
      if (enableCache && !forceRefresh) {
        const cachedData = cache.get<ApiProductsResponse>(cacheKey);
        if (cachedData) {
          console.log('useProducts: Retrieved from cache:', cachedData);
          setProducts(cachedData.data);
          setPagination(cachedData.meta);
          setFromCache(true);
          setLoading(false);
          return;
        }
      }
      
      // Fetch from API
      const response = await productApi.getProducts({
        search,
        category_id,
        page,
        sort_by,
        sort_order,
      });
      
      // Check if request was aborted
      if (abortController.signal.aborted) {
        return;
      }
      
      console.log('useProducts: Products fetched successfully:', response);
      
      // Cache the response if caching is enabled
      if (enableCache) {
        cache.set(cacheKey, response, { ttl });
      }
      
      setProducts(response.data);
      setPagination(response.meta);
    } catch (err) {
      if (err instanceof Error && err.name === 'AbortError') {
        console.log('useProducts: Request aborted');
        return;
      }
      
      const errorMessage = err instanceof Error ? err.message : 'Failed to fetch products';
      console.error('useProducts: Error fetching products:', err);
      setError(errorMessage);
    } finally {
      if (!abortController.signal.aborted) {
        setLoading(false);
        console.log('useProducts: Fetch completed');
      }
    }
  }, [search, category_id, page, sort_by, sort_order, enableCache, ttl]);

  // Force refresh function
  const refresh = useCallback(() => {
    return fetchProducts(true);
  }, [fetchProducts]);

  // Prefetch function for background loading
  const prefetch = useCallback(async (prefetchOptions: Omit<UseProductsOptions, 'autoFetch'>) => {
    const cacheKey = cacheKeys.products({
      search: prefetchOptions.search,
      category_id: prefetchOptions.category_id,
      page: prefetchOptions.page,
      sort_by: prefetchOptions.sort_by,
      sort_order: prefetchOptions.sort_order,
    });
    
    // Only prefetch if not already cached
    if (!cache.has(cacheKey)) {
      try {
        const response = await productApi.getProducts({
          search: prefetchOptions.search,
          category_id: prefetchOptions.category_id,
          page: prefetchOptions.page,
          sort_by: prefetchOptions.sort_by,
          sort_order: prefetchOptions.sort_order,
        });
        
        cache.set(cacheKey, response, { ttl: prefetchOptions.ttl || cacheTTL.products });
      } catch (error) {
        console.warn('Prefetch failed:', error);
      }
    }
  }, []);

  return {
    products,
    loading,
    error,
    pagination,
    fromCache,
    refetch: fetchProducts,
    refresh,
    prefetch,
  };
}

export function useProduct(slug: string, enableCache = true) {
  const [product, setProduct] = useState<ApiProduct | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [fromCache, setFromCache] = useState(false);
  
  const abortControllerRef = useRef<AbortController | null>(null);

  useEffect(() => {
    if (!slug) return;

    const fetchProduct = async () => {
      // Cancel previous request
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
      
      const abortController = new AbortController();
      abortControllerRef.current = abortController;
      
      setLoading(true);
      setError(null);
      setFromCache(false);
      
      try {
        const cacheKey = cacheKeys.product(slug);
        
        // Try cache first
        if (enableCache) {
          const cachedData = cache.get<{ data: ApiProduct }>(cacheKey);
          if (cachedData) {
            setProduct(cachedData.data);
            setFromCache(true);
            setLoading(false);
            return;
          }
        }
        
        // Fetch from API
        const response = await productApi.getProduct(slug);
        
        if (abortController.signal.aborted) {
          return;
        }
        
        // Cache the response
        if (enableCache) {
          cache.set(cacheKey, response, { ttl: cacheTTL.product });
        }
        
        setProduct(response.data);
      } catch (err) {
        if (err instanceof Error && err.name === 'AbortError') {
          return;
        }
        
        setError(err instanceof Error ? err.message : 'Failed to fetch product');
        console.error('Error fetching product:', err);
      } finally {
        if (!abortController.signal.aborted) {
          setLoading(false);
        }
      }
    };

    fetchProduct();
    
    return () => {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
    };
  }, [slug, enableCache]);

  return {
    product,
    loading,
    error,
    fromCache,
  };
}
