import { useState, useEffect, useCallback, useRef } from 'react';
import { purchaserApi } from '../api';
import { CACHE_CONFIG } from '../config/app';
import { useInventoryRealtime } from './useRealtime';
import type {
  Product,
  ProductWithInventory,
  ProductYarnRatio,
  FabricBatch,
  ProductInRecord,
  FactoryInventory,
} from '../types';

interface UseInventoryDataOptions {
  companyId: string | null;
  activeType: string;
}

interface InventoryDataState {
  products: ProductWithInventory[];
  productRatios: Record<string, ProductYarnRatio[]>;
  batches: FabricBatch[];
  loading: boolean;
  error: Error | null;
}

export function useInventoryData({ companyId, activeType }: UseInventoryDataOptions) {
  const [state, setState] = useState<InventoryDataState>({
    products: [],
    productRatios: {},
    batches: [],
    loading: true,
    error: null
  });

  const cacheRef = useRef<{
    data: InventoryDataState | null;
    timestamp: number;
    key: string;
  }>({ data: null, timestamp: 0, key: '' });

  const CACHE_DURATION = CACHE_CONFIG.inventoryDataDuration;

  const fetchData = useCallback(async () => {
    if (!companyId || activeType !== 'raw_fabric') {
      setState(prev => ({ ...prev, loading: false }));
      return;
    }

    const cacheKey = `${companyId}-${activeType}`;
    const now = Date.now();

    if (
      cacheRef.current.data &&
      cacheRef.current.key === cacheKey &&
      now - cacheRef.current.timestamp < CACHE_DURATION
    ) {
      setState(cacheRef.current.data);
      return;
    }

    setState(prev => ({ ...prev, loading: true, error: null }));

    try {
      const productsRes = await purchaserApi.listProducts();
      const products: Product[] = productsRes.data;

      const recordResults = await Promise.all(
        products.map(p =>
          purchaserApi.getRecords(p.id).catch(() => [] as ProductInRecord[])
        )
      );

      const allBatches: FabricBatch[] = [];
      const updatedProducts: ProductWithInventory[] = products.map((p, i) => {
        const records = recordResults[i];
        const inRecords = records.filter(r => r.record_type !== 'out');
        const outRecords = records.filter(r => r.record_type === 'out');

        const totalInRolls = inRecords.reduce((sum, r) => sum + (r.rolls || 0), 0);
        const totalInMeters = inRecords.reduce((sum, r) => sum + (r.meters || 0), 0);
        const totalOutRolls = outRecords.reduce((sum, r) => sum + (r.rolls || 0), 0);
        const totalOutMeters = outRecords.reduce((sum, r) => sum + (r.meters || 0), 0);

        const factoryInventories: Record<string, FactoryInventory> = {};
        inRecords
          .filter(r => r.source === 'textile' && r.factory_name)
          .forEach(r => {
            const key = r.factory_name!;
            if (!factoryInventories[key]) {
              factoryInventories[key] = {
                factory_id: r.factory_id || 'unknown',
                factory_name: key,
                rolls: 0,
                meters: 0,
                records: [],
              };
            }
            factoryInventories[key].rolls += r.rolls || 0;
            factoryInventories[key].meters += r.meters || 0;
            factoryInventories[key].records.push(r);
          });

        inRecords.forEach(r => {
          allBatches.push({
            id: r.id,
            product_id: r.product_id,
            company_id: r.company_id || '',
            batch_no: r.batch_no,
            rolls: r.rolls,
            meters: r.meters,
            notes: r.notes,
            created_at: r.created_at,
            product: p,
            source: r.source,
            factory_name: r.factory_name,
            factory_id: r.factory_id,
          } as FabricBatch);
        });

        return {
          ...p,
          production_price: p.production_price || 0,
          raw_fabric_rolls: Math.max(0, totalInRolls - totalOutRolls),
          raw_fabric_meters: Math.max(0, totalInMeters - totalOutMeters),
          total_stock: Math.max(0, totalInMeters - totalOutMeters),
          factory_inventories: factoryInventories,
          in_records: inRecords,
          out_records: outRecords,
          total_in_rolls: totalInRolls,
          total_in_meters: totalInMeters,
          total_out_rolls: totalOutRolls,
          total_out_meters: totalOutMeters,
        } as ProductWithInventory;
      });

      const newState: InventoryDataState = {
        products: updatedProducts,
        productRatios: {},
        batches: allBatches,
        loading: false,
        error: null
      };

      cacheRef.current = {
        data: newState,
        timestamp: now,
        key: cacheKey
      };

      setState(newState);
    } catch (err) {
      setState(prev => ({
        ...prev,
        loading: false,
        error: err instanceof Error ? err : new Error('Unknown error')
      }));
    }
  }, [companyId, activeType]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  useInventoryRealtime(companyId, () => {
    cacheRef.current.timestamp = 0;
    fetchData();
  });

  return {
    ...state,
    refetch: fetchData
  };
}
