import { http } from './http';
import {
  Supplier,
  ProcurementRecord,
  ProcurementStats,
  SupplierPerformance,
  ProcurementStatus,
  SupplierStatus,
  PaymentStatus,
  QualityStatus,
} from '@/types/procurement';

export interface CreateProcurementParams {
  supplier_id: string;
  items: {
    product_id: string;
    product_name: string;
    sku: string;
    quantity: number;
    unit: string;
    unit_price: number;
  }[];
  expected_date?: string;
  warehouse_id?: string;
  remarks?: string;
}

export interface CreateSupplierParams {
  name: string;
  code: string;
  contact_person: string;
  phone: string;
  email?: string;
  address: string;
  category: string[];
  payment_terms?: string;
  credit_limit?: number;
  lead_time_days?: number;
  min_order_amount?: number;
  remarks?: string;
}

export interface IProcurementDataSource {
  fetchSuppliers(tenantId: string): Promise<Supplier[]>;
  fetchSupplier(supplierId: string): Promise<Supplier>;
  createSupplier(params: CreateSupplierParams): Promise<Supplier>;
  updateSupplier(supplierId: string, params: Partial<CreateSupplierParams>): Promise<Supplier>;
  deleteSupplier(supplierId: string): Promise<void>;
  
  fetchProcurementRecords(tenantId: string, filters?: {
    status?: ProcurementStatus;
    supplier_id?: string;
    date_from?: string;
    date_to?: string;
  }): Promise<ProcurementRecord[]>;
  fetchProcurementRecord(recordId: string): Promise<ProcurementRecord>;
  createProcurement(params: CreateProcurementParams): Promise<ProcurementRecord>;
  updateProcurementStatus(recordId: string, status: ProcurementStatus): Promise<ProcurementRecord>;
  receiveProcurement(recordId: string, items: {
    item_id: string;
    received_quantity: number;
    quality_status: QualityStatus;
  }[]): Promise<ProcurementRecord>;
  
  fetchProcurementStats(tenantId: string): Promise<ProcurementStats>;
  fetchSupplierPerformance(supplierId: string): Promise<SupplierPerformance>;
  
  approveProcurement(recordId: string): Promise<ProcurementRecord>;
  cancelProcurement(recordId: string, reason: string): Promise<ProcurementRecord>;
}

class ProcurementApiDataSource implements IProcurementDataSource {
  private baseUrl = '/api/procurement';

  async fetchSuppliers(tenantId: string): Promise<Supplier[]> {
    const response = await http.get(`${this.baseUrl}/suppliers?tenant_id=${tenantId}`);
    return response.data.data;
  }

  async fetchSupplier(supplierId: string): Promise<Supplier> {
    const response = await http.get(`${this.baseUrl}/suppliers/${supplierId}`);
    return response.data.data;
  }

  async createSupplier(params: CreateSupplierParams): Promise<Supplier> {
    const response = await http.post(`${this.baseUrl}/suppliers`, params);
    return response.data.data;
  }

  async updateSupplier(supplierId: string, params: Partial<CreateSupplierParams>): Promise<Supplier> {
    const response = await http.put(`${this.baseUrl}/suppliers/${supplierId}`, params);
    return response.data.data;
  }

  async deleteSupplier(supplierId: string): Promise<void> {
    await http.delete(`${this.baseUrl}/suppliers/${supplierId}`);
  }

  async fetchProcurementRecords(tenantId: string, filters?: {
    status?: ProcurementStatus;
    supplier_id?: string;
    date_from?: string;
    date_to?: string;
  }): Promise<ProcurementRecord[]> {
    const response = await http.get(`${this.baseUrl}/records`, {
      params: { tenant_id: tenantId, ...filters },
    });
    return response.data.data;
  }

  async fetchProcurementRecord(recordId: string): Promise<ProcurementRecord> {
    const response = await http.get(`${this.baseUrl}/records/${recordId}`);
    return response.data.data;
  }

  async createProcurement(params: CreateProcurementParams): Promise<ProcurementRecord> {
    const response = await http.post(`${this.baseUrl}/records`, params);
    return response.data.data;
  }

  async updateProcurementStatus(recordId: string, status: ProcurementStatus): Promise<ProcurementRecord> {
    const response = await http.put(`${this.baseUrl}/records/${recordId}/status`, { status });
    return response.data.data;
  }

  async receiveProcurement(recordId: string, items: {
    item_id: string;
    received_quantity: number;
    quality_status: QualityStatus;
  }[]): Promise<ProcurementRecord> {
    const response = await http.post(`${this.baseUrl}/records/${recordId}/receive`, { items });
    return response.data.data;
  }

