/**
 * Data Import React Query hooks
 * Provides data fetching, caching, and state management for data import operations
 */

import { useMutation, useQuery, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
import { dataImportService } from '../services/dataImport';
import { ApiError } from '../client/apiClient';
import type {
  ImportValidationResponse,
  ImportProcessResponse,
  ImportStatusResponse,
} from '../types/dataImport';

// Query Keys Factory
export const dataImportKeys = {
  all: ['data-import'] as const,
  status: (tenantId: string, importId: string) => 
    [...dataImportKeys.all, 'status', tenantId, importId] as const,
} as const;

// Status Query
export const useImportStatus = (
  tenantId: string,
  importId: string,
  options?: Omit<UseQueryOptions<ImportStatusResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
  return useQuery<ImportStatusResponse, ApiError>({
    queryKey: dataImportKeys.status(tenantId, importId),
    queryFn: () => dataImportService.getImportStatus(tenantId, importId),
    enabled: !!tenantId && !!importId,
    refetchInterval: 5000, // Poll every 5 seconds for active imports
    staleTime: 1000, // Consider data stale after 1 second
    ...options,
  });
};

// Validation Mutations
export const useValidateJsonData = (
  options?: UseMutationOptions<
    ImportValidationResponse,
    ApiError,
    { tenantId: string; data: any }
  >
) => {
  return useMutation<
    ImportValidationResponse,
    ApiError,
    { tenantId: string; data: any }
  >({
    mutationFn: ({ tenantId, data }) => dataImportService.validateJsonData(tenantId, data),
    ...options,
  });
};

export const useValidateCsvFile = (
  options?: UseMutationOptions<
    ImportValidationResponse,
    ApiError,
    { tenantId: string; file: File }
  >
) => {
  return useMutation<
    ImportValidationResponse,
    ApiError,
    { tenantId: string; file: File }
  >({
    mutationFn: ({ tenantId, file }) => dataImportService.validateCsvFile(tenantId, file),
    ...options,
  });
};

// Import Mutations
export const useImportJsonData = (
  options?: UseMutationOptions<
    ImportProcessResponse,
    ApiError,
    { tenantId: string; data: any; options?: { skip_validation?: boolean; chunk_size?: number } }
  >
) => {
  return useMutation<
    ImportProcessResponse,
    ApiError,
    { tenantId: string; data: any; options?: { skip_validation?: boolean; chunk_size?: number } }
  >({
    mutationFn: ({ tenantId, data, options: importOptions }) => 
      dataImportService.importJsonData(tenantId, data, importOptions),
    ...options,
  });
};

export const useImportCsvFile = (
  options?: UseMutationOptions<
    ImportProcessResponse,
    ApiError,
    { tenantId: string; file: File; options?: { skip_validation?: boolean; chunk_size?: number } }
  >
) => {
  return useMutation<
    ImportProcessResponse,
    ApiError,
    { tenantId: string; file: File; options?: { skip_validation?: boolean; chunk_size?: number } }
  >({
    mutationFn: ({ tenantId, file, options: importOptions }) => 
      dataImportService.importCsvFile(tenantId, file, importOptions),
    ...options,
  });
};

// Combined validation and import hook for easier use
// Validation-only hook for onboarding
export const useValidateFileOnly = () => {
  const validateCsv = useValidateCsvFile();
  const validateJson = useValidateJsonData();

  const validateFile = async (
    tenantId: string,
    file: File,
    options?: {
      onProgress?: (stage: string, progress: number, message: string) => void;
    }
  ): Promise<{
    validationResult?: ImportValidationResponse;
    success: boolean;
    error?: string;
  }> => {
    try {
      let validationResult: ImportValidationResponse | undefined;

      options?.onProgress?.('validating', 20, 'Validando estructura del archivo...');
      
      const fileExtension = file.name.split('.').pop()?.toLowerCase();
      if (fileExtension === 'csv') {
        validationResult = await validateCsv.mutateAsync({ tenantId, file });
      } else if (fileExtension === 'json') {
        const jsonData = await file.text().then(text => JSON.parse(text));
        validationResult = await validateJson.mutateAsync({ tenantId, data: jsonData });
      } else {
        throw new Error('Formato de archivo no soportado. Use CSV o JSON.');
      }

      options?.onProgress?.('validating', 50, 'Verificando integridad de datos...');

      if (!validationResult.is_valid) {
        const errorMessage = validationResult.errors && validationResult.errors.length > 0 
          ? validationResult.errors.join(', ')
          : 'Error de validación desconocido';
        throw new Error(`Archivo inválido: ${errorMessage}`);
      }
      
      // Report validation success with details
      options?.onProgress?.('completed', 100, 
        `Archivo validado: ${validationResult.valid_records} registros válidos de ${validationResult.total_records} totales`
      );

      return {
        validationResult,
        success: true,
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Error validando archivo';
      options?.onProgress?.('error', 0, errorMessage);
      
      return {
        success: false,
        error: errorMessage,
      };
    }
  };

  return {
    validateFile,
  };
};

// Full validation + import hook (for later use)
export const useValidateAndImportFile = () => {
  const validateCsv = useValidateCsvFile();
  const validateJson = useValidateJsonData();
  const importCsv = useImportCsvFile();
  const importJson = useImportJsonData();

  const processFile = async (
    tenantId: string,
    file: File,
    options?: {
      skipValidation?: boolean;
      chunkSize?: number;
      onProgress?: (stage: string, progress: number, message: string) => void;
    }
  ): Promise<{
    validationResult?: ImportValidationResponse;
    importResult?: ImportProcessResponse;
    success: boolean;
    error?: string;
  }> => {
    try {
      let validationResult: ImportValidationResponse | undefined;

      // Step 1: Validation (unless skipped)
      if (!options?.skipValidation) {
        options?.onProgress?.('validating', 20, 'Validando estructura del archivo...');
        
        const fileExtension = file.name.split('.').pop()?.toLowerCase();
        if (fileExtension === 'csv') {
          validationResult = await validateCsv.mutateAsync({ tenantId, file });
        } else if (fileExtension === 'json') {
          const jsonData = await file.text().then(text => JSON.parse(text));
          validationResult = await validateJson.mutateAsync({ tenantId, data: jsonData });
        } else {
          throw new Error('Formato de archivo no soportado. Use CSV o JSON.');
        }

        options?.onProgress?.('validating', 50, 'Verificando integridad de datos...');

        if (!validationResult.is_valid) {
          const errorMessage = validationResult.errors && validationResult.errors.length > 0 
            ? validationResult.errors.join(', ')
            : 'Error de validación desconocido';
          throw new Error(`Archivo inválido: ${errorMessage}`);
        }
        
        // Report validation success with details
        options?.onProgress?.('validating', 60, 
          `Archivo validado: ${validationResult.valid_records} registros válidos de ${validationResult.total_records} totales`
        );
      }

      // Step 2: Import
      options?.onProgress?.('importing', 70, 'Importando datos...');
      
      const importOptions = {
        skip_validation: options?.skipValidation || false,
        chunk_size: options?.chunkSize,
      };

      let importResult: ImportProcessResponse;
      const fileExtension = file.name.split('.').pop()?.toLowerCase();
      
      if (fileExtension === 'csv') {
        importResult = await importCsv.mutateAsync({ 
          tenantId, 
          file, 
          options: importOptions 
        });
      } else if (fileExtension === 'json') {
        const jsonData = await file.text().then(text => JSON.parse(text));
        importResult = await importJson.mutateAsync({ 
          tenantId, 
          data: jsonData, 
          options: importOptions 
        });
      } else {
        throw new Error('Formato de archivo no soportado. Use CSV o JSON.');
      }

      // Report completion with details
      const completionMessage = importResult.success 
        ? `Importación completada: ${importResult.records_processed} registros procesados`
        : `Importación fallida: ${importResult.errors?.join(', ') || 'Error desconocido'}`;
        
      options?.onProgress?.('completed', 100, completionMessage);

      return {
        validationResult,
        importResult,
        success: importResult.success,
        error: importResult.success ? undefined : (importResult.errors?.join(', ') || 'Error en la importación'),
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Error procesando archivo';
      options?.onProgress?.('error', 0, errorMessage);
      
      return {
        success: false,
        error: errorMessage,
      };
    }
  };

  return {
    processFile,
    validateCsv,
    validateJson,
    importCsv,
    importJson,
    isValidating: validateCsv.isPending || validateJson.isPending,
    isImporting: importCsv.isPending || importJson.isPending,
    isLoading: validateCsv.isPending || validateJson.isPending || importCsv.isPending || importJson.isPending,
    error: validateCsv.error || validateJson.error || importCsv.error || importJson.error,
  };
};

// Import-only hook (for when validation has already been done)
export const useImportFileOnly = () => {
  const importCsv = useImportCsvFile();
  const importJson = useImportJsonData();

  const importFile = async (
    tenantId: string,
    file: File,
    options?: {
      chunkSize?: number;
      onProgress?: (stage: string, progress: number, message: string) => void;
    }
  ): Promise<{
    importResult?: ImportProcessResponse;
    success: boolean;
    error?: string;
  }> => {
    try {
      options?.onProgress?.('importing', 10, 'Iniciando importación de datos...');
      
      const fileExtension = file.name.split('.').pop()?.toLowerCase();
      let importResult: ImportProcessResponse;
      
      if (fileExtension === 'csv') {
        importResult = await importCsv.mutateAsync({
          tenantId,
          file,
          options: { 
            skip_validation: true, // Skip validation since already done
            chunk_size: options?.chunkSize 
          }
        });
      } else if (fileExtension === 'json') {
        const jsonData = await file.text().then(text => JSON.parse(text));
        importResult = await importJson.mutateAsync({
          tenantId,
          data: jsonData,
          options: { 
            skip_validation: true, // Skip validation since already done
            chunk_size: options?.chunkSize 
          }
        });
      } else {
        throw new Error('Formato de archivo no soportado. Use CSV o JSON.');
      }

      options?.onProgress?.('completed', 100, 
        `Importación completada: ${importResult.records_processed} registros procesados`
      );

      return {
        importResult,
        success: importResult.success,
        error: importResult.success ? undefined : (importResult.errors?.join(', ') || 'Error en la importación'),
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Error importando archivo';
      options?.onProgress?.('error', 0, errorMessage);
      
      return {
        success: false,
        error: errorMessage,
      };
    }
  };

  return {
    importFile,
    isImporting: importCsv.isPending || importJson.isPending,
    error: importCsv.error || importJson.error,
  };
};