/**
 * Orders Service - API endpoints for Orders Service
 * 
 * This service mirrors the backend API endpoints defined in:
 * services/orders/app/api/orders.py
 */

import { apiClient } from '../client/apiClient';
import {
  OrderResponse,
  OrderCreate,
  OrderUpdate,
  CustomerResponse,
  CustomerCreate,
  CustomerUpdate,
  OrdersDashboardSummary,
  DemandRequirements,
  BusinessModelDetection,
  ServiceStatus,
  GetOrdersParams,
  GetCustomersParams,
  UpdateOrderStatusParams,
  GetDemandRequirementsParams,
  // Procurement types
  ProcurementPlanResponse,
  ProcurementPlanCreate,
  ProcurementPlanUpdate,
  ProcurementRequirementResponse,
  ProcurementRequirementUpdate,
  ProcurementDashboardData,
  GeneratePlanRequest,
  GeneratePlanResponse,
  PaginatedProcurementPlans,
  GetProcurementPlansParams,
  GetPlanRequirementsParams,
  UpdatePlanStatusParams,
} from '../types/orders';

export class OrdersService {
  // ===== Dashboard and Analytics Endpoints =====

  /**
   * Get comprehensive dashboard summary for orders
   * GET /tenants/{tenant_id}/orders/dashboard-summary
   */
  static async getDashboardSummary(tenantId: string): Promise<OrdersDashboardSummary> {
    return apiClient.get<OrdersDashboardSummary>(`/tenants/${tenantId}/orders/dashboard-summary`);
  }

  /**
   * Get demand requirements for production planning
   * GET /tenants/{tenant_id}/orders/demand-requirements
   */
  static async getDemandRequirements(params: GetDemandRequirementsParams): Promise<DemandRequirements> {
    const { tenant_id, target_date } = params;
    return apiClient.get<DemandRequirements>(
      `/tenants/${tenant_id}/orders/demand-requirements?target_date=${target_date}`
    );
  }

  // ===== Order Management Endpoints =====

  /**
   * Create a new customer order
   * POST /tenants/{tenant_id}/orders
   */
  static async createOrder(orderData: OrderCreate): Promise<OrderResponse> {
    const { tenant_id, ...data } = orderData;
    return apiClient.post<OrderResponse>(`/tenants/${tenant_id}/orders`, data);
  }

  /**
   * Get order details with items
   * GET /tenants/{tenant_id}/orders/{order_id}
   */
  static async getOrder(tenantId: string, orderId: string): Promise<OrderResponse> {
    return apiClient.get<OrderResponse>(`/tenants/${tenantId}/orders/${orderId}`);
  }

  /**
   * Get orders with filtering and pagination
   * GET /tenants/{tenant_id}/orders
   */
  static async getOrders(params: GetOrdersParams): Promise<OrderResponse[]> {
    const { tenant_id, status_filter, start_date, end_date, skip = 0, limit = 100 } = params;
    
    const queryParams = new URLSearchParams({
      skip: skip.toString(),
      limit: limit.toString(),
    });

    if (status_filter) {
      queryParams.append('status_filter', status_filter);
    }
    if (start_date) {
      queryParams.append('start_date', start_date);
    }
    if (end_date) {
      queryParams.append('end_date', end_date);
    }

    return apiClient.get<OrderResponse[]>(`/tenants/${tenant_id}/orders?${queryParams.toString()}`);
  }