  async fetchProcurementStats(tenantId: string): Promise<ProcurementStats> {
    const response = await http.get(`${this.baseUrl}/stats?tenant_id=${tenantId}`);
    return response.data.data;
  }

  async fetchSupplierPerformance(supplierId: string): Promise<SupplierPerformance> {
    const response = await http.get(`${this.baseUrl}/suppliers/${supplierId}/performance`);
    return response.data.data;
  }

  async approveProcurement(recordId: string): Promise<ProcurementRecord> {
    const response = await http.post(`${this.baseUrl}/records/${recordId}/approve`);
    return response.data.data;
  }

  async cancelProcurement(recordId: string, reason: string): Promise<ProcurementRecord> {
    const response = await http.post(`${this.baseUrl}/records/${recordId}/cancel`, { reason });
    return response.data.data;
  }
}

class ProcurementMockDataSource implements IProcurementDataSource {
  private suppliers: Supplier[] = [
    {
      id: 'SUP-001',
      tenant_id: 'tenant-001',
      name: '深圳电子科技有限公司',
      code: 'SZ-ELEC-001',
      contact_person: '张经理',
      phone: '13800138001',
      email: 'zhang@sz-elec.com',
      address: '深圳市南山区科技园',
      status: 'ACTIVE',
      level: 'A',
      category: ['电子产品', '配件'],
      payment_terms: '月结30天',
      credit_limit: 500000,
      credit_used: 120000,
      lead_time_days: 7,
      min_order_amount: 1000,
      rating: 4.8,
      total_orders: 156,
      total_amount: 2580000,
      on_time_rate: 96.5,
      quality_pass_rate: 98.2,
      created_at: '2025-01-15T10:00:00Z',
      updated_at: '2026-03-20T14:30:00Z',
    },
    {
      id: 'SUP-002',
      tenant_id: 'tenant-001',
      name: '广州服装批发中心',
      code: 'GZ-CLOTH-001',
      contact_person: '李总',
      phone: '13900139002',
      email: 'li@gz-cloth.com',
      address: '广州市白云区服装城',
      status: 'ACTIVE',
      level: 'B',
      category: ['服装', '纺织品'],
      payment_terms: '月结15天',
      credit_limit: 200000,
      credit_used: 50000,
      lead_time_days: 5,
      min_order_amount: 500,
      rating: 4.5,
      total_orders: 89,
      total_amount: 890000,
      on_time_rate: 92.3,
      quality_pass_rate: 95.8,
      created_at: '2025-03-20T09:00:00Z',
      updated_at: '2026-03-18T16:00:00Z',
    },
    {
      id: 'SUP-003',
      tenant_id: 'tenant-001',
      name: '义乌小商品批发',
      code: 'YW-SMALL-001',
      contact_person: '王老板',
      phone: '13700137003',
      address: '义乌市国际商贸城',
      status: 'ACTIVE',
      level: 'B',
      category: ['小商品', '日用品', '饰品'],
      payment_terms: '现结',
      credit_limit: 100000,
      credit_used: 0,
      lead_time_days: 3,
      min_order_amount: 200,
      rating: 4.2,
      total_orders: 234,
      total_amount: 456000,
      on_time_rate: 88.5,
      quality_pass_rate: 92.1,
      created_at: '2025-02-10T08:00:00Z',
      updated_at: '2026-03-22T10:00:00Z',
    },
    {
      id: 'SUP-004',
      tenant_id: 'tenant-001',
      name: '东莞塑料制品厂',
      code: 'DG-PLASTIC-001',
      contact_person: '陈经理',
      phone: '13600136004',
      email: 'chen@dg-plastic.com',
      address: '东莞市长安镇工业区',
      status: 'INACTIVE',
      level: 'C',
      category: ['塑料制品', '包装材料'],
      payment_terms: '月结30天',
      credit_limit: 80000,
      credit_used: 25000,
      lead_time_days: 10,
      min_order_amount: 2000,
      rating: 3.5,
      total_orders: 45,
      total_amount: 180000,
      on_time_rate: 78.2,
      quality_pass_rate: 85.6,
      remarks: '近期质量问题较多，暂停合作',
      created_at: '2025-04-05T11:00:00Z',
      updated_at: '2026-02-28T09:00:00Z',
    },
  ];

