import { Injectable } from '@angular/core';
import { Observable, switchMap, map, catchError, of } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import { ApiClientService } from '../../services/api/api-client.service';
import { ImageUploadService } from '../image-uploader/image-uploader.service';
import { DataUrlFile } from '../../interfaces/image.interface';
import { 
  CsvValidationResponse, 
  CsvValidationResult, 
  ImportResult 
} from './csv-importer.interface';

/**
 * 📊 CsvImporterService
 * 
 * Service para importação de arquivos CSV que segue o mesmo padrão do ImageUploadService:
 * 1. Validação prévia (novo passo)
 * 2. Upload via get-upload-url (reutiliza sistema existente)
 * 3. Confirmação/importação final
 */
@Injectable({
  providedIn: 'root'
})
export class CsvImporterService {

  constructor(
    private apiClient: ApiClientService,
    private imageUploadService: ImageUploadService,
    private http: HttpClient
  ) {}

    /**
   * 🔍 ETAPA 1: Validação prévia do CSV
   * Endpoint: POST /account-payable/validate/csv
   * Content-Type: multipart/form-data (automático com FormData)
   */
    validateCsv(file: File): Observable<CsvValidationResult> {
    console.log('📤 Iniciando validação do CSV:', {
      fileName: file.name,
      fileSize: file.size,
      fileType: file.type
    });

    // 🔄 Primeiro, fazer validação local
    return this.validateCsvLocally(file).pipe(
      switchMap(localValidation => {
        if (!localValidation.valid) {
          console.log('❌ Validação local falhou:', localValidation.errors);
          return of(localValidation);
        }

        // 🌐 Tentar validação no servidor
        return this.validateCsvOnServer(file).pipe(
          catchError(error => {
            console.warn('⚠️ Validação no servidor falhou, usando validação local:', error);
            
            // Se o servidor falhar, retornar validação local com aviso adicional
            return of({
              ...localValidation,
              warnings: [
                ...(localValidation.warnings || []),
                'Validação do servidor não disponível.',
                'Alguns erros podem não ser detectados até a importação.'
              ]
            });
          })
        );
      })
    );
  }

    /**
   * 🔍 Validação local do CSV (fallback)
   */
  private validateCsvLocally(file: File): Observable<CsvValidationResult> {
    const errors: string[] = [];
    const warnings: string[] = [];

    // Validar tipo de arquivo
    if (!file.name.toLowerCase().endsWith('.csv')) {
      errors.push('Arquivo deve ter extensão .csv');
    }

    // Validar tamanho
    const sizeMb = file.size / (1024 * 1024);
    if (sizeMb > 10) {
      errors.push(`Arquivo muito grande (${sizeMb.toFixed(2)}MB). Máximo: 10MB`);
    }

    if (sizeMb === 0) {
      errors.push('Arquivo está vazio');
    }

    // Se há erros, retornar inválido
    if (errors.length > 0) {
      return of({
        valid: false,
        errors,
        warnings
      });
    }

    // 📖 Ler arquivo para contar linhas e fazer preview
    return new Observable<CsvValidationResult>(observer => {
      const reader = new FileReader();
      
      reader.onload = (e) => {
        try {
          const content = e.target?.result as string;
          const lines = content.split('\n').filter(line => line.trim() !== '');
          const totalRows = Math.max(0, lines.length - 1); // Subtrair header
          
          // Pegar primeiras linhas para preview
          const previewLines = lines.slice(0, 6); // Header + 5 linhas de dados
          const headers = previewLines.length > 0 ? previewLines[0].split(',').map(h => h.trim()) : [];
          const dataRows = previewLines.slice(1).map(line => line.split(',').map(cell => cell.trim()));

          const result: CsvValidationResult = {
            valid: true,
            totalRows,
            validRows: totalRows, // Assumir que todas são válidas na validação local
            invalidRows: 0,
            errors: [],
            warnings: [
              'Validação local concluída.',
              `Encontradas ${totalRows} linhas de dados (${headers.length} colunas).`,
              'Validação completa será feita na importação.'
            ],
            preview: {
              headers,
              rows: dataRows,
              totalRows,
              previewRows: dataRows.length
            }
          };

          console.log('📊 Validação local concluída:', {
            totalRows,
            headers: headers.length,
            previewRows: dataRows.length
          });

          observer.next(result);
          observer.complete();
        } catch (error) {
          observer.next({
            valid: false,
            errors: [`Erro ao ler arquivo: ${error}`],
            warnings
          });
          observer.complete();
        }
      };

      reader.onerror = () => {
        observer.next({
          valid: false,
          errors: ['Erro ao ler o arquivo'],
          warnings
        });
        observer.complete();
      };

      reader.readAsText(file, 'UTF-8');
    });
  }