  /**
   * Update order status
   * PUT /tenants/{tenant_id}/orders/{order_id}/status
   */
  static async updateOrderStatus(params: UpdateOrderStatusParams): Promise<OrderResponse> {
    const { tenant_id, order_id, new_status, reason } = params;
    
    const queryParams = new URLSearchParams();
    if (reason) {
      queryParams.append('reason', reason);
    }

    const url = `/tenants/${tenant_id}/orders/${order_id}/status${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
    
    return apiClient.put<OrderResponse>(url, { status: new_status });
  }

  // ===== Customer Management Endpoints =====

  /**
   * Create a new customer
   * POST /tenants/{tenant_id}/customers
   */
  static async createCustomer(customerData: CustomerCreate): Promise<CustomerResponse> {
    const { tenant_id, ...data } = customerData;
    return apiClient.post<CustomerResponse>(`/tenants/${tenant_id}/customers`, data);
  }

  /**
   * Get customers with filtering and pagination
   * GET /tenants/{tenant_id}/customers
   */
  static async getCustomers(params: GetCustomersParams): Promise<CustomerResponse[]> {
    const { tenant_id, active_only = true, skip = 0, limit = 100 } = params;
    
    const queryParams = new URLSearchParams({
      active_only: active_only.toString(),
      skip: skip.toString(),
      limit: limit.toString(),
    });

    return apiClient.get<CustomerResponse[]>(`/tenants/${tenant_id}/customers?${queryParams.toString()}`);
  }

  /**
   * Get customer details
   * GET /tenants/{tenant_id}/customers/{customer_id}
   */
  static async getCustomer(tenantId: string, customerId: string): Promise<CustomerResponse> {
    return apiClient.get<CustomerResponse>(`/tenants/${tenantId}/customers/${customerId}`);
  }

  /**
   * Update customer details
   * PUT /tenants/{tenant_id}/customers/{customer_id}
   */
  static async updateCustomer(tenantId: string, customerId: string, customerData: CustomerUpdate): Promise<CustomerResponse> {
    return apiClient.put<CustomerResponse>(`/tenants/${tenantId}/customers/${customerId}`, customerData);
  }

  // ===== Business Intelligence Endpoints =====

  /**
   * Detect business model based on order patterns
   * GET /tenants/{tenant_id}/orders/business-model
   */
  static async detectBusinessModel(tenantId: string): Promise<BusinessModelDetection> {
    return apiClient.get<BusinessModelDetection>(`/tenants/${tenantId}/orders/business-model`);
  }

  // ===== Health and Status Endpoints =====

  /**
   * Get orders service status
   * GET /tenants/{tenant_id}/orders/status
   */
  static async getServiceStatus(tenantId: string): Promise<ServiceStatus> {
    return apiClient.get<ServiceStatus>(`/tenants/${tenantId}/orders/status`);
  }

  // ===== Procurement Planning Endpoints =====

  /**
   * Get current procurement plan for today
   * GET /tenants/{tenant_id}/procurement/plans/current
   */
  static async getCurrentProcurementPlan(tenantId: string): Promise<ProcurementPlanResponse | null> {
    return apiClient.get<ProcurementPlanResponse | null>(`/tenants/${tenantId}/procurement/plans/current`);
  }

  /**
   * Get procurement plan by specific date
   * GET /tenants/{tenant_id}/procurement/plans/date/{plan_date}
   */
  static async getProcurementPlanByDate(tenantId: string, planDate: string): Promise<ProcurementPlanResponse | null> {
    return apiClient.get<ProcurementPlanResponse | null>(`/tenants/${tenantId}/procurement/plans/date/${planDate}`);
  }

  /**
   * Get procurement plan by ID
   * GET /tenants/{tenant_id}/procurement/plans/id/{plan_id}
   */
  static async getProcurementPlanById(tenantId: string, planId: string): Promise<ProcurementPlanResponse | null> {
    return apiClient.get<ProcurementPlanResponse | null>(`/tenants/${tenantId}/procurement/plans/id/${planId}`);
  }

  /**
   * List procurement plans with filtering
   * GET /tenants/{tenant_id}/procurement/plans/
   */
  static async getProcurementPlans(params: GetProcurementPlansParams): Promise<PaginatedProcurementPlans> {
    const { tenant_id, status, start_date, end_date, limit = 50, offset = 0 } = params;
    
    const queryParams = new URLSearchParams({
      limit: limit.toString(),
      offset: offset.toString(),
    });

    if (status) queryParams.append('status', status);
    if (start_date) queryParams.append('start_date', start_date);
    if (end_date) queryParams.append('end_date', end_date);

    return apiClient.get<PaginatedProcurementPlans>(
      `/tenants/${tenant_id}/procurement/plans?${queryParams.toString()}`
    );
  }

  /**
   * Generate a new procurement plan
   * POST /tenants/{tenant_id}/procurement/plans/generate
   */
  static async generateProcurementPlan(tenantId: string, request: GeneratePlanRequest): Promise<GeneratePlanResponse> {
    return apiClient.post<GeneratePlanResponse>(`/tenants/${tenantId}/procurement/plans/generate`, request);
  }

  /**
   * Update procurement plan status
   * PUT /tenants/{tenant_id}/procurement/plans/{plan_id}/status
   */
  static async updateProcurementPlanStatus(params: UpdatePlanStatusParams): Promise<ProcurementPlanResponse> {
    const { tenant_id, plan_id, status } = params;
    
    const queryParams = new URLSearchParams({ status });

    return apiClient.put<ProcurementPlanResponse>(
      `/tenants/${tenant_id}/procurement/plans/${plan_id}/status?${queryParams.toString()}`,
      {}
    );
  }

  /**
   * Get procurement dashboard data
   * GET /tenants/{tenant_id}/procurement/dashboard
   */
  static async getProcurementDashboard(tenantId: string): Promise<ProcurementDashboardData | null> {
    return apiClient.get<ProcurementDashboardData | null>(`/tenants/${tenantId}/procurement/dashboard`);
  }

  /**
   * Get requirements for a specific plan
   * GET /tenants/{tenant_id}/procurement/plans/{plan_id}/requirements
   */
  static async getPlanRequirements(params: GetPlanRequirementsParams): Promise<ProcurementRequirementResponse[]> {
    const { tenant_id, plan_id, status, priority } = params;
    
    const queryParams = new URLSearchParams();
    if (status) queryParams.append('status', status);
    if (priority) queryParams.append('priority', priority);

    const url = `/tenants/${tenant_id}/procurement/plans/${plan_id}/requirements${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;

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

  /**
   * Get critical requirements across all plans
   * GET /tenants/{tenant_id}/procurement/requirements/critical
   */
  static async getCriticalRequirements(tenantId: string): Promise<ProcurementRequirementResponse[]> {
    return apiClient.get<ProcurementRequirementResponse[]>(`/tenants/${tenantId}/procurement/requirements/critical`);
  }

  /**
   * Trigger daily scheduler manually
   * POST /tenants/{tenant_id}/procurement/scheduler/trigger
   */
  static async triggerDailyScheduler(tenantId: string): Promise<{ success: boolean; message: string; tenant_id: string }> {
    return apiClient.post<{ success: boolean; message: string; tenant_id: string }>(
      `/tenants/${tenantId}/procurement/scheduler/trigger`,
      {}
    );
  }

  /**
   * Get procurement service health
   * GET /tenants/{tenant_id}/procurement/health
   */
  static async getProcurementHealth(tenantId: string): Promise<{ status: string; service: string; procurement_enabled: boolean; timestamp: string }> {
    return apiClient.get<{ status: string; service: string; procurement_enabled: boolean; timestamp: string }>(`/tenants/${tenantId}/procurement/health`);
  }
}

export default OrdersService;