  private procurementRecords: ProcurementRecord[] = [
    {
      id: 'PO-2026032401',
      tenant_id: 'tenant-001',
      supplier_id: 'SUP-001',
      supplier_name: '深圳电子科技有限公司',
      order_no: 'PO-2026032401',
      status: 'CONFIRMED',
      items: [
        {
          id: 'ITEM-001',
          procurement_id: 'PO-2026032401',
          product_id: 'PROD-001',
          product_name: '蓝牙耳机',
          sku: 'SKU-BT-001',
          quantity: 100,
          unit: '个',
          unit_price: 35,
          total_price: 3500,
          received_quantity: 0,
          quality_status: 'PENDING',
        },
        {
          id: 'ITEM-002',
          procurement_id: 'PO-2026032401',
          product_id: 'PROD-002',
          product_name: '手机壳',
          sku: 'SKU-CASE-001',
          quantity: 200,
          unit: '个',
          unit_price: 8,
          total_price: 1600,
          received_quantity: 0,
          quality_status: 'PENDING',
        },
      ],
      total_quantity: 300,
      total_amount: 5100,
      currency: 'CNY',
      payment_status: 'UNPAID',
      paid_amount: 0,
      expected_date: '2026-03-31',
      warehouse_id: 'WH-001',
      warehouse_name: '深圳仓',
      purchaser: '采购员A',
      remarks: '紧急补货',
      created_at: '2026-03-24T10:00:00Z',
      updated_at: '2026-03-24T10:00:00Z',
    },
    {
      id: 'PO-2026032301',
      tenant_id: 'tenant-001',
      supplier_id: 'SUP-002',
      supplier_name: '广州服装批发中心',
      order_no: 'PO-2026032301',
      status: 'IN_TRANSIT',
      items: [
        {
          id: 'ITEM-003',
          procurement_id: 'PO-2026032301',
          product_id: 'PROD-003',
          product_name: '夏季T恤',
          sku: 'SKU-TSHIRT-001',
          quantity: 500,
          unit: '件',
          unit_price: 25,
          total_price: 12500,
          received_quantity: 0,
          quality_status: 'PENDING',
        },
      ],
      total_quantity: 500,
      total_amount: 12500,
      currency: 'CNY',
      payment_status: 'PARTIAL',
      paid_amount: 5000,
      expected_date: '2026-03-28',
      warehouse_id: 'WH-002',
      warehouse_name: '广州仓',
      purchaser: '采购员B',
      created_at: '2026-03-23T14:00:00Z',
      updated_at: '2026-03-24T09:00:00Z',
    },
    {
      id: 'PO-2026032001',
      tenant_id: 'tenant-001',
      supplier_id: 'SUP-003',
      supplier_name: '义乌小商品批发',
      order_no: 'PO-2026032001',
      status: 'RECEIVED',
      items: [
        {
          id: 'ITEM-004',
          procurement_id: 'PO-2026032001',
          product_id: 'PROD-004',
          product_name: '发夹套装',
          sku: 'SKU-HAIR-001',
          quantity: 1000,
          unit: '套',
          unit_price: 3.5,
          total_price: 3500,
          received_quantity: 1000,
          quality_status: 'PASSED',
        },
      ],
      total_quantity: 1000,
      total_amount: 3500,
      currency: 'CNY',
      payment_status: 'PAID',
      paid_amount: 3500,
      expected_date: '2026-03-23',
      actual_date: '2026-03-22',
      warehouse_id: 'WH-001',
      warehouse_name: '深圳仓',
      purchaser: '采购员A',
      approver: '采购经理',
      approved_at: '2026-03-20T15:00:00Z',
      created_at: '2026-03-20T10:00:00Z',
      updated_at: '2026-03-22T16:00:00Z',
    },
  ];

  private delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  async fetchSuppliers(tenantId: string): Promise<Supplier[]> {
    await this.delay(300);
    return this.suppliers.filter(s => s.tenant_id === tenantId);
  }

  async fetchSupplier(supplierId: string): Promise<Supplier> {
    await this.delay(200);
    const supplier = this.suppliers.find(s => s.id === supplierId);
    if (!supplier) throw new Error('Supplier not found');
    return supplier;
  }

