/**
 * useProductLines Hook
 *
 * Manages fetching and caching of product lines and sublines.
 * Lines are hierarchical: Company -> Line -> Subline
 *
 * PERFORMANCE NOTE: This hook has NO subscriptions to avoid re-renders.
 * All state is read via getState() at call-time inside callbacks.
 * This prevents components using this hook from re-rendering when cache updates.
 */

import { useCallback, useRef } from 'react';
import { useValidationStore } from '../store/validationStore';
import type { SelectOption } from '../../../types';
import { apiClient } from "@/utils/apiClient";

/**
 * Fetch product lines for a company
 */
const fetchProductLinesApi = async (companyId: string): Promise<SelectOption[]> => {
  const response = await apiClient.get(`/api/import/product-lines/${companyId}`);
  const lines = response.data;

  return lines.map((line: { name?: string; label?: string; value?: string | number; id?: string | number }) => ({
    label: line.name || line.label || String(line.value || line.id),
    value: String(line.value || line.id),
  }));
};

/**
 * Fetch sublines for a product line
 */
const fetchSublinesApi = async (lineId: string): Promise<SelectOption[]> => {
  const response = await apiClient.get(`/api/import/sublines/${lineId}`);
  const sublines = response.data;

  return sublines.map((subline: { name?: string; label?: string; value?: string | number; id?: string | number }) => ({
    label: subline.name || subline.label || String(subline.value || subline.id),
    value: String(subline.value || subline.id),
  }));
};

/**
 * Hook for product lines operations
 *
 * PERFORMANCE: This hook has NO subscriptions to cache state.
 * All cache reads use getState() at call-time inside callbacks.
 * This prevents re-renders when cache updates.
 */
export const useProductLines = () => {
  // Store actions (these are stable from Zustand)
  const setProductLines = useValidationStore((state) => state.setProductLines);
  const setSublines = useValidationStore((state) => state.setSublines);
  const setLoadingProductLines = useValidationStore((state) => state.setLoadingProductLines);
  const setLoadingSublines = useValidationStore((state) => state.setLoadingSublines);

  // Track pending requests to prevent duplicates
  const pendingCompanyRequests = useRef(new Set<string>());
  const pendingLineRequests = useRef(new Set<string>());

  /**
   * Fetch product lines for a company
   * IMPORTANT: This callback is stable - no subscriptions, only store actions
   */
  const fetchProductLines = useCallback(
    async (companyId: string): Promise<SelectOption[]> => {
      if (!companyId) return [];

      // Check cache first via getState()
      const cached = useValidationStore.getState().productLinesCache.get(companyId);
      if (cached) return cached;

      // Check if already fetching
      if (pendingCompanyRequests.current.has(companyId)) {
        // Wait for the pending request
        return new Promise((resolve) => {
          const checkInterval = setInterval(() => {
            const result = useValidationStore.getState().productLinesCache.get(companyId);
            if (result !== undefined) {
              clearInterval(checkInterval);
              resolve(result);
            }
          }, 100);

          // Timeout after 10 seconds
          setTimeout(() => {
            clearInterval(checkInterval);
            resolve([]);
          }, 10000);
        });
      }

      pendingCompanyRequests.current.add(companyId);
      setLoadingProductLines(companyId, true);

      try {
        const lines = await fetchProductLinesApi(companyId);
        setProductLines(companyId, lines);
        return lines;
      } catch (error) {
        console.error(`Error fetching product lines for company ${companyId}:`, error);
        setProductLines(companyId, []); // Cache empty to prevent retries
        return [];
      } finally {
        pendingCompanyRequests.current.delete(companyId);
        setLoadingProductLines(companyId, false);
      }
    },
    [setProductLines, setLoadingProductLines] // Only stable store actions as deps
  );

  /**
   * Fetch sublines for a product line
   * IMPORTANT: This callback is stable - no subscriptions, only store actions
   */
  const fetchSublines = useCallback(
    async (lineId: string): Promise<SelectOption[]> => {
      if (!lineId) return [];

      // Check cache first via getState()
      const cached = useValidationStore.getState().sublinesCache.get(lineId);
      if (cached) return cached;

      // Check if already fetching
      if (pendingLineRequests.current.has(lineId)) {
        return new Promise((resolve) => {
          const checkInterval = setInterval(() => {
            const result = useValidationStore.getState().sublinesCache.get(lineId);
            if (result !== undefined) {
              clearInterval(checkInterval);
              resolve(result);
            }
          }, 100);

          setTimeout(() => {
            clearInterval(checkInterval);
            resolve([]);
          }, 10000);
        });
      }

      pendingLineRequests.current.add(lineId);
      setLoadingSublines(lineId, true);

      try {
        const sublines = await fetchSublinesApi(lineId);
        setSublines(lineId, sublines);
        return sublines;
      } catch (error) {
        console.error(`Error fetching sublines for line ${lineId}:`, error);
        setSublines(lineId, []); // Cache empty to prevent retries
        return [];
      } finally {
        pendingLineRequests.current.delete(lineId);
        setLoadingSublines(lineId, false);
      }
    },
    [setSublines, setLoadingSublines] // Only stable store actions as deps
  );

  /**
   * Prefetch product lines and sublines for all rows
   * PERFORMANCE: Uses getState() to read rows at action time
   */
  const prefetchAllLines = useCallback(async () => {
    // Get rows at action time via getState()
    const currentRows = useValidationStore.getState().rows;

    // Collect unique company IDs
    const companyIds = new Set<string>();
    const lineIds = new Set<string>();

    currentRows.forEach((row) => {
      if (row.company) companyIds.add(String(row.company));
      if (row.line) lineIds.add(String(row.line));
    });

    // Fetch all product lines in parallel
    await Promise.all(
      Array.from(companyIds).map((companyId) => fetchProductLines(companyId))
    );

    // Fetch all sublines in parallel
    await Promise.all(
      Array.from(lineIds).map((lineId) => fetchSublines(lineId))
    );
  }, [fetchProductLines, fetchSublines]);

  /**
   * Get product lines for a company (from cache)
   */
  const getProductLines = useCallback(
    (companyId: string): SelectOption[] => {
      return useValidationStore.getState().productLinesCache.get(companyId) || [];
    },
    []
  );

  /**
   * Get sublines for a line (from cache)
   */
  const getSublines = useCallback(
    (lineId: string): SelectOption[] => {
      return useValidationStore.getState().sublinesCache.get(lineId) || [];
    },
    []
  );

  /**
   * Check if product lines are loading for a company
   */
  const isLoadingProductLines = useCallback(
    (companyId: string): boolean => {
      return pendingCompanyRequests.current.has(companyId);
    },
    []
  );

  /**
   * Check if sublines are loading for a line
   */
  const isLoadingSublines = useCallback(
    (lineId: string): boolean => {
      return pendingLineRequests.current.has(lineId);
    },
    []
  );

  return {
    fetchProductLines,
    fetchSublines,
    prefetchAllLines,
    getProductLines,
    getSublines,
    isLoadingProductLines,
    isLoadingSublines,
  };
};
