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


import { Supplier } from './supplier.interface';
import { ApiClientService } from '../../shared/services/api/api-client.service';
import { DomainService } from '../../shared/components/base-domain/base-domain.component';
import { PaginatedResponse } from '../../shared/interfaces/paginate.interface';


/**
 * 🎯 SupplierService - Serviço para gestão de Fornecedores
 * 
 * ✨ Implementa DomainService<Supplier>
 * 🚀 Padrões de nomenclatura obrigatórios: create, update, delete, getById, getSuppliers
 * 
 * 🆕 V2.0 Features:

 * - ApiClientService: NUNCA usar HttpClient diretamente
 * - Fallback: Dados mock para desenvolvimento
 */
@Injectable({
  providedIn: 'root'
})
export class SupplierService implements DomainService<Supplier> {

  constructor(
    private apiClient: ApiClientService
  ) {}

  // ========================================
  // 🎯 IMPLEMENTAÇÃO DA INTERFACE DOMAINSERVICE
  // ========================================

  getEntities(page: number, pageSize: number, filters: any): Observable<{
    data: Supplier[];
    totalCount: number;
    pageCount: number;
    currentPage: number;
  }> {
    return this.getSuppliers(page, pageSize, filters).pipe(
      map(response => ({
        data: response.data,
        totalCount: response.totalCount,  
        pageCount: response.pageCount,
        currentPage: response.currentPage
      }))
    );
  }

  create(data: any): Observable<Supplier> {
    return this.apiClient.post<Supplier>('supplier', data);
  }

  update(id: any, data: any): Observable<Supplier> {
    return this.apiClient.patch<Supplier>(`supplier/${id}`, data);
  }

  // ========================================
  // 🎯 MÉTODOS ESPECÍFICOS DO DOMÍNIO
  // ========================================

  getSuppliers(
    page = 1,
    limit = 10,
    filters?: any
  ): Observable<PaginatedResponse<Supplier>> {
    const processedFilters = this.processFilters(filters || {});
    
    let url = `supplier?page=${page}&limit=${limit}`;
    
    if (processedFilters && Object.keys(processedFilters).length > 0) {
      const params = new URLSearchParams();
      
      for (const [key, value] of Object.entries(processedFilters)) {
        if (value !== null && value !== undefined && value !== '') {

          if (Array.isArray(value)) {
            value.forEach(item => {
              if (item) {
                params.append(key, item.toString());
              }
            });
          } else {
            params.append(key, value.toString());
          }
        }
      }
      
      if (params.toString()) {
        url += `&${params.toString()}`;
      }
    }

    return this.apiClient.get<PaginatedResponse<Supplier>>(url).pipe(
      catchError(error => {
        console.warn('⚠️ Backend indisponível, usando dados de fallback', error);
        return of(this.getFallbackData(page, limit, processedFilters));
      })
    );
  }

  /**
   * 🎯 Processa filtros para o formato esperado pela API
   * Converte filtros do frontend para o formato da API /supplier
   * Suporta apenas: name, cpf, cnpj
   */
  private processFilters(filters: any): any {
    const processed: any = {};
    
    // 📝 Filtro por nome (string simples)
    if (filters.name && typeof filters.name === 'string') {
      const name = filters.name.trim();
      if (name.length >= 2) {
        processed.name = name;
      }
    }
    
    // 📝 Filtro por CPF (string individual)
    if (filters.cpf && typeof filters.cpf === 'string') {
      const cpf = filters.cpf.replace(/\D/g, ''); 
      if (cpf.length === 11) {
        processed.cpf = cpf;
      }
    }
    
    // 📝 Filtro por CNPJ (string individual)
    if (filters.cnpj && typeof filters.cnpj === 'string') {
      const cnpj = filters.cnpj.replace(/\D/g, '');
      if (cnpj.length === 14) {
        processed.cnpj = cnpj;
      }
    }
    
    return processed;
  }

  getById(id: string): Observable<Supplier> {
    return this.apiClient.get<Supplier>(`supplier/${id}`);
  }

  delete(id: string): Observable<void> {
    return this.apiClient.delete<void>(`supplier/${id}`);
  }

  

  private getFallbackData(page: number, limit: number, filters?: any): PaginatedResponse<Supplier> {
    const mockData: Supplier[] = [];
    
    const startIndex = (page - 1) * limit;
    const endIndex = startIndex + limit;
    const paginatedData = mockData.slice(startIndex, endIndex);
    
    const totalPages = Math.ceil(mockData.length / limit);
    
    return {
      data: paginatedData,
      totalCount: mockData.length,
      pageCount: totalPages,
      currentPage: page,
      isFirstPage: page === 1,
      isLastPage: page === totalPages,
      nextPage: page < totalPages ? page + 1 : null,
      previousPage: page > 1 ? page - 1 : null
    };
  }
}