/**
 * 📄 FiscalDocumentService - Gestão de Documentos Fiscais
 * 
 * Service responsável por operações CRUD de documentos fiscais NFe/NFCe,
 * validações e integração futura com SEFAZ.
 * 
 * ✨ Funcionalidades:
 * - CRUD de documentos fiscais
 * - Validações NFe/NFCe
 * - Sistema de fallback
 * - Preparação para integração SEFAZ
 */

import { Injectable } from '@angular/core';
import { Observable, of, catchError } from 'rxjs';

// Interfaces
import { 
  FiscalDocument, 
  FiscalDocumentResponse, 
  FiscalDocumentFilters,
  FiscalDocumentValidation 
} from '../route-stops.interface';

// Services
import { ApiClientService } from '../../../shared/services/api/api-client.service';

// Mock Data
import { 
  mockFiscalDocuments, 
  getFiscalDocumentById 
} from '../route-stops-mock.data';

@Injectable({
  providedIn: 'root'
})
export class FiscalDocumentService {

  constructor(
    private apiClient: ApiClientService
  ) {}

  // ========================================
  // 📊 BUSCA E LISTAGEM
  // ========================================

  getFiscalDocuments(filters: FiscalDocumentFilters): Observable<FiscalDocumentResponse> {
    let url = 'fiscal-documents?';
    
    // Construir query parameters
    const params = new URLSearchParams();
    
    if (filters.documentType?.length) params.append('documentType', filters.documentType.join(','));
    if (filters.status?.length) params.append('status', filters.status.join(','));
    if (filters.productType?.length) params.append('productType', filters.productType.join(','));
    if (filters.minValue) params.append('minValue', filters.minValue.toString());
    if (filters.maxValue) params.append('maxValue', filters.maxValue.toString());
    if (filters.emitterCnpj) params.append('emitterCnpj', filters.emitterCnpj);
    if (filters.page) params.append('page', filters.page.toString());
    if (filters.limit) params.append('limit', filters.limit.toString());
    
    if (filters.dateRange) {
      params.append('startDate', filters.dateRange.start.toISOString());
      params.append('endDate', filters.dateRange.end.toISOString());
    }
    
    url += params.toString();

    return this.apiClient.get<FiscalDocumentResponse>(url).pipe(
      catchError(error => {
        console.warn('⚠️ Backend indisponível para fiscal-documents, usando dados de fallback', error);
        return of(this.getFallbackFiscalDocuments(filters));
      })
    );
  }

  getFiscalDocumentById(id: string): Observable<FiscalDocument> {
    return this.apiClient.get<FiscalDocument>(`fiscal-documents/${id}`).pipe(
      catchError(error => {
        console.warn('⚠️ Backend indisponível, usando dados de fallback', error);
        const mockDocument = getFiscalDocumentById(id);
        if (mockDocument) {
          return of(mockDocument);
        }
        throw error;
      })
    );
  }

  // ========================================
  // 💾 OPERAÇÕES CRUD
  // ========================================

  createFiscalDocument(documentData: Partial<FiscalDocument>): Observable<FiscalDocument> {
    // Validar dados antes de enviar
    const validation = this.validateFiscalDocument(documentData);
    if (!validation.isValid) {
      throw new Error(`Documento fiscal inválido: ${validation.errors.join(', ')}`);
    }

    return this.apiClient.post<FiscalDocument>('fiscal-documents', documentData).pipe(
      catchError(error => {
        console.warn('⚠️ Backend indisponível, simulando criação', error);
        
        // Simular criação com dados mock
        const newDocument: FiscalDocument = {
          fiscalDocumentId: `doc_${Date.now()}`,
          documentType: documentData.documentType || 'NFCe',
          documentNumber: documentData.documentNumber || '',
          series: documentData.series || null,
          accessKey: documentData.accessKey || null,
          issueDate: documentData.issueDate || new Date(),
          totalValue: documentData.totalValue || 0,
          productType: documentData.productType || '',
          status: 'pending',
          createdAt: new Date(),
          updatedAt: new Date(),
          ...documentData
        } as FiscalDocument;
        
        return of(newDocument);
      })
    );
  }

  updateFiscalDocument(id: string, documentData: Partial<FiscalDocument>): Observable<FiscalDocument> {
    // Validar dados antes de enviar
    const validation = this.validateFiscalDocument(documentData);
    if (!validation.isValid) {
      throw new Error(`Documento fiscal inválido: ${validation.errors.join(', ')}`);
    }

    return this.apiClient.patch<FiscalDocument>(`fiscal-documents/${id}`, documentData).pipe(
      catchError(error => {
        console.warn('⚠️ Backend indisponível, simulando atualização', error);
        
        // Simular atualização com dados mock
        const existingDocument = getFiscalDocumentById(id);
        if (existingDocument) {
          const updatedDocument: FiscalDocument = {
            ...existingDocument,
            ...documentData,
            updatedAt: new Date()
          };
          return of(updatedDocument);
        }
        
        throw error;
      })
    );
  }

  deleteFiscalDocument(id: string): Observable<void> {
    return this.apiClient.delete<void>(`fiscal-documents/${id}`).pipe(
      catchError(error => {
        console.warn('⚠️ Backend indisponível, simulando exclusão', error);
        return of(undefined);
      })
    );
  }

  // ========================================
  // ✅ VALIDAÇÕES
  // ========================================

