import { createMachine, createActor } from 'xstate';
import db from '../../config/database';
import { DomainEventBus } from '../../core/runtime/DomainEventBus';
import { logger } from '../../utils/logger';
import { PricingService } from '../core/PricingService';
import { ProductService } from '../product/ProductService';

/**
 * [BE-P102] 商品刊登服务
 * 负责将可售商品同步到各平台，支持 API 平台和无 API 平台
 *
 * 状态流转: READY_FOR_LISTING → LISTING_IN_PROGRESS → LISTED → MONITORING
 */

// 刊登任务状态
export type ListingState =
  | 'READY_FOR_LISTING'
  | 'LISTING_IN_PROGRESS'
  | 'LISTED'
  | 'MONITORING'
  | 'FAILED';

// 刊登任务事件
export type ListingEvent =
  | { type: 'START_LISTING' }
  | { type: 'COMPLETE_LISTING' }
  | { type: 'START_MONITORING' }
  | { type: 'FAIL'; reason: string }
  | { type: 'RETRY' };

// 刊登任务上下文
export interface ListingContext {
  taskId: string;
  tenantId: string;
  shopId: string;
  traceId: string;
  businessType: 'TOC' | 'TOB';
  productId: string;
  platform: string;
  platformType: 'api' | 'no_api';
  listingData: any;
  platformProductId?: string;
  errorMessage?: string;
  createdAt: string;
  updatedAt: string;
}

// 刊登配置
export interface ListingConfig {
  platform: string;
  platformType: 'api' | 'no_api';
  priceStrategy?: string;
  syncInventory?: boolean;
  autoRetry?: boolean;
  retryCount?: number;
  maxRetryDelay?: number;
}

// 平台连接器接口
export interface IPlatformConnector {
  publish(productData: any): Promise<{ success: boolean; platformProductId?: string; error?: string }>;
  update(productId: string, productData: any): Promise<{ success: boolean; error?: string }>;
  delete(productId: string): Promise<{ success: boolean; error?: string }>;
  getStatus(productId: string): Promise<{ status: string; error?: string }>;
}

// 刊登状态机
export const listingStateMachine = createMachine({
  id: 'listing',
  initial: 'READY_FOR_LISTING',
  context: {} as ListingContext,
  states: {
    READY_FOR_LISTING: {
      on: {
        START_LISTING: 'LISTING_IN_PROGRESS',
        FAIL: 'FAILED',
      },
    },
    LISTING_IN_PROGRESS: {
      on: {
        COMPLETE_LISTING: 'LISTED',
        FAIL: 'FAILED',
      },
    },
    LISTED: {
      on: {
        START_MONITORING: 'MONITORING',
        FAIL: 'FAILED',
      },
    },
    MONITORING: {
      type: 'final',
    },
    FAILED: {
      on: {
        RETRY: 'READY_FOR_LISTING',
      },
    },
  },
});

export class ProductListingService {
  private static TABLE_NAME = 'cf_product_listing';
  private pricingService: PricingService;
  private productService: ProductService;
  private connectors: Map<string, IPlatformConnector> = new Map();

