import { Inventory, InventoryFilterParams, InventoryStatistics, InventoryStatus } from '../types/inventory';

const useMock = process.env.REACT_APP_USE_MOCK === 'true';

interface InventoryListResult {
  data: Inventory[];
  total: number;
}

interface IInventoryDataSource {
  list(params?: InventoryFilterParams): Promise<InventoryListResult>;
  getById(id: string): Promise<Inventory | null>;
  getStatistics(): Promise<InventoryStatistics>;
  updateQuantity(id: string, quantity: number): Promise<Inventory | null>;
}

class MockInventoryDataSource implements IInventoryDataSource {
  readonly __MOCK_NAME__ = 'MockInventoryDataSource';

  private mockInventory: Inventory[] = [
    {
      id: 'inv-1',
      skuId: 'sku-1',
      productId: 'prod-1',
      productName: 'Wireless Bluetooth Headphones',
      sku: 'WBH-001',
      quantity: 150,
      availableQuantity: 120,
      reservedQuantity: 30,
      warehouseId: 'wh-1',
      warehouseName: 'Main Warehouse',
      status: InventoryStatus.IN_STOCK,
      costPrice: 25.00,
      sellingPrice: 49.99,
      reorderPoint: 50,
      maxStock: 500,
      lastRestockDate: '2026-03-20',
      createdAt: '2026-01-15',
      updatedAt: '2026-03-20',
    },
    {
      id: 'inv-2',
      skuId: 'sku-2',
      productId: 'prod-2',
      productName: 'Smart Watch Pro',
      sku: 'SWP-002',
      quantity: 45,
      availableQuantity: 40,
      reservedQuantity: 5,
      warehouseId: 'wh-1',
      warehouseName: 'Main Warehouse',
      status: InventoryStatus.LOW_STOCK,
      costPrice: 45.00,
      sellingPrice: 89.99,
      reorderPoint: 50,
      maxStock: 300,
      lastRestockDate: '2026-03-15',
      createdAt: '2026-01-20',
      updatedAt: '2026-03-15',
    },
    {
      id: 'inv-3',
      skuId: 'sku-3',
      productId: 'prod-3',
      productName: 'USB-C Charging Cable',
      sku: 'UCC-003',
      quantity: 0,
      availableQuantity: 0,
      reservedQuantity: 0,
      warehouseId: 'wh-2',
      warehouseName: 'Secondary Warehouse',
      status: InventoryStatus.OUT_OF_STOCK,
      costPrice: 2.50,
      sellingPrice: 9.99,
      reorderPoint: 100,
      maxStock: 1000,
      lastRestockDate: '2026-02-28',
      createdAt: '2026-01-10',
      updatedAt: '2026-03-01',
    },
    {
      id: 'inv-4',
      skuId: 'sku-4',
      productId: 'prod-4',
      productName: 'Laptop Stand Aluminum',
      sku: 'LSA-004',
      quantity: 800,
      availableQuantity: 750,
      reservedQuantity: 50,
      warehouseId: 'wh-1',
      warehouseName: 'Main Warehouse',
      status: InventoryStatus.OVERSTOCKED,
      costPrice: 15.00,
      sellingPrice: 34.99,
      reorderPoint: 100,
      maxStock: 500,
      lastRestockDate: '2026-03-10',
      createdAt: '2026-01-05',
      updatedAt: '2026-03-10',
    },
  ];

  async list(params?: InventoryFilterParams): Promise<InventoryListResult> {
    await new Promise(resolve => setTimeout(resolve, 300));
    let data = [...this.mockInventory];
    
    if (params?.keyword) {
      const keyword = params.keyword.toLowerCase();
      data = data.filter(item => 
        item.productName.toLowerCase().includes(keyword) ||
        item.sku.toLowerCase().includes(keyword)
      );
    }
    
    if (params?.status) {
      data = data.filter(item => item.status === params.status);
    }
    
    if (params?.warehouseId) {
      data = data.filter(item => item.warehouseId === params.warehouseId);
    }
    
    return { data, total: data.length };
  }

  async getById(id: string): Promise<Inventory | null> {
    await new Promise(resolve => setTimeout(resolve, 200));
    return this.mockInventory.find(item => item.id === id) || null;
  }

  async getStatistics(): Promise<InventoryStatistics> {
    await new Promise(resolve => setTimeout(resolve, 200));
    return {
      totalProducts: this.mockInventory.length,
      totalQuantity: this.mockInventory.reduce((sum, item) => sum + item.quantity, 0),
      totalValue: this.mockInventory.reduce((sum, item) => sum + (item.quantity * item.costPrice), 0),
      lowStockCount: this.mockInventory.filter(item => item.status === InventoryStatus.LOW_STOCK).length,
      outOfStockCount: this.mockInventory.filter(item => item.status === InventoryStatus.OUT_OF_STOCK).length,
      overstockedCount: this.mockInventory.filter(item => item.status === InventoryStatus.OVERSTOCKED).length,
    };
  }

  async updateQuantity(id: string, quantity: number): Promise<Inventory | null> {
    await new Promise(resolve => setTimeout(resolve, 300));
    const item = this.mockInventory.find(i => i.id === id);
    if (item) {
      item.quantity = quantity;
      item.availableQuantity = quantity - item.reservedQuantity;
      item.updatedAt = new Date().toISOString();
      return item;
    }
    return null;
  }
}

class ApiInventoryDataSource implements IInventoryDataSource {
  async list(params?: InventoryFilterParams): Promise<InventoryListResult> {
    const query = new URLSearchParams(params as Record<string, string>).toString();
    const response = await fetch(`/api/inventory?${query}`);
    return response.json();
  }

  async getById(id: string): Promise<Inventory | null> {
    const response = await fetch(`/api/inventory/${id}`);
    return response.json();
  }

  async getStatistics(): Promise<InventoryStatistics> {
    const response = await fetch('/api/inventory/statistics');
    return response.json();
  }

  async updateQuantity(id: string, quantity: number): Promise<Inventory | null> {
    const response = await fetch(`/api/inventory/${id}`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ quantity }),
    });
    return response.json();
  }
}

export const inventoryDataSource: IInventoryDataSource = useMock
  ? new MockInventoryDataSource()
  : new ApiInventoryDataSource();
