import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Store } from '../../entities/Store';
import { PlatformAdapterFactory } from './adapters/PlatformAdapterFactory';
import { IPlatformAdapter } from './adapters/IPlatformAdapter';
import { StoreBindingDto } from '../../api/dto/StoreBindingDto';
import { StoreStatus } from '../../types/enums/StoreStatus';
import { OperationAgentEvent } from '../../types/events/OperationAgentEvent';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { Logger } from '@nestjs/common';

@Injectable()
export class OperationAgentService {
  private readonly logger = new Logger(OperationAgentService.name);

  constructor(
    @InjectRepository(Store) private storeRepository: Repository<Store>,
    private platformAdapterFactory: PlatformAdapterFactory,
    private eventEmitter: EventEmitter2
  ) {}

  /**
   * 绑定店铺
   * @param dto 店铺绑定信息
   * @returns 绑定结果
   */
  async bindStore(dto: StoreBindingDto): Promise<Store> {
    this.logger.log(`开始绑定店铺: ${dto.platform} - ${dto.platformShopId}`);

    // 检查店铺是否已存在
    const existingStore = await this.storeRepository.findOne({
      where: {
        merchantId: dto.merchantId,
        platform: dto.platform,
        platformShopId: dto.platformShopId
      }
    });

    if (existingStore) {
      this.logger.warn(`店铺已存在: ${dto.platform} - ${dto.platformShopId}`);
      return existingStore;
    }

    // 创建新店铺记录
    const store = this.storeRepository.create({
      merchantId: dto.merchantId,
      name: dto.name,
      platform: dto.platform,
      platformShopId: dto.platformShopId,
      description: dto.description,
      status: StoreStatus.PENDING
    });

    try {
      // 保存店铺记录
      await this.storeRepository.save(store);
      
      // 获取平台适配器
      const adapter = this.platformAdapterFactory.createAdapter(dto.platform);
      
      // 执行授权
      await adapter.authorize(dto.authInfo);
      
      // 同步店铺信息
      const shopInfo = await adapter.getShopInfo();
      store.name = shopInfo.name;
      store.description = shopInfo.description;
      
      // 更新店铺状态
      store.status = StoreStatus.ACTIVE;
      await this.storeRepository.save(store);
      
      // 触发店铺绑定成功事件
      this.eventEmitter.emit(OperationAgentEvent.STORE_BOUND, store);
      
      this.logger.log(`店铺绑定成功: ${dto.platform} - ${dto.platformShopId}`);
      return store;
    } catch (error) {
      this.logger.error(`店铺绑定失败: ${error.message}`, error.stack);
      
      // 更新店铺状态为失败
      store.status = StoreStatus.INACTIVE;
      await this.storeRepository.save(store);
      
      // 触发店铺绑定失败事件
      this.eventEmitter.emit(OperationAgentEvent.STORE_BIND_FAILED, {
        storeId: store.id,
        error: error.message
      });
      
      throw error;
    }
  }

  /**
   * 同步店铺商品
   * @param storeId 店铺ID
   * @returns 同步结果
   */
  async syncProducts(storeId: string): Promise<{ success: boolean; count: number }> {
    this.logger.log(`开始同步店铺商品: ${storeId}`);

    const store = await this.storeRepository.findOneBy({ id: storeId });
    if (!store) {
      throw new Error('店铺不存在');
    }

    if (store.status !== StoreStatus.ACTIVE) {
      throw new Error('店铺状态异常，无法同步商品');
    }

    try {
      const adapter = this.platformAdapterFactory.createAdapter(store.platform);
      const products = await adapter.getProducts();
      
      // 处理商品同步逻辑
      // TODO: 实现商品同步到数据库
      
      this.logger.log(`商品同步完成: ${storeId}, 同步商品数: ${products.length}`);
      
      // 触发商品同步成功事件
      this.eventEmitter.emit(OperationAgentEvent.PRODUCTS_SYNCED, {
        storeId,
        count: products.length
      });
      
      return {
        success: true,
        count: products.length
      };
    } catch (error) {
      this.logger.error(`商品同步失败: ${error.message}`, error.stack);
      
      // 触发商品同步失败事件
      this.eventEmitter.emit(OperationAgentEvent.PRODUCTS_SYNC_FAILED, {
        storeId,
        error: error.message
      });
      
      throw error;
    }
  }

