import { OrderCollector } from './OrderCollector';
import { ReturnSync } from './ReturnSync';
import { RefundQuery } from './RefundQuery';
import { Logger } from '../utils/Logger';

interface Message {
  type: string;
  payload: any;
  traceId?: string;
}

export class MessageHandler {
  private logger = new Logger('MessageHandler');
  
  constructor(
    private orderCollector: OrderCollector,
    private returnSync: ReturnSync,
    private refundQuery: RefundQuery
  ) {}
  
  async handle(message: Message, sender: chrome.runtime.MessageSender): Promise<any> {
    const traceId = message.traceId || this.generateTraceId();
    
    this.logger.info('Handling message', {
      type: message.type,
      traceId,
    });
    
    switch (message.type) {
      case 'COLLECT_ORDERS':
        return this.orderCollector.collectOrders(
          message.payload.shopId,
          message.payload.platform,
          message.payload.dateRange,
          traceId
        );
        
      case 'SYNC_ALL_ORDERS':
        return this.orderCollector.syncAllShops();
        
      case 'SYNC_RETURNS':
        return this.returnSync.syncReturns(
          message.payload.shopId,
          message.payload.platform,
          message.payload.returnIds,
          traceId
        );
        
      case 'SYNC_ALL_RETURNS':
        return this.returnSync.syncAllReturns();
        
      case 'GET_RETURN_STATUS':
        return this.returnSync.getReturnStatus(
          message.payload.platform,
          message.payload.returnId,
          traceId
        );
        
      case 'QUERY_REFUND_STATUS':
        return this.refundQuery.queryRefundStatus(
          message.payload.platform,
          message.payload.refundId,
          traceId
        );
        
      case 'QUERY_ALL_REFUNDS':
        return this.refundQuery.queryAllRefunds();
        
      case 'BATCH_QUERY_REFUNDS':
        return this.refundQuery.batchQueryRefunds(
          message.payload.refunds,
          traceId
        );
        
      case 'GET_CONFIG':
        return chrome.storage.local.get('config');
        
      case 'UPDATE_CONFIG':
        await chrome.storage.local.set({ config: message.payload.config });
        return { success: true };
        
      case 'REGISTER_SHOP':
        return this.registerShop(message.payload);
        
      case 'UNREGISTER_SHOP':
        return this.unregisterShop(message.payload.shopId);
        
      case 'GET_SHOPS':
        return chrome.storage.local.get('shops');
        
      default:
        throw new Error(`Unknown message type: ${message.type}`);
    }
  }
  
  private async registerShop(payload: {
    shopId: string;
    platform: string;
    tenantId: string;
  }): Promise<{ success: boolean }> {
    const data = await chrome.storage.local.get('shops');
    const shops = data.shops || [];
    
    const existingIndex = shops.findIndex(
      (s: any) => s.shopId === payload.shopId && s.platform === payload.platform
    );
    
    if (existingIndex >= 0) {
      shops[existingIndex] = payload;
    } else {
      shops.push(payload);
    }
    
    await chrome.storage.local.set({ shops });
    
    this.logger.info('Shop registered', { shopId: payload.shopId });
    
    return { success: true };
  }
  
  private async unregisterShop(shopId: string): Promise<{ success: boolean }> {
    const data = await chrome.storage.local.get('shops');
    const shops = data.shops || [];
    
    const updatedShops = shops.filter((s: any) => s.shopId !== shopId);
    
    await chrome.storage.local.set({ shops: updatedShops });
    
    this.logger.info('Shop unregistered', { shopId });
    
    return { success: true };
  }
  
  private generateTraceId(): string {
    return `TRC-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  }
}
