import { useCallback, useState } from 'react';
import { pipelineApi } from '../services/pipelineApi';
import type {
  DataClearType,
  ExchangeStats,
  PipelineJobResult,
  ProviderMappingStats,
} from '../types';

export function usePipeline() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [lastJobResult, setLastJobResult] = useState<PipelineJobResult | null>(null);

  const executeOperation = useCallback(
    async (operation: () => Promise<PipelineJobResult>): Promise<boolean> => {
      try {
        setLoading(true);
        setError(null);
        const result = await operation();
        setLastJobResult(result);
        if (!result.success) {
          setError(result.error || 'Operation failed');
          return false;
        }
        return true;
      } catch (err) {
        const errorMessage = err instanceof Error ? err.message : 'Unknown error occurred';
        setError(errorMessage);
        setLastJobResult({ success: false, error: errorMessage });
        return false;
      } finally {
        setLoading(false);
      }
    },
    []
  );

  // Symbol sync operations
  const syncQMSymbols = useCallback(
    () => executeOperation(() => pipelineApi.syncQMSymbols()),
    [executeOperation]
  );

  const syncProviderSymbols = useCallback(
    (provider: string) => executeOperation(() => pipelineApi.syncProviderSymbols(provider)),
    [executeOperation]
  );

  // Exchange sync operations
  const syncQMExchanges = useCallback(
    () => executeOperation(() => pipelineApi.syncQMExchanges()),
    [executeOperation]
  );

  const syncAllExchanges = useCallback(
    (clearFirst: boolean = false) =>
      executeOperation(() => pipelineApi.syncAllExchanges(clearFirst)),
    [executeOperation]
  );

  // Provider mapping sync operations
  const syncQMProviderMappings = useCallback(
    () => executeOperation(() => pipelineApi.syncQMProviderMappings()),
    [executeOperation]
  );

  const syncIBExchanges = useCallback(
    () => executeOperation(() => pipelineApi.syncIBExchanges()),
    [executeOperation]
  );

  // Maintenance operations
  const clearPostgreSQLData = useCallback(
    (dataType: DataClearType = 'all') =>
      executeOperation(() => pipelineApi.clearPostgreSQLData(dataType)),
    [executeOperation]
  );

  // Status and stats operations
  const getSyncStatus = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const result = await pipelineApi.getSyncStatus();
      return result;
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Failed to get sync status';
      setError(errorMessage);
      return null;
    } finally {
      setLoading(false);
    }
  }, []);

  const getExchangeStats = useCallback(async (): Promise<ExchangeStats | null> => {
    try {
      setLoading(true);
      setError(null);
      const result = await pipelineApi.getExchangeStats();
      if (result.success && result.data) {
        return result.data as ExchangeStats;
      }
      setError(result.error || 'Failed to get exchange stats');
      return null;
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Failed to get exchange stats';
      setError(errorMessage);
      return null;
    } finally {
      setLoading(false);
    }
  }, []);

  const getProviderMappingStats = useCallback(async (): Promise<ProviderMappingStats | null> => {
    try {
      setLoading(true);
      setError(null);
      const result = await pipelineApi.getProviderMappingStats();
      if (result.success && result.data) {
        return result.data as ProviderMappingStats;
      }
      setError(result.error || 'Failed to get provider mapping stats');
      return null;
    } catch (err) {
      const errorMessage =
        err instanceof Error ? err.message : 'Failed to get provider mapping stats';
      setError(errorMessage);
      return null;
    } finally {
      setLoading(false);
    }
  }, []);

  return {
    // State
    loading,
    error,
    lastJobResult,

    // Symbol operations
    syncQMSymbols,
    syncProviderSymbols,

    // Exchange operations
    syncQMExchanges,
    syncAllExchanges,

    // Provider mapping operations
    syncQMProviderMappings,
    syncIBExchanges,

    // Maintenance operations
    clearPostgreSQLData,

    // Status and stats operations
    getSyncStatus,
    getExchangeStats,
    getProviderMappingStats,
  };
}
