/**
 * Inventory Service - Mirror backend inventory endpoints
 */
import { apiClient } from '../client';
import {
  IngredientCreate,
  IngredientUpdate,
  IngredientResponse,
  StockCreate,
  StockUpdate,
  StockResponse,
  StockMovementCreate,
  StockMovementResponse,
  InventoryFilter,
  StockFilter,
  StockConsumptionRequest,
  StockConsumptionResponse,
  PaginatedResponse,
  DeletionSummary,
} from '../types/inventory';

export class InventoryService {
  private readonly baseUrl = '/tenants';

  // Ingredient Management
  async createIngredient(
    tenantId: string,
    ingredientData: IngredientCreate
  ): Promise<IngredientResponse> {
    return apiClient.post<IngredientResponse>(`${this.baseUrl}/${tenantId}/ingredients`, ingredientData);
  }

  async getIngredient(tenantId: string, ingredientId: string): Promise<IngredientResponse> {
    return apiClient.get<IngredientResponse>(`${this.baseUrl}/${tenantId}/ingredients/${ingredientId}`);
  }

  async getIngredients(
    tenantId: string,
    filter?: InventoryFilter
  ): Promise<IngredientResponse[]> {
    const queryParams = new URLSearchParams();
    
    if (filter?.category) queryParams.append('category', filter.category);
    if (filter?.stock_status) queryParams.append('stock_status', filter.stock_status);
    if (filter?.requires_refrigeration !== undefined) 
      queryParams.append('requires_refrigeration', filter.requires_refrigeration.toString());
    if (filter?.requires_freezing !== undefined) 
      queryParams.append('requires_freezing', filter.requires_freezing.toString());
    if (filter?.is_seasonal !== undefined) 
      queryParams.append('is_seasonal', filter.is_seasonal.toString());
    if (filter?.supplier_id) queryParams.append('supplier_id', filter.supplier_id);
    if (filter?.expiring_within_days !== undefined) 
      queryParams.append('expiring_within_days', filter.expiring_within_days.toString());
    if (filter?.search) queryParams.append('search', filter.search);
    if (filter?.limit !== undefined) queryParams.append('limit', filter.limit.toString());
    if (filter?.offset !== undefined) queryParams.append('offset', filter.offset.toString());
    if (filter?.order_by) queryParams.append('order_by', filter.order_by);
    if (filter?.order_direction) queryParams.append('order_direction', filter.order_direction);

    const url = queryParams.toString() 
      ? `${this.baseUrl}/${tenantId}/ingredients?${queryParams.toString()}`
      : `${this.baseUrl}/${tenantId}/ingredients`;

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

  async updateIngredient(
    tenantId: string,
    ingredientId: string,
    updateData: IngredientUpdate
  ): Promise<IngredientResponse> {
    return apiClient.put<IngredientResponse>(
      `${this.baseUrl}/${tenantId}/ingredients/${ingredientId}`,
      updateData
    );
  }

  async softDeleteIngredient(tenantId: string, ingredientId: string): Promise<void> {
    return apiClient.delete<void>(`${this.baseUrl}/${tenantId}/ingredients/${ingredientId}`);
  }

  async hardDeleteIngredient(tenantId: string, ingredientId: string): Promise<DeletionSummary> {
    return apiClient.delete<DeletionSummary>(`${this.baseUrl}/${tenantId}/ingredients/${ingredientId}/hard`);
  }

  async getIngredientsByCategory(tenantId: string): Promise<Record<string, IngredientResponse[]>> {
    return apiClient.get<Record<string, IngredientResponse[]>>(`${this.baseUrl}/${tenantId}/ingredients/by-category`);
  }

  async getLowStockIngredients(tenantId: string): Promise<IngredientResponse[]> {
    return apiClient.get<IngredientResponse[]>(`${this.baseUrl}/${tenantId}/stock/low-stock`);
  }

  // Stock Management
  async addStock(tenantId: string, stockData: StockCreate): Promise<StockResponse> {
    return apiClient.post<StockResponse>(`${this.baseUrl}/${tenantId}/stock`, stockData);
  }

  async getStock(tenantId: string, stockId: string): Promise<StockResponse> {
    return apiClient.get<StockResponse>(`${this.baseUrl}/${tenantId}/stock/${stockId}`);
  }

  async getStockByIngredient(
    tenantId: string,
    ingredientId: string,
    includeUnavailable: boolean = false
  ): Promise<StockResponse[]> {
    const queryParams = new URLSearchParams();
    queryParams.append('include_unavailable', includeUnavailable.toString());

    const url = `${this.baseUrl}/${tenantId}/ingredients/${ingredientId}/stock?${queryParams.toString()}`;
    return apiClient.get<StockResponse[]>(url);
  }

  async getAllStock(tenantId: string, filter?: StockFilter): Promise<PaginatedResponse<StockResponse>> {
    const queryParams = new URLSearchParams();
    
    if (filter?.ingredient_id) queryParams.append('ingredient_id', filter.ingredient_id);
    if (filter?.is_available !== undefined) queryParams.append('is_available', filter.is_available.toString());
    if (filter?.is_expired !== undefined) queryParams.append('is_expired', filter.is_expired.toString());
    if (filter?.expiring_within_days !== undefined) 
      queryParams.append('expiring_within_days', filter.expiring_within_days.toString());
    if (filter?.batch_number) queryParams.append('batch_number', filter.batch_number);
    if (filter?.supplier_id) queryParams.append('supplier_id', filter.supplier_id);
    if (filter?.limit !== undefined) queryParams.append('limit', filter.limit.toString());
    if (filter?.offset !== undefined) queryParams.append('offset', filter.offset.toString());
    if (filter?.order_by) queryParams.append('order_by', filter.order_by);
    if (filter?.order_direction) queryParams.append('order_direction', filter.order_direction);

    const url = queryParams.toString() 
      ? `${this.baseUrl}/${tenantId}/stock?${queryParams.toString()}`
      : `${this.baseUrl}/${tenantId}/stock`;

    return apiClient.get<PaginatedResponse<StockResponse>>(url);
  }

  async updateStock(
    tenantId: string,
    stockId: string,
    updateData: StockUpdate
  ): Promise<StockResponse> {
    return apiClient.put<StockResponse>(`${this.baseUrl}/${tenantId}/stock/${stockId}`, updateData);
  }

  async deleteStock(tenantId: string, stockId: string): Promise<{ message: string }> {
    return apiClient.delete<{ message: string }>(`${this.baseUrl}/${tenantId}/stock/${stockId}`);
  }

  async consumeStock(
    tenantId: string,
    consumptionData: StockConsumptionRequest
  ): Promise<StockConsumptionResponse> {
    const queryParams = new URLSearchParams();
    queryParams.append('ingredient_id', consumptionData.ingredient_id);
    queryParams.append('quantity', consumptionData.quantity.toString());
    if (consumptionData.reference_number) 
      queryParams.append('reference_number', consumptionData.reference_number);
    if (consumptionData.notes) queryParams.append('notes', consumptionData.notes);
    if (consumptionData.fifo !== undefined) queryParams.append('fifo', consumptionData.fifo.toString());

    return apiClient.post<StockConsumptionResponse>(
      `${this.baseUrl}/${tenantId}/stock/consume?${queryParams.toString()}`
    );
  }

  // Stock Movements
  async createStockMovement(
    tenantId: string,
    movementData: StockMovementCreate
  ): Promise<StockMovementResponse> {
    return apiClient.post<StockMovementResponse>(`${this.baseUrl}/${tenantId}/stock/movements`, movementData);
  }

  async getStockMovements(
    tenantId: string,
    ingredientId?: string,
    limit: number = 50,
    offset: number = 0
  ): Promise<StockMovementResponse[]> {
    const queryParams = new URLSearchParams();
    if (ingredientId) queryParams.append('ingredient_id', ingredientId);
    queryParams.append('limit', limit.toString());
    queryParams.append('skip', offset.toString()); // Backend expects 'skip' not 'offset'

    const url = `${this.baseUrl}/${tenantId}/stock/movements?${queryParams.toString()}`;
    console.log('🔍 Frontend calling API:', url);

    try {
      const result = await apiClient.get<StockMovementResponse[]>(url);
      console.log('✅ Frontend API response:', result);
      return result;
    } catch (error) {
      console.error('❌ Frontend API error:', error);
      throw error;
    }
  }

  // Expiry Management
  async getExpiringStock(
    tenantId: string,
    withinDays: number = 7
  ): Promise<StockResponse[]> {
    const queryParams = new URLSearchParams();
    queryParams.append('within_days', withinDays.toString());

    return apiClient.get<StockResponse[]>(
      `${this.baseUrl}/${tenantId}/stock/expiring?${queryParams.toString()}`
    );
  }

  async getExpiredStock(tenantId: string): Promise<StockResponse[]> {
    return apiClient.get<StockResponse[]>(`${this.baseUrl}/${tenantId}/stock/expired`);
  }

  // Analytics
  async getStockAnalytics(
    tenantId: string,
    startDate?: string,
    endDate?: string
  ): Promise<{
    total_ingredients: number;
    total_stock_value: number;
    low_stock_count: number;
    out_of_stock_count: number;
    expiring_soon_count: number;
    stock_turnover_rate: number;
  }> {
    const queryParams = new URLSearchParams();
    if (startDate) queryParams.append('start_date', startDate);
    if (endDate) queryParams.append('end_date', endDate);

    const url = queryParams.toString() 
      ? `/tenants/${tenantId}/dashboard/analytics?${queryParams.toString()}`
      : `/tenants/${tenantId}/dashboard/analytics`;

    return apiClient.get(url);
  }
}

export const inventoryService = new InventoryService();