  constructor() {
    this.pricingService = new PricingService();
    this.productService = new ProductService();
    this.initializeConnectors();
  }

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.TABLE_NAME);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.TABLE_NAME} table...`);
      await db.schema.createTable(this.TABLE_NAME, (table) => {
        table.increments('id').primary();
        table.string('task_id', 64).notNullable().unique();
        table.string('tenant_id', 50).notNullable().index();
        table.string('shop_id', 50).notNullable().index();
        table.string('trace_id', 64).notNullable();
        table.enum('business_type', ['TOC', 'TOB']).notNullable();
        table.string('product_id', 100).notNullable();
        table.string('platform', 50).notNullable();
        table.enum('platform_type', ['api', 'no_api']).notNullable();
        table.enum('status', [
          'READY_FOR_LISTING',
          'LISTING_IN_PROGRESS',
          'LISTED',
          'MONITORING',
          'FAILED',
        ]).defaultTo('READY_FOR_LISTING');
        table.string('platform_product_id', 100).nullable();
        table.json('listing_data');
        table.text('error_message');
        table.integer('retry_count').defaultTo(0);
        table.timestamps(true, true);

        // 索引优化
        table.index(['tenant_id', 'status'], 'idx_listing_status');
        table.index(['platform', 'status'], 'idx_listing_platform');
        table.index(['product_id'], 'idx_listing_product');
        table.index(['created_at'], 'idx_listing_created');
      });
      logger.info(`✅ Table ${this.TABLE_NAME} created`);
    }
  }

  /**
   * 初始化平台连接器
   */
  private initializeConnectors(): void {
    // 注册模拟连接器（实际项目中应该从 connectors 目录加载）
    this.registerConnector('amazon', {
      async publish(productData) {
        logger.info(`[AmazonConnector] Publishing product: ${productData.title}`);
        // 模拟API调用
        await new Promise((resolve) => setTimeout(resolve, 1000));
        return {
          success: true,
          platformProductId: `AMZ-${Date.now()}`,
        };
      },
      async update(productId, productData) {
        return { success: true };
      },
      async delete(productId) {
        return { success: true };
      },
      async getStatus(productId) {
        return { status: 'ACTIVE' };
      },
    });

    this.registerConnector('shopee', {
      async publish(productData) {
        logger.info(`[ShopeeConnector] Publishing product: ${productData.title}`);
        await new Promise((resolve) => setTimeout(resolve, 1000));
        return {
          success: true,
          platformProductId: `SHO-${Date.now()}`,
        };
      },
      async update(productId, productData) {
        return { success: true };
      },
      async delete(productId) {
        return { success: true };
      },
      async getStatus(productId) {
        return { status: 'ACTIVE' };
      },
    });
  }

  /**
   * 注册平台连接器
   */
  registerConnector(platform: string, connector: IPlatformConnector): void {
    this.connectors.set(platform.toLowerCase(), connector);
    logger.info(`[ProductListingService] Registered connector for platform: ${platform}`);
  }

  /**
   * 创建刊登任务
   */
  async createTask(
    tenantId: string,
    shopId: string,
    businessType: 'TOC' | 'TOB',
    productId: string,
    platform: string,
    platformType: 'api' | 'no_api',
    listingData: any,
    traceId: string
  ): Promise<string> {
    const taskId = `LIST-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    const now = new Date().toISOString();

    await db(ProductListingService.TABLE_NAME).insert({
      task_id: taskId,
      tenant_id: tenantId,
      shop_id: shopId,
      trace_id: traceId,
      business_type: businessType,
      product_id: productId,
      platform,
      platform_type: platformType,
      status: 'READY_FOR_LISTING',
      listing_data: JSON.stringify(listingData),
      created_at: now,
      updated_at: now,
    });

    this.logOperation(taskId, tenantId, shopId, traceId, businessType, 'TASK_CREATED', {
      platform,
      platformType,
      productId,
    });

    return taskId;
  }

  /**
   * 执行刊登流程
   */
  async executeListing(taskId: string): Promise<void> {
    const task = await this.getTask(taskId);
    if (!task) {
      throw new Error(`Task not found: ${taskId}`);
    }

    const context: ListingContext = {
      taskId: task.task_id,
      tenantId: task.tenant_id,
      shopId: task.shop_id,
      traceId: task.trace_id,
      businessType: task.business_type,
      productId: task.product_id,
      platform: task.platform,
      platformType: task.platform_type,
      listingData: JSON.parse(task.listing_data),
      platformProductId: task.platform_product_id,
      errorMessage: task.error_message,
      createdAt: task.created_at,
      updatedAt: task.updated_at,
    };

    const actor = createActor(listingStateMachine, {
      input: context,
    });

    actor.subscribe((state) => {
      this.handleStateChange(taskId, state.value as ListingState, state.context);
    });

    actor.start();

    try {
      // Step 1: 开始刊登
      actor.send({ type: 'START_LISTING' });
      await this.updateTask(taskId, {
        status: 'LISTING_IN_PROGRESS',
      });

      // Step 2: 执行刊登
      const publishResult = await this.publishToPlatform(task);

      if (!publishResult.success) {
        actor.send({ type: 'FAIL', reason: publishResult.error || 'Unknown error' });
        await this.updateTask(taskId, {
          status: 'FAILED',
          error_message: publishResult.error || 'Unknown error',
          retry_count: (task.retry_count || 0) + 1,
        });
        return;
      }

      // Step 3: 完成刊登
      actor.send({ type: 'COMPLETE_LISTING' });
      await this.updateTask(taskId, {
        status: 'LISTED',
        platform_product_id: publishResult.platformProductId,
      });

      // Step 4: 开始监控
      actor.send({ type: 'START_MONITORING' });
      await this.updateTask(taskId, {
        status: 'MONITORING',
      });

      // 发布事件通知
      DomainEventBus.publish('product.listing.completed', {
        taskId,
        tenantId: task.tenant_id,
        shopId: task.shop_id,
        productId: task.product_id,
        platform: task.platform,
        platformProductId: publishResult.platformProductId,
      });

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      actor.send({ type: 'FAIL', reason: errorMessage });
      await this.updateTask(taskId, {
        status: 'FAILED',
        error_message: errorMessage,
        retry_count: (task.retry_count || 0) + 1,
      });

      this.logOperation(
        taskId,
        task.tenant_id,
        task.shop_id,
        task.trace_id,
        task.business_type,
        'LISTING_FAILED',
        { error: errorMessage }
      );
    }

    actor.stop();
  }

  /**
   * 发布到平台
   */
  private async publishToPlatform(task: any): Promise<{ success: boolean; platformProductId?: string; error?: string }> {
    const platform = task.platform.toLowerCase();
    const connector = this.connectors.get(platform);

    if (!connector) {
      // 无 API 平台处理
      if (task.platform_type === 'no_api') {
        return this.handleNoAPIPlatform(task);
      }
      return { success: false, error: `No connector found for platform: ${task.platform}` };
    }

    // API 平台处理
    const listingData = JSON.parse(task.listing_data);
    return connector.publish(listingData);
  }

  /**
   * 处理无 API 平台
   */
  private async handleNoAPIPlatform(task: any): Promise<{ success: boolean; platformProductId?: string; error?: string }> {
    // 对于无 API 平台，生成 PENDING_REVIEW 状态的任务
    // 实际项目中应该创建审核任务，由人工处理
    logger.info(`[ProductListingService] Creating PENDING_REVIEW task for no-API platform: ${task.platform}`);
    
    // 模拟生成平台商品ID
    const platformProductId = `NOAPI-${Date.now()}`;
    
    // 发布审核事件
    DomainEventBus.publish('product.listing.pending_review', {
      taskId: task.task_id,
      tenantId: task.tenant_id,
      productId: task.product_id,
      platform: task.platform,
      platformProductId,
    });

    return { success: true, platformProductId };
  }

  /**
   * 重试失败任务
   */
  async retryTask(taskId: string): Promise<void> {
    const task = await this.getTask(taskId);
    if (!task) {
      throw new Error(`Task not found: ${taskId}`);
    }

    if (task.status !== 'FAILED') {
      throw new Error(`Task ${taskId} is not in FAILED state`);
    }

    // 检查重试次数
    const maxRetries = 3;
    if ((task.retry_count || 0) >= maxRetries) {
      throw new Error(`Task ${taskId} has reached maximum retry limit`);
    }

    await this.updateTask(taskId, {
      status: 'READY_FOR_LISTING',
      error_message: '',
    });

    await this.executeListing(taskId);
  }

  /**
   * 批量执行刊登任务
   */
  async batchExecuteTasks(taskIds: string[]): Promise<Array<{ taskId: string; success: boolean; error?: string }>> {
    const results = await Promise.all(
      taskIds.map(async (taskId) => {
        try {
          await this.executeListing(taskId);
          return { taskId, success: true };
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Unknown error';
          return { taskId, success: false, error: errorMessage };
        }
      })
    );

    return results;
  }

  /**
   * 获取任务详情
   */
  private async getTask(taskId: string): Promise<any> {
    return db(ProductListingService.TABLE_NAME).where('task_id', taskId).first();
  }

  /**
   * 更新任务
   */
  private async updateTask(
    taskId: string,
    updates: Partial<{
      status: ListingState;
      platform_product_id: string;
      error_message: string;
      retry_count: number;
    }>
  ): Promise<void> {
    await db(ProductListingService.TABLE_NAME).where('task_id', taskId).update({
      ...updates,
      updated_at: new Date().toISOString(),
    });
  }

  /**
   * 处理状态变更
   */
  private handleStateChange(
    taskId: string,
    newState: ListingState,
    context: ListingContext
  ): void {
    this.logOperation(
      taskId,
      context.tenantId,
      context.shopId,
      context.traceId,
      context.businessType,
      'STATE_CHANGED',
      { newState }
    );
  }

  /**
   * 记录操作日志
   */
  private logOperation(
    taskId: string,
    tenantId: string,
    shopId: string,
    traceId: string,
    businessType: 'TOC' | 'TOB',
    operation: string,
    details: any
  ): void {
    logger.info(`[ProductListingService] ${operation}`, {
      taskId,
      tenantId,
      shopId,
      traceId,
      businessType,
      operation,
      details,
    });
  }

  /**
   * 获取任务列表
   */
  async getTasks(
    tenantId: string,
    filters?: {
      status?: ListingState;
      platform?: string;
      platformType?: 'api' | 'no_api';
      limit?: number;
      offset?: number;
    }
  ): Promise<any[]> {
    let query = db(ProductListingService.TABLE_NAME).where('tenant_id', tenantId);

    if (filters?.status) {
      query = query.where('status', filters.status);
    }
    if (filters?.platform) {
      query = query.where('platform', filters.platform);
    }
    if (filters?.platformType) {
      query = query.where('platform_type', filters.platformType);
    }

    query = query.orderBy('created_at', 'desc');

    if (filters?.limit) {
      query = query.limit(filters.limit);
    }
    if (filters?.offset) {
      query = query.offset(filters.offset);
    }

    return query.select('*');
  }

  /**
   * 取消刊登任务
   */
  async cancelTask(taskId: string): Promise<void> {
    const task = await this.getTask(taskId);
    if (!task) {
      throw new Error(`Task not found: ${taskId}`);
    }

    // 只有在 READY_FOR_LISTING 或 LISTING_IN_PROGRESS 状态可以取消
    if (task.status !== 'READY_FOR_LISTING' && task.status !== 'LISTING_IN_PROGRESS') {
      throw new Error(`Task ${taskId} cannot be cancelled in current status: ${task.status}`);
    }

    await this.updateTask(taskId, {
      status: 'FAILED',
      error_message: 'Task cancelled by user',
    });
  }

  /**
   * 获取平台状态
   */
  async getPlatformStatus(
    platform: string,
    platformProductId: string
  ): Promise<{ status: string; error?: string }> {
    const connector = this.connectors.get(platform.toLowerCase());
    if (!connector) {
      return { status: 'UNKNOWN', error: `No connector found for platform: ${platform}` };
    }

    return connector.getStatus(platformProductId);
  }
}
