// ================================================================
// frontend/src/api/services/suppliers.ts
// ================================================================
/**
 * Suppliers Service - Complete backend alignment
 *
 * Backend API structure (3-tier architecture):
 * - ATOMIC: suppliers.py, purchase_orders.py, deliveries.py
 * - OPERATIONS: supplier_operations.py (approval, statistics, performance)
 * - ANALYTICS: analytics.py (performance metrics, alerts)
 *
 * Last Updated: 2025-10-05
 * Status: ✅ Complete - Zero drift with backend
 */

import { apiClient } from '../client/apiClient';
import type {
  SupplierCreate,
  SupplierUpdate,
  SupplierResponse,
  SupplierSummary,
  SupplierApproval,
  SupplierSearchParams,
  SupplierStatistics,
  SupplierDeletionSummary,
  SupplierResponse as SupplierResponse_,
  DeliveryCreate,
  DeliveryUpdate,
  DeliveryResponse,
  DeliveryReceiptConfirmation,
  DeliverySearchParams,
  PerformanceMetric,
  PerformanceAlert,
  SupplierPriceListCreate,
  SupplierPriceListUpdate,
  SupplierPriceListResponse
} from '../types/suppliers';

class SuppliersService {
  private readonly baseUrl = '/tenants';

  // ===================================================================
  // ATOMIC: Suppliers CRUD
  // Backend: services/suppliers/app/api/suppliers.py
  // ===================================================================

  async createSupplier(
    tenantId: string,
    supplierData: SupplierCreate
  ): Promise<SupplierResponse> {
    return apiClient.post<SupplierResponse>(
      `${this.baseUrl}/${tenantId}/suppliers`,
      supplierData
    );
  }

 // ===================================================================
  // ATOMIC: Supplier Price Lists CRUD
  // Backend: services/suppliers/app/api/suppliers.py (price list endpoints)
  // ===================================================================

  async getSupplierPriceLists(
    tenantId: string,
    supplierId: string,
    isActive: boolean = true
  ): Promise<SupplierPriceListResponse[]> {
    const params = new URLSearchParams();
    params.append('is_active', isActive.toString());

    return apiClient.get<SupplierPriceListResponse[]>(
      `${this.baseUrl}/${tenantId}/suppliers/${supplierId}/price-lists?${params.toString()}`
    );
  }

