/**
 * [MOCK] 物流管理数据源
 * AI注意: 这是Mock实现，不是真实业务逻辑
 * 仅在USE_MOCK=true时启用
 */

export interface LogisticsProvider {
  id: string;
  name: string;
  code: string;
  status: 'ACTIVE' | 'INACTIVE';
  apiEndpoint?: string;
  createdAt: string;
  updatedAt: string;
}

export interface Shipment {
  id: string;
  orderId: string;
  trackingNumber: string;
  provider: string;
  status: 'PENDING' | 'PICKED_UP' | 'IN_TRANSIT' | 'OUT_FOR_DELIVERY' | 'DELIVERED' | 'FAILED';
  origin: string;
  destination: string;
  estimatedDelivery: string;
  actualDelivery?: string;
  createdAt: string;
  updatedAt: string;
}

export interface TrackingEvent {
  id: string;
  shipmentId: string;
  status: string;
  location: string;
  description: string;
  timestamp: string;
}

export interface ILogisticsDataSource {
  fetchProviders(): Promise<LogisticsProvider[]>;
  createProvider(data: Partial<LogisticsProvider>): Promise<LogisticsProvider>;
  updateProvider(id: string, data: Partial<LogisticsProvider>): Promise<LogisticsProvider>;
  deleteProvider(id: string): Promise<void>;
  
  fetchShipments(params?: { status?: string; provider?: string }): Promise<Shipment[]>;
  createShipment(data: Partial<Shipment>): Promise<Shipment>;
  updateShipment(id: string, data: Partial<Shipment>): Promise<Shipment>;
  
  fetchTrackingEvents(shipmentId: string): Promise<TrackingEvent[]>;
  calculateFreight(params: { origin: string; destination: string; weight: number; dimensions: { length: number; width: number; height: number } }): Promise<{ provider: string; cost: number; estimatedDays: number }[]>;
}

class MockLogisticsDataSource implements ILogisticsDataSource {
  private providers: LogisticsProvider[] = [
    { id: '1', name: 'FedEx', code: 'FEDEX', status: 'ACTIVE', createdAt: '2026-03-01', updatedAt: '2026-03-01' },
    { id: '2', name: 'UPS', code: 'UPS', status: 'ACTIVE', createdAt: '2026-03-01', updatedAt: '2026-03-01' },
    { id: '3', name: 'DHL', code: 'DHL', status: 'ACTIVE', createdAt: '2026-03-01', updatedAt: '2026-03-01' },
  ];

  private shipments: Shipment[] = [
    {
      id: '1',
      orderId: 'ORD-2026-001',
      trackingNumber: 'FX123456789',
      provider: 'FEDEX',
      status: 'IN_TRANSIT',
      origin: 'Los Angeles, CA',
      destination: 'New York, NY',
      estimatedDelivery: '2026-03-20',
      createdAt: '2026-03-15',
      updatedAt: '2026-03-16',
    },
  ];

  private trackingEvents: TrackingEvent[] = [
    { id: '1', shipmentId: '1', status: 'PICKED_UP', location: 'Los Angeles, CA', description: 'Package picked up', timestamp: '2026-03-15T10:00:00Z' },
    { id: '2', shipmentId: '1', status: 'IN_TRANSIT', location: 'Phoenix, AZ', description: 'In transit', timestamp: '2026-03-16T08:00:00Z' },
  ];

  async fetchProviders(): Promise<LogisticsProvider[]> {
    await new Promise(resolve => setTimeout(resolve, 300));
    return [...this.providers];
  }

  async createProvider(data: Partial<LogisticsProvider>): Promise<LogisticsProvider> {
    await new Promise(resolve => setTimeout(resolve, 300));
    const newProvider: LogisticsProvider = {
      id: `${Date.now()}`,
      name: data.name || '',
      code: data.code || '',
      status: 'ACTIVE',
      createdAt: new Date().toISOString().split('T')[0],
      updatedAt: new Date().toISOString().split('T')[0],
      ...data,
    };
    this.providers.push(newProvider);
    return newProvider;
  }

  async updateProvider(id: string, data: Partial<LogisticsProvider>): Promise<LogisticsProvider> {
    await new Promise(resolve => setTimeout(resolve, 300));
    const index = this.providers.findIndex(p => p.id === id);
    if (index === -1) throw new Error('Provider not found');
    this.providers[index] = { ...this.providers[index], ...data, updatedAt: new Date().toISOString().split('T')[0] };
    return this.providers[index];
  }

  async deleteProvider(id: string): Promise<void> {
    await new Promise(resolve => setTimeout(resolve, 300));
    const index = this.providers.findIndex(p => p.id === id);
    if (index !== -1) {
      this.providers.splice(index, 1);
    }
  }

