import apiService from './apiService';

// Item Interfaces
export interface Item {
  name: string;
  item_code: string;
  item_name: string;
  item_group?: string;
  custom_part_description?: string;
  stock_uom?: string;
  custom_item_cost_per_unit?: number;
  disabled?: number;
  is_stock_item?: number;
  opening_stock?: number;
  valuation_rate?: number;
  standard_rate?: number;
  custom_last_calibration_date?: string;
  custom_next_due_calibration_date?: string;
  description?: string;
  brand?: string;
  custom_warranty_in_months?: string;
  valuation_method?: string;
  has_batch_no?: number;
  has_serial_no?: number;
  is_purchase_item?: number;
  is_sales_item?: number;
  country_of_origin?: string;
  creation?: string;
  modified?: string;
  owner?: string;
  modified_by?: string;
  docstatus?: number;
  uoms?: Array<{
    uom?: string;
    conversion_factor?: number;
  }>;
  item_defaults?: Array<{
    company?: string;
    default_warehouse?: string;
  }>;
  [key: string]: any;
}

export interface CreateItemData {
  item_code: string;
  item_name: string;
  item_group?: string;
  custom_part_description?: string;
  stock_uom?: string;
  custom_item_cost_per_unit?: number;
  disabled?: number;
  is_stock_item?: number;
  opening_stock?: number;
  valuation_rate?: number;
  standard_rate?: number;
  custom_last_calibration_date?: string;
  custom_next_due_calibration_date?: string;
  description?: string;
  brand?: string;
  custom_warranty_in_months?: string;
  valuation_method?: string;
  has_batch_no?: number;
  has_serial_no?: number;
  is_purchase_item?: number;
  is_sales_item?: number;
  country_of_origin?: string;
  uoms?: Array<{
    uom?: string;
    conversion_factor?: number;
  }>;
  item_defaults?: Array<{
    company?: string;
    default_warehouse?: string;
  }>;
  [key: string]: any;
}

class ItemService {
  private buildListParams(
    filters?: Record<string, any>,
    fields?: string[],
    limit: number = 20,
    offset: number = 0,
    orderBy?: string
  ): URLSearchParams {
    const params = new URLSearchParams();

    if (filters) {
      params.append('filters', JSON.stringify(filters));
    }

    if (fields) {
      params.append('fields', JSON.stringify(fields));
    }

    params.append('limit_page_length', limit.toString());
    params.append('limit_start', offset.toString());

    if (orderBy) {
      params.append('order_by', orderBy);
    }

    return params;
  }

  private async getItemCount(filters?: Record<string, any>): Promise<number> {
    const total = await apiService.apiCall<number>(
      '/api/method/frappe.client.get_count',
      {
        method: 'POST',
        body: JSON.stringify({
          doctype: 'Item',
          filters: filters || {},
        }),
      }
    );

    return typeof total === 'number' ? total : 0;
  }

  // Get list of items
  async getItems(
    filters?: Record<string, any>,
    fields?: string[],
    limit: number = 20,
    offset: number = 0,
    orderBy?: string
  ): Promise<{ data: Item[]; total: number }> {
    try {
      const params = this.buildListParams(filters, fields, limit, offset, orderBy);

      const [listResponse, total] = await Promise.all([
        apiService.apiCall<{ data: Item[] }>(`/api/resource/Item?${params.toString()}`),
        this.getItemCount(filters),
      ]);

      const data = listResponse.data || [];

      return {
        data,
        total,
      };
    } catch (error) {
      console.error('Error fetching items:', error);
      throw error;
    }
  }

  // Get single item by name
  async getItem(itemName: string): Promise<Item> {
    try {
      const response = await apiService.apiCall<{ data: Item }>(
        `/api/resource/Item/${itemName}`
      );
      return response.data;
    } catch (error) {
      console.error('Error fetching item:', error);
      throw error;
    }
  }

  // Create new item
  async createItem(itemData: CreateItemData): Promise<Item> {
    try {
      const response = await apiService.apiCall<{ data: Item }>(
        '/api/resource/Item',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(itemData),
        }
      );
      return response.data;
    } catch (error) {
      console.error('Error creating item:', error);
      throw error;
    }
  }

  // Update item
  async updateItem(itemName: string, itemData: Partial<CreateItemData>): Promise<Item> {
    try {
      const response = await apiService.apiCall<{ data: Item }>(
        `/api/resource/Item/${itemName}`,
        {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(itemData),
        }
      );
      return response.data;
    } catch (error) {
      console.error('Error updating item:', error);
      throw error;
    }
  }

  // Delete item
  async deleteItem(itemName: string): Promise<void> {
    try {
      await apiService.apiCall(
        `/api/resource/Item/${itemName}`,
        {
          method: 'DELETE',
        }
      );
    } catch (error) {
      console.error('Error deleting item:', error);
      throw error;
    }
  }

  // Submit item
  async submitItem(itemName: string): Promise<Item> {
    try {
      const response = await apiService.apiCall<{ data: Item }>(
        `/api/resource/Item/${itemName}/submit`,
        {
          method: 'POST',
        }
      );
      return response.data;
    } catch (error) {
      console.error('Error submitting item:', error);
      throw error;
    }
  }

  // Cancel item
  async cancelItem(itemName: string): Promise<Item> {
    try {
      const response = await apiService.apiCall<{ data: Item }>(
        `/api/resource/Item/${itemName}/cancel`,
        {
          method: 'POST',
        }
      );
      return response.data;
    } catch (error) {
      console.error('Error cancelling item:', error);
      throw error;
    }
  }
}

export default new ItemService();