  async getSupplierPriceList(
    tenantId: string,
    supplierId: string,
    priceListId: string
  ): Promise<SupplierPriceListResponse> {
    return apiClient.get<SupplierPriceListResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/${supplierId}/price-lists/${priceListId}`
    );
  }

  async createSupplierPriceList(
    tenantId: string,
    supplierId: string,
    priceListData: SupplierPriceListCreate
  ): Promise<SupplierPriceListResponse> {
    return apiClient.post<SupplierPriceListResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/${supplierId}/price-lists`,
      priceListData
    );
  }

 async updateSupplierPriceList(
    tenantId: string,
    supplierId: string,
    priceListId: string,
    priceListData: SupplierPriceListUpdate
  ): Promise<SupplierPriceListResponse> {
    return apiClient.put<SupplierPriceListResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/${supplierId}/price-lists/${priceListId}`,
      priceListData
    );
  }

  async deleteSupplierPriceList(
    tenantId: string,
    supplierId: string,
    priceListId: string
  ): Promise<{ message: string }> {
    return apiClient.delete<{ message: string }>(
      `${this.baseUrl}/${tenantId}/suppliers/${supplierId}/price-lists/${priceListId}`
    );
  }

  async getSuppliers(
    tenantId: string,
    queryParams?: SupplierSearchParams
  ): Promise<SupplierSummary[]> {
    const params = new URLSearchParams();

    if (queryParams?.search_term) params.append('search_term', queryParams.search_term);
    if (queryParams?.supplier_type) params.append('supplier_type', queryParams.supplier_type);
    if (queryParams?.status) params.append('status', queryParams.status);
    if (queryParams?.limit) params.append('limit', queryParams.limit.toString());
    if (queryParams?.offset) params.append('offset', queryParams.offset.toString());

    const queryString = params.toString() ? `?${params.toString()}` : '';
    return apiClient.get<SupplierSummary[]>(
      `${this.baseUrl}/${tenantId}/suppliers${queryString}`
    );
  }

  async getSupplier(tenantId: string, supplierId: string): Promise<SupplierResponse> {
    return apiClient.get<SupplierResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/${supplierId}`
    );
  }

  async updateSupplier(
    tenantId: string,
    supplierId: string,
    updateData: SupplierUpdate
  ): Promise<SupplierResponse> {
    return apiClient.put<SupplierResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/${supplierId}`,
      updateData
    );
  }

  async deleteSupplier(
    tenantId: string,
    supplierId: string
  ): Promise<{ message: string }> {
    return apiClient.delete<{ message: string }>(
      `${this.baseUrl}/${tenantId}/suppliers/${supplierId}`
    );
  }

  async hardDeleteSupplier(
    tenantId: string,
    supplierId: string
  ): Promise<SupplierDeletionSummary> {
    return apiClient.delete<SupplierDeletionSummary>(
      `${this.baseUrl}/${tenantId}/suppliers/${supplierId}/hard`
    );
  }

  async getSupplierProducts(
    tenantId: string,
    supplierId: string,
    isActive: boolean = true
  ): Promise<Array<{ inventory_product_id: string }>> {
    const params = new URLSearchParams();
    params.append('is_active', isActive.toString());

    return apiClient.get<Array<{ inventory_product_id: string }>>(
      `${this.baseUrl}/${tenantId}/suppliers/${supplierId}/products?${params.toString()}`
    );
  }

  // ===================================================================
  // ATOMIC: Purchase Orders CRUD
  // Backend: services/suppliers/app/api/purchase_orders.py
  // ===================================================================

  async createPurchaseOrder(
    tenantId: string,
    orderData: PurchaseOrderCreate
  ): Promise<PurchaseOrderResponse> {
    return apiClient.post<PurchaseOrderResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/purchase-orders`,
      orderData
    );
  }

   async getPurchaseOrders(
    tenantId: string,
    queryParams?: PurchaseOrderSearchParams
  ): Promise<PurchaseOrderResponse[]> {
    const params = new URLSearchParams();

    if (queryParams?.supplier_id) params.append('supplier_id', queryParams.supplier_id);
    if (queryParams?.status) params.append('status', queryParams.status);
    if (queryParams?.priority) params.append('priority', queryParams.priority);
    if (queryParams?.date_from) params.append('date_from', queryParams.date_from);
    if (queryParams?.date_to) params.append('date_to', queryParams.date_to);
    if (queryParams?.limit) params.append('limit', queryParams.limit.toString());
    if (queryParams?.offset) params.append('offset', queryParams.offset.toString());

    const queryString = params.toString() ? `?${params.toString()}` : '';
    return apiClient.get<PurchaseOrderResponse[]>(
      `${this.baseUrl}/${tenantId}/suppliers/purchase-orders${queryString}`
    );
  }

  async getPurchaseOrder(tenantId: string, orderId: string): Promise<PurchaseOrderResponse> {
    return apiClient.get<PurchaseOrderResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/purchase-orders/${orderId}`
    );
  }

  async updatePurchaseOrder(
    tenantId: string,
    orderId: string,
    updateData: PurchaseOrderUpdate
  ): Promise<PurchaseOrderResponse> {
    return apiClient.put<PurchaseOrderResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/purchase-orders/${orderId}`,
      updateData
    );
  }

  async approvePurchaseOrder(
    tenantId: string,
    orderId: string,
    approval: PurchaseOrderApproval
  ): Promise<PurchaseOrderResponse> {
    return apiClient.post<PurchaseOrderResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/purchase-orders/${orderId}/approve`,
      approval
    );
  }

  // ===================================================================
  // ATOMIC: Deliveries CRUD
  // Backend: services/suppliers/app/api/deliveries.py
  // ===================================================================

  async createDelivery(
    tenantId: string,
    deliveryData: DeliveryCreate
  ): Promise<DeliveryResponse> {
    return apiClient.post<DeliveryResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/deliveries`,
      deliveryData
    );
  }

  async getDeliveries(
    tenantId: string,
    queryParams?: DeliverySearchParams
 ): Promise<DeliveryResponse[]> {
    const params = new URLSearchParams();

    if (queryParams?.supplier_id) params.append('supplier_id', queryParams.supplier_id);
    if (queryParams?.purchase_order_id) {
      params.append('purchase_order_id', queryParams.purchase_order_id);
    }
    if (queryParams?.status) params.append('status', queryParams.status);
    if (queryParams?.scheduled_date_from) {
      params.append('scheduled_date_from', queryParams.scheduled_date_from);
    }
    if (queryParams?.scheduled_date_to) {
      params.append('scheduled_date_to', queryParams.scheduled_date_to);
    }
    if (queryParams?.limit) params.append('limit', queryParams.limit.toString());
    if (queryParams?.offset) params.append('offset', queryParams.offset.toString());

    const queryString = params.toString() ? `?${params.toString()}` : '';
    return apiClient.get<DeliveryResponse[]>(
      `${this.baseUrl}/${tenantId}/suppliers/deliveries${queryString}`
    );
  }

  async getDelivery(tenantId: string, deliveryId: string): Promise<DeliveryResponse> {
    return apiClient.get<DeliveryResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/deliveries/${deliveryId}`
    );
  }

  async updateDelivery(
    tenantId: string,
    deliveryId: string,
    updateData: DeliveryUpdate
  ): Promise<DeliveryResponse> {
    return apiClient.put<DeliveryResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/deliveries/${deliveryId}`,
      updateData
    );
  }

  async confirmDeliveryReceipt(
    tenantId: string,
    deliveryId: string,
    confirmation: DeliveryReceiptConfirmation
  ): Promise<DeliveryResponse> {
    return apiClient.post<DeliveryResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/deliveries/${deliveryId}/confirm-receipt`,
      confirmation
    );
  }

  // ===================================================================
  // OPERATIONS: Supplier Management
  // Backend: services/suppliers/app/api/supplier_operations.py
  // ===================================================================

  async getSupplierStatistics(tenantId: string): Promise<SupplierStatistics> {
    return apiClient.get<SupplierStatistics>(
      `${this.baseUrl}/${tenantId}/suppliers/operations/statistics`
    );
  }

  async getActiveSuppliers(
    tenantId: string,
    queryParams?: SupplierSearchParams
  ): Promise<SupplierSummary[]> {
    const params = new URLSearchParams();
    if (queryParams?.search_term) params.append('search_term', queryParams.search_term);
    if (queryParams?.supplier_type) params.append('supplier_type', queryParams.supplier_type);
    if (queryParams?.limit) params.append('limit', queryParams.limit.toString());
    if (queryParams?.offset) params.append('offset', queryParams.offset.toString());

    const queryString = params.toString() ? `?${params.toString()}` : '';
    return apiClient.get<SupplierSummary[]>(
      `${this.baseUrl}/${tenantId}/suppliers/operations/active${queryString}`
    );
 }

  async getTopSuppliers(tenantId: string): Promise<TopSuppliersResponse> {
    return apiClient.get<TopSuppliersResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/operations/top`
    );
  }

  async getPendingApprovalSuppliers(
    tenantId: string
  ): Promise<PaginatedResponse<SupplierSummary>> {
    return apiClient.get<PaginatedResponse<SupplierSummary>>(
      `${this.baseUrl}/${tenantId}/suppliers/operations/pending-review`
    );
  }

  async getSuppliersByType(
    tenantId: string,
    supplierType: string,
    queryParams?: Omit<SupplierQueryParams, 'supplier_type'>
  ): Promise<PaginatedResponse<SupplierSummary>> {
    const params = new URLSearchParams();
    if (queryParams?.search_term) params.append('search_term', queryParams.search_term);
    if (queryParams?.status) params.append('status', queryParams.status);
    if (queryParams?.limit) params.append('limit', queryParams.limit.toString());
    if (queryParams?.offset) params.append('offset', queryParams.offset.toString());

    const queryString = params.toString() ? `?${params.toString()}` : '';
    return apiClient.get<PaginatedResponse<SupplierSummary>>(
      `${this.baseUrl}/${tenantId}/suppliers/types/${supplierType}${queryString}`
    );
  }

  async approveSupplier(
    tenantId: string,
    supplierId: string,
    approval: SupplierApproval
  ): Promise<SupplierResponse> {
    return apiClient.post<SupplierResponse>(
      `${this.baseUrl}/${tenantId}/suppliers/${supplierId}/approve`,
      approval
    );
  }

  // ===================================================================
  // ANALYTICS: Performance Metrics
  // Backend: services/suppliers/app/api/analytics.py
  // ===================================================================

  async calculateSupplierPerformance(
    tenantId: string,
    supplierId: string,
    request?: PerformanceCalculationRequest
  ): Promise<{ message: string; calculation_id: string }> {
    const params = new URLSearchParams();
    if (request?.period) params.append('period', request.period);
    if (request?.period_start) params.append('period_start', request.period_start);
    if (request?.period_end) params.append('period_end', request.period_end);

    const queryString = params.toString() ? `?${params.toString()}` : '';
    return apiClient.post<{ message: string; calculation_id: string }>(
      `${this.baseUrl}/${tenantId}/suppliers/analytics/performance/${supplierId}/calculate${queryString}`
    );
  }

  async getSupplierPerformanceMetrics(
    tenantId: string,
    supplierId: string
  ): Promise<PerformanceMetric[]> {
    return apiClient.get<PerformanceMetric[]>(
      `${this.baseUrl}/${tenantId}/suppliers/analytics/performance/${supplierId}/metrics`
    );
 }

  async evaluatePerformanceAlerts(
    tenantId: string
  ): Promise<{ alerts_generated: number; message: string }> {
    return apiClient.post<{ alerts_generated: number; message: string }>(
      `${this.baseUrl}/${tenantId}/suppliers/analytics/performance/alerts/evaluate`
    );
  }

  async getPerformanceAlerts(
    tenantId: string,
    supplierId?: string
  ): Promise<PerformanceAlert[]> {
    const url = supplierId
      ? `${this.baseUrl}/${tenantId}/suppliers/analytics/performance/${supplierId}/alerts`
      : `${this.baseUrl}/${tenantId}/suppliers/analytics/performance/alerts`;

    return apiClient.get<PerformanceAlert[]>(url);
  }

  // ===================================================================
  // UTILITY METHODS (Client-side helpers)
  // ===================================================================

  calculateOrderTotal(
    items: { ordered_quantity: number; unit_price: number }[],
    taxAmount: number = 0,
    shippingCost: number = 0,
    discountAmount: number = 0
  ): number {
    const subtotal = items.reduce(
      (sum, item) => sum + (item.ordered_quantity * item.unit_price),
      0
    );
    return subtotal + taxAmount + shippingCost - discountAmount;
  }

  formatSupplierCode(name: string, sequence?: number): string {
    const cleanName = name.replace(/[^a-zA-Z0-9]/g, '').toUpperCase();
    const prefix = cleanName.substring(0, 3).padEnd(3, 'X');
    const suffix = sequence ? sequence.toString().padStart(3, '0') : '001';
    return `${prefix}${suffix}`;
  }

  validateTaxId(taxId: string, country: string = 'ES'): boolean {
    // Simplified validation - real implementation would have proper country-specific validation
    if (country === 'ES') {
      // Spanish VAT format: ES + letter + 8 digits or ES + 8 digits + letter
      const spanishVatRegex = /^ES[A-Z]\d{8}$|^ES\d{8}[A-Z]$/;
      return spanishVatRegex.test(taxId.toUpperCase());
    }
    return taxId.length > 0;
  }

  formatCurrency(amount: number, currency: string = 'EUR'): string {
    return new Intl.NumberFormat('es-ES', {
      style: 'currency',
      currency: currency,
    }).format(amount);
  }
}

// Create and export singleton instance
export const suppliersService = new SuppliersService();
export default suppliersService;