  async fetchShipments(params?: { status?: string; provider?: string }): Promise<Shipment[]> {
    await new Promise(resolve => setTimeout(resolve, 300));
    let result = [...this.shipments];
    if (params?.status) {
      result = result.filter(s => s.status === params.status);
    }
    if (params?.provider) {
      result = result.filter(s => s.provider === params.provider);
    }
    return result;
  }

  async createShipment(data: Partial<Shipment>): Promise<Shipment> {
    await new Promise(resolve => setTimeout(resolve, 300));
    const newShipment: Shipment = {
      id: `${Date.now()}`,
      orderId: data.orderId || '',
      trackingNumber: `FX${Date.now()}`,
      provider: data.provider || 'FEDEX',
      status: 'PENDING',
      origin: data.origin || '',
      destination: data.destination || '',
      estimatedDelivery: data.estimatedDelivery || '',
      createdAt: new Date().toISOString().split('T')[0],
      updatedAt: new Date().toISOString().split('T')[0],
      ...data,
    };
    this.shipments.push(newShipment);
    return newShipment;
  }

  async updateShipment(id: string, data: Partial<Shipment>): Promise<Shipment> {
    await new Promise(resolve => setTimeout(resolve, 300));
    const index = this.shipments.findIndex(s => s.id === id);
    if (index === -1) throw new Error('Shipment not found');
    this.shipments[index] = { ...this.shipments[index], ...data, updatedAt: new Date().toISOString().split('T')[0] };
    return this.shipments[index];
  }

  async fetchTrackingEvents(shipmentId: string): Promise<TrackingEvent[]> {
    await new Promise(resolve => setTimeout(resolve, 300));
    return this.trackingEvents.filter(e => e.shipmentId === shipmentId);
  }

  async calculateFreight(params: { origin: string; destination: string; weight: number; dimensions: { length: number; width: number; height: number } }): Promise<{ provider: string; cost: number; estimatedDays: number }[]> {
    await new Promise(resolve => setTimeout(resolve, 500));
    return [
      { provider: 'FEDEX', cost: 15.99, estimatedDays: 3 },
      { provider: 'UPS', cost: 18.50, estimatedDays: 2 },
      { provider: 'DHL', cost: 22.00, estimatedDays: 1 },
    ];
  }
}

class ApiLogisticsDataSource implements ILogisticsDataSource {
  private baseUrl = '/api/logistics';

  async fetchProviders(): Promise<LogisticsProvider[]> {
    const response = await fetch(`${this.baseUrl}/providers`);
    if (!response.ok) throw new Error('Failed to fetch providers');
    return response.json();
  }

  async createProvider(data: Partial<LogisticsProvider>): Promise<LogisticsProvider> {
    const response = await fetch(`${this.baseUrl}/providers`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
    if (!response.ok) throw new Error('Failed to create provider');
    return response.json();
  }

  async updateProvider(id: string, data: Partial<LogisticsProvider>): Promise<LogisticsProvider> {
    const response = await fetch(`${this.baseUrl}/providers/${id}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
    if (!response.ok) throw new Error('Failed to update provider');
    return response.json();
  }

  async deleteProvider(id: string): Promise<void> {
    const response = await fetch(`${this.baseUrl}/providers/${id}`, { method: 'DELETE' });
    if (!response.ok) throw new Error('Failed to delete provider');
  }

  async fetchShipments(params?: { status?: string; provider?: string }): Promise<Shipment[]> {
    const response = await fetch(`${this.baseUrl}/shipments?${new URLSearchParams(params as any)}`);
    if (!response.ok) throw new Error('Failed to fetch shipments');
    return response.json();
  }

  async createShipment(data: Partial<Shipment>): Promise<Shipment> {
    const response = await fetch(`${this.baseUrl}/shipments`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
    if (!response.ok) throw new Error('Failed to create shipment');
    return response.json();
  }

  async updateShipment(id: string, data: Partial<Shipment>): Promise<Shipment> {
    const response = await fetch(`${this.baseUrl}/shipments/${id}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
    if (!response.ok) throw new Error('Failed to update shipment');
    return response.json();
  }

  async fetchTrackingEvents(shipmentId: string): Promise<TrackingEvent[]> {
    const response = await fetch(`${this.baseUrl}/shipments/${shipmentId}/tracking`);
    if (!response.ok) throw new Error('Failed to fetch tracking events');
    return response.json();
  }

  async calculateFreight(params: { origin: string; destination: string; weight: number; dimensions: { length: number; width: number; height: number } }): Promise<{ provider: string; cost: number; estimatedDays: number }[]> {
    const response = await fetch(`${this.baseUrl}/freight/calculate`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(params),
    });
    if (!response.ok) throw new Error('Failed to calculate freight');
    return response.json();
  }
}

const useMock = process.env.REACT_APP_USE_MOCK === 'true';
export const logisticsDataSource: ILogisticsDataSource = useMock
  ? new MockLogisticsDataSource()
  : new ApiLogisticsDataSource();