  async createSupplier(params: CreateSupplierParams): Promise<Supplier> {
    await this.delay(300);
    const newSupplier: Supplier = {
      id: `SUP-${Date.now()}`,
      tenant_id: 'tenant-001',
      name: params.name,
      code: params.code,
      contact_person: params.contact_person,
      phone: params.phone,
      email: params.email,
      address: params.address,
      status: 'ACTIVE',
      level: 'C',
      category: params.category,
      payment_terms: params.payment_terms,
      credit_limit: params.credit_limit,
      lead_time_days: params.lead_time_days,
      min_order_amount: params.min_order_amount,
      rating: 0,
      total_orders: 0,
      total_amount: 0,
      on_time_rate: 0,
      quality_pass_rate: 0,
      remarks: params.remarks,
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
    };
    this.suppliers.push(newSupplier);
    return newSupplier;
  }

  async updateSupplier(supplierId: string, params: Partial<CreateSupplierParams>): Promise<Supplier> {
    await this.delay(300);
    const index = this.suppliers.findIndex(s => s.id === supplierId);
    if (index === -1) throw new Error('Supplier not found');
    
    this.suppliers[index] = {
      ...this.suppliers[index],
      ...params,
      updated_at: new Date().toISOString(),
    };
    return this.suppliers[index];
  }

  async deleteSupplier(supplierId: string): Promise<void> {
    await this.delay(200);
    const index = this.suppliers.findIndex(s => s.id === supplierId);
    if (index !== -1) {
      this.suppliers.splice(index, 1);
    }
  }

  async fetchProcurementRecords(tenantId: string, filters?: {
    status?: ProcurementStatus;
    supplier_id?: string;
    date_from?: string;
    date_to?: string;
  }): Promise<ProcurementRecord[]> {
    await this.delay(300);
    let records = this.procurementRecords.filter(r => r.tenant_id === tenantId);
    
    if (filters?.status) {
      records = records.filter(r => r.status === filters.status);
    }
    if (filters?.supplier_id) {
      records = records.filter(r => r.supplier_id === filters.supplier_id);
    }
    
    return records;
  }

  async fetchProcurementRecord(recordId: string): Promise<ProcurementRecord> {
    await this.delay(200);
    const record = this.procurementRecords.find(r => r.id === recordId);
    if (!record) throw new Error('Procurement record not found');
    return record;
  }

  async createProcurement(params: CreateProcurementParams): Promise<ProcurementRecord> {
    await this.delay(300);
    const supplier = this.suppliers.find(s => s.id === params.supplier_id);
    if (!supplier) throw new Error('Supplier not found');

    const items = params.items.map((item, idx) => ({
      id: `ITEM-${Date.now()}-${idx}`,
      procurement_id: `PO-${Date.now()}`,
      product_id: item.product_id,
      product_name: item.product_name,
      sku: item.sku,
      quantity: item.quantity,
      unit: item.unit,
      unit_price: item.unit_price,
      total_price: item.quantity * item.unit_price,
      received_quantity: 0,
      quality_status: 'PENDING' as QualityStatus,
    }));

    const newRecord: ProcurementRecord = {
      id: `PO-${Date.now()}`,
      tenant_id: 'tenant-001',
      supplier_id: params.supplier_id,
      supplier_name: supplier.name,
      order_no: `PO-${new Date().toISOString().slice(0, 10).replace(/-/g, '')}${String(this.procurementRecords.length + 1).padStart(2, '0')}`,
      status: 'PENDING',
      items,
      total_quantity: items.reduce((sum, i) => sum + i.quantity, 0),
      total_amount: items.reduce((sum, i) => sum + i.total_price, 0),
      currency: 'CNY',
      payment_status: 'UNPAID',
      paid_amount: 0,
      expected_date: params.expected_date,
      warehouse_id: params.warehouse_id,
      purchaser: '当前用户',
      remarks: params.remarks,
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
    };

    this.procurementRecords.push(newRecord);
    return newRecord;
  }

  async updateProcurementStatus(recordId: string, status: ProcurementStatus): Promise<ProcurementRecord> {
    await this.delay(300);
    const index = this.procurementRecords.findIndex(r => r.id === recordId);
    if (index === -1) throw new Error('Procurement record not found');

    this.procurementRecords[index] = {
      ...this.procurementRecords[index],
      status,
      updated_at: new Date().toISOString(),
    };

    return this.procurementRecords[index];
  }

  async receiveProcurement(recordId: string, items: {
    item_id: string;
    received_quantity: number;
    quality_status: QualityStatus;
  }[]): Promise<ProcurementRecord> {
    await this.delay(300);
    const index = this.procurementRecords.findIndex(r => r.id === recordId);
    if (index === -1) throw new Error('Procurement record not found');

    const record = this.procurementRecords[index];
    items.forEach(item => {
      const itemIndex = record.items.findIndex(i => i.id === item.item_id);
      if (itemIndex !== -1) {
        record.items[itemIndex].received_quantity = item.received_quantity;
        record.items[itemIndex].quality_status = item.quality_status;
      }
    });

    record.status = 'RECEIVED';
    record.actual_date = new Date().toISOString().slice(0, 10);
    record.updated_at = new Date().toISOString();

    return record;
  }

