/**
 * Suppliers service API implementation
 * Handles all supplier-related backend communications
 */

import { apiClient } from '../client/apiClient';
import type {
  SupplierCreate,
  SupplierUpdate,
  SupplierResponse,
  SupplierSummary,
  SupplierApproval,
  SupplierQueryParams,
  SupplierStatistics,
  TopSuppliersResponse,
  PurchaseOrderCreate,
  PurchaseOrderUpdate,
  PurchaseOrderResponse,
  PurchaseOrderApproval,
  PurchaseOrderQueryParams,
  DeliveryCreate,
  DeliveryUpdate,
  DeliveryResponse,
  DeliveryReceiptConfirmation,
  DeliveryQueryParams,
  PerformanceCalculationRequest,
  PerformanceMetrics,
  PerformanceAlert,
  PaginatedResponse,
  ApiResponse,
} from '../types/suppliers';

class SuppliersService {
  private readonly baseUrl = '/tenants';
  private readonly purchaseOrdersUrl = '/purchase-orders';
  private readonly deliveriesUrl = '/deliveries';
  private readonly performanceUrl = '/performance';

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

  async getSuppliers(
    tenantId: string,
    queryParams?: SupplierQueryParams
  ): Promise<PaginatedResponse<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());
    if (queryParams?.sort_by) params.append('sort_by', queryParams.sort_by);
    if (queryParams?.sort_order) params.append('sort_order', queryParams.sort_order);

    const queryString = params.toString() ? `?${params.toString()}` : '';
    return apiClient.get<PaginatedResponse<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}`
    );
  }

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

  async getActiveSuppliers(
    tenantId: string,
    queryParams?: Omit<SupplierQueryParams, 'status'>
  ): Promise<PaginatedResponse<SupplierSummary>> {
    return this.getSuppliers(tenantId, { ...queryParams, status: 'active' });
  }

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

  async getPendingApprovalSuppliers(
    tenantId: string
  ): Promise<PaginatedResponse<SupplierSummary>> {
    return this.getSuppliers(tenantId, { status: 'pending_approval' });
  }

  async getSuppliersByType(
    tenantId: string,
    supplierType: string,
    queryParams?: Omit<SupplierQueryParams, 'supplier_type'>
  ): Promise<PaginatedResponse<SupplierSummary>> {
    return apiClient.get<PaginatedResponse<SupplierSummary>>(
      `${this.baseUrl}/${tenantId}/suppliers/types/${supplierType}`
    );
  }

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

  // Purchase Orders
  async createPurchaseOrder(orderData: PurchaseOrderCreate): Promise<PurchaseOrderResponse> {
    return apiClient.post<PurchaseOrderResponse>(this.purchaseOrdersUrl, orderData);
  }

  async getPurchaseOrders(
    queryParams?: PurchaseOrderQueryParams
  ): Promise<PaginatedResponse<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());
    if (queryParams?.sort_by) params.append('sort_by', queryParams.sort_by);
    if (queryParams?.sort_order) params.append('sort_order', queryParams.sort_order);

    const queryString = params.toString() ? `?${params.toString()}` : '';
    return apiClient.get<PaginatedResponse<PurchaseOrderResponse>>(
      `${this.purchaseOrdersUrl}${queryString}`
    );
  }

  async getPurchaseOrder(orderId: string): Promise<PurchaseOrderResponse> {
    return apiClient.get<PurchaseOrderResponse>(`${this.purchaseOrdersUrl}/${orderId}`);
  }

  async updatePurchaseOrder(
    orderId: string,
    updateData: PurchaseOrderUpdate
  ): Promise<PurchaseOrderResponse> {
    return apiClient.put<PurchaseOrderResponse>(
      `${this.purchaseOrdersUrl}/${orderId}`,
      updateData
    );
  }

  async approvePurchaseOrder(
    orderId: string,
    approval: PurchaseOrderApproval
  ): Promise<PurchaseOrderResponse> {
    return apiClient.post<PurchaseOrderResponse>(
      `${this.purchaseOrdersUrl}/${orderId}/approve`,
      approval
    );
  }

  // Deliveries
  async createDelivery(deliveryData: DeliveryCreate): Promise<DeliveryResponse> {
    return apiClient.post<DeliveryResponse>(this.deliveriesUrl, deliveryData);
  }

  async getDeliveries(
    queryParams?: DeliveryQueryParams
  ): Promise<PaginatedResponse<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());
    if (queryParams?.sort_by) params.append('sort_by', queryParams.sort_by);
    if (queryParams?.sort_order) params.append('sort_order', queryParams.sort_order);

    const queryString = params.toString() ? `?${params.toString()}` : '';
    return apiClient.get<PaginatedResponse<DeliveryResponse>>(
      `${this.deliveriesUrl}${queryString}`
    );
  }

  async getDelivery(deliveryId: string): Promise<DeliveryResponse> {
    return apiClient.get<DeliveryResponse>(`${this.deliveriesUrl}/${deliveryId}`);
  }

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

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

  // Performance Tracking
  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.performanceUrl}/tenants/${tenantId}/suppliers/${supplierId}/calculate${queryString}`
    );
  }

  async getSupplierPerformanceMetrics(
    tenantId: string,
    supplierId: string
  ): Promise<PerformanceMetrics> {
    return apiClient.get<PerformanceMetrics>(
      `${this.performanceUrl}/tenants/${tenantId}/suppliers/${supplierId}/metrics`
    );
  }

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

  async getPerformanceAlerts(
    tenantId: string,
    supplierId?: string
  ): Promise<PerformanceAlert[]> {
    const url = supplierId 
      ? `${this.performanceUrl}/tenants/${tenantId}/suppliers/${supplierId}/alerts`
      : `${this.performanceUrl}/tenants/${tenantId}/alerts`;
    
    return apiClient.get<PerformanceAlert[]>(url);
  }

  // Utility methods
  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;