  /**
   * 🌐 Validação no servidor (preferencial)
   */
  private validateCsvOnServer(file: File): Observable<CsvValidationResult> {
    const formData = new FormData();
    formData.append('file', file);

    const endpoint = 'account-payable/validate/csv';
    
    console.log('📤 Enviando CSV para validação no servidor:', {
      endpoint: this.apiClient.buildUrl(endpoint)
    });

    return this.http.post<CsvValidationResponse>(
      this.apiClient.buildUrl(endpoint), 
      formData
    ).pipe(
      map(response => {
        console.log('✅ Resposta da validação do servidor:', response);
        if (response.success && response.data) {
          return response.data;
        }
        throw new Error(response.message || 'Erro na validação do CSV');
      })
    );
  }

  /**
   * ⬆️ ETAPA 2: Upload do arquivo (reutiliza sistema existente)
   * Mesmo fluxo do ImageUploadService:
   * 1. GET /file/get-upload-url
   * 2. PUT para S3
   * 3. POST /file/confirm
   */
  uploadCsv(file: File): Observable<string> {
    // Garantir que o arquivo tem uma extensão CSV
    const csvFile = file.name.endsWith('.csv') 
      ? file 
      : new File([file], `${file.name.replace(/\.[^/.]+$/, '')}.csv`, { type: 'text/csv' });

    return this.imageUploadService.uploadImageUrl(csvFile.name).pipe(
      switchMap((dataUrlFile: DataUrlFile) =>
        this.http.put(dataUrlFile.data.uploadUrl, csvFile).pipe(
          switchMap(() =>
            this.imageUploadService.uploadImageConfirm(dataUrlFile.data.storageKey)
          )
        )
      ),
      map((response: any) => {
        if (response && response.data && response.data.id) {
          return response.data.id.toString();
        }
        throw new Error('Resposta inválida do servidor no upload');
      }),
      catchError(error => {
        console.error('Erro no upload do CSV:', error);
        throw error;
      })
    );
  }

  /**
   * 📥 ETAPA 3: Importação final do CSV
   * Endpoint: POST /account-payable/import/csv/{fileId}
   */
  importCsv(fileId: string): Observable<ImportResult> {
    return this.apiClient.post<ImportResult>(`account-payable/import/csv/${fileId}`, {})
      .pipe(
        map(response => {
          if (response.success) {
            return response;
          }
          throw new Error(response.message || 'Erro na importação do CSV');
        }),
        catchError(error => {
          console.error('Erro ao importar CSV:', error);
          const errorResult: ImportResult = {
            success: false,
            message: error.message || 'Erro desconhecido na importação',
            errors: [error.message]
          };
          return of(errorResult);
        })
      );
  }

  /**
   * 📋 Método auxiliar: Validar tipo de arquivo
   */
  isValidCsvFile(file: File): { valid: boolean; error?: string } {
    // Verificar extensão
    if (!file.name.toLowerCase().endsWith('.csv')) {
      return { valid: false, error: 'Apenas arquivos .csv são permitidos' };
    }

    // Verificar tipo MIME (alguns browsers)
    const validMimeTypes = ['text/csv', 'application/csv', 'text/plain'];
    if (file.type && !validMimeTypes.includes(file.type)) {
      return { valid: false, error: 'Tipo de arquivo inválido' };
    }

    return { valid: true };
  }

  /**
   * 📏 Método auxiliar: Validar tamanho do arquivo
   */
  isValidFileSize(file: File, maxSizeMb: number): { valid: boolean; error?: string } {
    const sizeMb = file.size / (1024 * 1024);
    
    if (sizeMb > maxSizeMb) {
      return { 
        valid: false, 
        error: `Arquivo muito grande. Tamanho máximo: ${maxSizeMb}MB` 
      };
    }

    return { valid: true };
  }

  /**
   * 🎯 Método auxiliar: Validação completa do arquivo
   */
  validateFile(file: File, maxSizeMb: number = 10): { valid: boolean; errors: string[] } {
    const errors: string[] = [];

    const typeValidation = this.isValidCsvFile(file);
    if (!typeValidation.valid) {
      errors.push(typeValidation.error!);
    }

    const sizeValidation = this.isValidFileSize(file, maxSizeMb);
    if (!sizeValidation.valid) {
      errors.push(sizeValidation.error!);
    }

    return {
      valid: errors.length === 0,
      errors
    };
  }
} 