  async fetchProcurementStats(tenantId: string): Promise<ProcurementStats> {
    await this.delay(200);
    const records = this.procurementRecords.filter(r => r.tenant_id === tenantId);
    const suppliers = this.suppliers.filter(s => s.tenant_id === tenantId);

    return {
      total_orders: records.length,
      pending_orders: records.filter(r => r.status === 'PENDING' || r.status === 'CONFIRMED').length,
      in_transit_orders: records.filter(r => r.status === 'IN_TRANSIT').length,
      completed_orders: records.filter(r => r.status === 'RECEIVED').length,
      total_amount: records.reduce((sum, r) => sum + r.total_amount, 0),
      pending_amount: records.filter(r => r.payment_status !== 'PAID').reduce((sum, r) => sum + r.total_amount - r.paid_amount, 0),
      supplier_count: suppliers.length,
      active_supplier_count: suppliers.filter(s => s.status === 'ACTIVE').length,
    };
  }

  async fetchSupplierPerformance(supplierId: string): Promise<SupplierPerformance> {
    await this.delay(200);
    const supplier = this.suppliers.find(s => s.id === supplierId);
    if (!supplier) throw new Error('Supplier not found');

    const records = this.procurementRecords.filter(r => r.supplier_id === supplierId);

    return {
      supplier_id: supplierId,
      supplier_name: supplier.name,
      total_orders: records.length,
      on_time_rate: supplier.on_time_rate,
      quality_pass_rate: supplier.quality_pass_rate,
      return_rate: 2.5,
      avg_lead_time: supplier.lead_time_days || 7,
      total_amount: records.reduce((sum, r) => sum + r.total_amount, 0),
    };
  }

  async approveProcurement(recordId: string): Promise<ProcurementRecord> {
    await this.delay(300);
    const index = this.procurementRecords.findIndex(r => r.id === recordId);
    if (index === -1) throw new Error('Procurement record not found');

    this.procurementRecords[index] = {
      ...this.procurementRecords[index],
      status: 'CONFIRMED',
      approver: '审批人',
      approved_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
    };

    return this.procurementRecords[index];
  }

  async cancelProcurement(recordId: string, reason: string): Promise<ProcurementRecord> {
    await this.delay(300);
    const index = this.procurementRecords.findIndex(r => r.id === recordId);
    if (index === -1) throw new Error('Procurement record not found');

    this.procurementRecords[index] = {
      ...this.procurementRecords[index],
      status: 'CANCELLED',
      remarks: `${this.procurementRecords[index].remarks || ''}\n取消原因: ${reason}`,
      updated_at: new Date().toISOString(),
    };

    return this.procurementRecords[index];
  }
}

const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const procurementDataSource: IProcurementDataSource = useMock
  ? new ProcurementMockDataSource()
  : new ProcurementApiDataSource();

export const SUPPLIER_STATUS_COLORS: Record<SupplierStatus, string> = {
  ACTIVE: 'success',
  INACTIVE: 'default',
  BLACKLISTED: 'error',
};

export const SUPPLIER_LEVEL_COLORS: Record<string, string> = {
  A: 'gold',
  B: 'blue',
  C: 'green',
  D: 'default',
};

export const PROCUREMENT_STATUS_COLORS: Record<ProcurementStatus, string> = {
  PENDING: 'default',
  CONFIRMED: 'processing',
  IN_TRANSIT: 'warning',
  RECEIVED: 'success',
  CANCELLED: 'error',
};

export const PROCUREMENT_STATUS_TEXT: Record<ProcurementStatus, string> = {
  PENDING: '待确认',
  CONFIRMED: '已确认',
  IN_TRANSIT: '运输中',
  RECEIVED: '已收货',
  CANCELLED: '已取消',
};

export const PAYMENT_STATUS_COLORS: Record<PaymentStatus, string> = {
  UNPAID: 'error',
  PARTIAL: 'warning',
  PAID: 'success',
};

export const QUALITY_STATUS_COLORS: Record<QualityStatus, string> = {
  PENDING: 'default',
  PASSED: 'success',
  FAILED: 'error',
  PARTIAL: 'warning',
};