  /**
   * 同步店铺订单
   * @param storeId 店铺ID
   * @returns 同步结果
   */
  async syncOrders(storeId: string): Promise<{ success: boolean; count: number }> {
    this.logger.log(`开始同步店铺订单: ${storeId}`);

    const store = await this.storeRepository.findOneBy({ id: storeId });
    if (!store) {
      throw new Error('店铺不存在');
    }

    if (store.status !== StoreStatus.ACTIVE) {
      throw new Error('店铺状态异常，无法同步订单');
    }

    try {
      const adapter = this.platformAdapterFactory.createAdapter(store.platform);
      const orders = await adapter.getOrders();
      
      // 处理订单同步逻辑
      // TODO: 实现订单同步到数据库
      
      this.logger.log(`订单同步完成: ${storeId}, 同步订单数: ${orders.length}`);
      
      // 触发订单同步成功事件
      this.eventEmitter.emit(OperationAgentEvent.ORDERS_SYNCED, {
        storeId,
        count: orders.length
      });
      
      return {
        success: true,
        count: orders.length
      };
    } catch (error) {
      this.logger.error(`订单同步失败: ${error.message}`, error.stack);
      
      // 触发订单同步失败事件
      this.eventEmitter.emit(OperationAgentEvent.ORDERS_SYNC_FAILED, {
        storeId,
        error: error.message
      });
      
      throw error;
    }
  }

  /**
   * 更新商品价格
   * @param storeId 店铺ID
   * @param productId 商品ID
   * @param price 新价格
   * @returns 更新结果
   */
  async updateProductPrice(storeId: string, productId: string, price: number): Promise<boolean> {
    this.logger.log(`开始更新商品价格: ${storeId} - ${productId} - ${price}`);

    const store = await this.storeRepository.findOneBy({ id: storeId });
    if (!store) {
      throw new Error('店铺不存在');
    }

    if (store.status !== StoreStatus.ACTIVE) {
      throw new Error('店铺状态异常，无法更新商品价格');
    }

    try {
      const adapter = this.platformAdapterFactory.createAdapter(store.platform);
      await adapter.updateProductPrice(productId, price);
      
      this.logger.log(`商品价格更新成功: ${storeId} - ${productId} - ${price}`);
      
      // 触发商品价格更新成功事件
      this.eventEmitter.emit(OperationAgentEvent.PRODUCT_PRICE_UPDATED, {
        storeId,
        productId,
        price
      });
      
      return true;
    } catch (error) {
      this.logger.error(`商品价格更新失败: ${error.message}`, error.stack);
      
      // 触发商品价格更新失败事件
      this.eventEmitter.emit(OperationAgentEvent.PRODUCT_PRICE_UPDATE_FAILED, {
        storeId,
        productId,
        price,
        error: error.message
      });
      
      throw error;
    }
  }

  /**
   * 获取店铺列表
   * @param merchantId 商户ID
   * @returns 店铺列表
   */
  async getStores(merchantId: string): Promise<Store[]> {
    this.logger.log(`获取商户店铺列表: ${merchantId}`);
    return this.storeRepository.find({ where: { merchantId } });
  }

  /**
   * 获取店铺详情
   * @param storeId 店铺ID
   * @returns 店铺详情
   */
  async getStore(storeId: string): Promise<Store> {
    this.logger.log(`获取店铺详情: ${storeId}`);
    const store = await this.storeRepository.findOneBy({ id: storeId });
    if (!store) {
      throw new Error('店铺不存在');
    }
    return store;
  }

  /**
   * 停用店铺
   * @param storeId 店铺ID
   * @returns 操作结果
   */
  async deactivateStore(storeId: string): Promise<Store> {
    this.logger.log(`停用店铺: ${storeId}`);

    const store = await this.storeRepository.findOneBy({ id: storeId });
    if (!store) {
      throw new Error('店铺不存在');
    }

    store.status = StoreStatus.INACTIVE;
    await this.storeRepository.save(store);
    
    // 触发店铺停用事件
    this.eventEmitter.emit(OperationAgentEvent.STORE_DEACTIVATED, store);
    
    this.logger.log(`店铺已停用: ${storeId}`);
    return store;
  }

  /**
   * 重新激活店铺
   * @param storeId 店铺ID
   * @returns 操作结果
   */
  async reactivateStore(storeId: string): Promise<Store> {
    this.logger.log(`重新激活店铺: ${storeId}`);

    const store = await this.storeRepository.findOneBy({ id: storeId });
    if (!store) {
      throw new Error('店铺不存在');
    }

    store.status = StoreStatus.ACTIVE;
    await this.storeRepository.save(store);
    
    // 触发店铺激活事件
    this.eventEmitter.emit(OperationAgentEvent.STORE_ACTIVATED, store);
    
    this.logger.log(`店铺已重新激活: ${storeId}`);
    return store;
  }
}