  validateFiscalDocument(document: Partial<FiscalDocument>): FiscalDocumentValidation {
    const errors: string[] = [];
    const warnings: string[] = [];

    // Validações obrigatórias
    if (!document.documentNumber) {
      errors.push('Número do documento é obrigatório');
    }

    if (!document.issueDate) {
      errors.push('Data de emissão é obrigatória');
    }

    if (!document.totalValue || document.totalValue <= 0) {
      errors.push('Valor total deve ser maior que zero');
    }

    if (!document.productType) {
      errors.push('Tipo de produto é obrigatório');
    }

    if (!document.documentType) {
      errors.push('Tipo de documento (NFe/NFCe) é obrigatório');
    }

    // Validações específicas
    const numberValid = this.validateDocumentNumber(document.documentNumber);
    const dateValid = this.validateIssueDate(document.issueDate);
    const valueValid = this.validateTotalValue(document.totalValue);
    const accessKeyValid = this.validateAccessKey(document.accessKey);

    if (!numberValid) {
      errors.push('Número do documento deve conter apenas dígitos');
    }

    if (!dateValid) {
      errors.push('Data de emissão não pode ser futura');
    }

    if (!valueValid) {
      errors.push('Valor total inválido');
    }

    if (document.accessKey && !accessKeyValid) {
      errors.push('Chave de acesso deve ter exatamente 44 dígitos');
    }

    // Warnings
    if (document.documentType === 'NFCe' && document.series) {
      warnings.push('NFCe geralmente não possui série');
    }

    if (document.documentType === 'NFe' && !document.accessKey) {
      warnings.push('NFe deveria ter chave de acesso');
    }

    return {
      isValid: errors.length === 0,
      errors,
      warnings,
      numberValid,
      dateValid,
      valueValid,
      accessKeyValid,
      formatValid: errors.length === 0
    };
  }

  private validateDocumentNumber(number?: string): boolean {
    if (!number) return false;
    return /^\d+$/.test(number);
  }

  private validateIssueDate(date?: Date): boolean {
    if (!date) return false;
    return date <= new Date();
  }

  private validateTotalValue(value?: number): boolean {
    if (value === undefined || value === null) return false;
    return value > 0;
  }

  private validateAccessKey(key?: string | null): boolean {
    if (!key) return true; // Chave é opcional
    return /^\d{44}$/.test(key);
  }

  // ========================================
  // 🔍 CONSULTA SEFAZ (FUTURO)
  // ========================================

  consultSefaz(accessKey: string): Observable<any> {
    // TODO: Implementar integração com SEFAZ
    return this.apiClient.get<any>(`fiscal-documents/sefaz/${accessKey}`).pipe(
      catchError(error => {
        console.warn('⚠️ Consulta SEFAZ indisponível', error);
        return of({
          situation: 'Não consultado',
          message: 'Serviço SEFAZ temporariamente indisponível'
        });
      })
    );
  }

  // ========================================
  // 📊 ESTATÍSTICAS
  // ========================================

  getFiscalDocumentsStats(): Observable<any> {
    return this.apiClient.get<any>('fiscal-documents/stats').pipe(
      catchError(error => {
        console.warn('⚠️ Backend indisponível, usando estatísticas mock', error);
        
        const stats = {
          totalDocuments: mockFiscalDocuments.length,
          nfeCount: mockFiscalDocuments.filter(d => d.documentType === 'NFe').length,
          nfceCount: mockFiscalDocuments.filter(d => d.documentType === 'NFCe').length,
          totalValue: mockFiscalDocuments.reduce((sum, d) => sum + d.totalValue, 0),
          validatedCount: mockFiscalDocuments.filter(d => d.status === 'validated').length,
          pendingCount: mockFiscalDocuments.filter(d => d.status === 'pending').length,
          errorCount: mockFiscalDocuments.filter(d => d.status === 'error').length
        };
        
        return of(stats);
      })
    );
  }

  // ========================================
  // 🔄 DADOS DE FALLBACK
  // ========================================

  private getFallbackFiscalDocuments(filters: FiscalDocumentFilters): FiscalDocumentResponse {
    let filteredDocuments = [...mockFiscalDocuments];

    // Aplicar filtros
    if (filters.documentType?.length) {
      filteredDocuments = filteredDocuments.filter(doc => 
        filters.documentType!.includes(doc.documentType)
      );
    }

    if (filters.status?.length) {
      filteredDocuments = filteredDocuments.filter(doc => 
        filters.status!.includes(doc.status)
      );
    }

    if (filters.productType?.length) {
      filteredDocuments = filteredDocuments.filter(doc => 
        filters.productType!.some(type => 
          doc.productType.toLowerCase().includes(type.toLowerCase())
        )
      );
    }

    if (filters.minValue !== undefined) {
      filteredDocuments = filteredDocuments.filter(doc => 
        doc.totalValue >= filters.minValue!
      );
    }

    if (filters.maxValue !== undefined) {
      filteredDocuments = filteredDocuments.filter(doc => 
        doc.totalValue <= filters.maxValue!
      );
    }

    if (filters.emitterCnpj) {
      filteredDocuments = filteredDocuments.filter(doc => 
        doc.emitter?.cnpj.includes(filters.emitterCnpj!)
      );
    }

    if (filters.dateRange) {
      filteredDocuments = filteredDocuments.filter(doc => 
        doc.issueDate >= filters.dateRange!.start && 
        doc.issueDate <= filters.dateRange!.end
      );
    }

    // Paginação
    const page = filters.page || 1;
    const limit = filters.limit || 10;
    const startIndex = (page - 1) * limit;
    const endIndex = startIndex + limit;
    
    const paginatedDocuments = filteredDocuments.slice(startIndex, endIndex);

    return {
      data: paginatedDocuments,
      pagination: {
        total: filteredDocuments.length,
        page: page,
        limit: limit,
        totalPages: Math.ceil(filteredDocuments.length / limit)
      },
      source: 'fallback',
      timestamp: new Date().toISOString()
    };
  }
} 