/**
 * [BE-AILOG-001] AI决策日志服务
 * 负责记录、存储、查询AI决策全链路日志
 * AI注意: 所有AI决策操作必须通过此服务记录日志
 */

import db from '../config/database';
import { logger } from '../utils/logger';
import { EventBusService } from './EventBusService';
import { RedisService } from './RedisService';

// 决策类型
export type DecisionType = 
  | 'PRICING'      // 定价决策
  | 'INVENTORY'    // 库存决策
  | 'AD_OPTIMIZE'  // 广告优化
  | 'PRODUCT_SELECT' // 选品决策
  | 'LOGISTICS'    // 物流决策
  | 'RISK_CONTROL' // 风控决策
  | 'CUSTOMER_SERVICE' // 客服决策
  | 'SETTLEMENT'   // 结算决策
  | 'OTHER';       // 其他

// 决策状态
export type DecisionStatus = 
  | 'PENDING'      // 待执行
  | 'EXECUTING'    // 执行中
  | 'SUCCESS'      // 成功
  | 'FAILED'       // 失败
  | 'REJECTED'     // 被拒绝
  | 'ROLLED_BACK'; // 已回滚

// 决策日志实体
export interface AIDecisionLog {
  id: string;
  tenant_id: string;
  shop_id: string;
  task_id: string;
  trace_id: string;
  decision_type: DecisionType;
  business_type: 'TOC' | 'TOB';
  status: DecisionStatus;
  
  // 决策输入
  input_data: {
    context: Record<string, any>;
    parameters: Record<string, any>;
    constraints: Record<string, any>;
  };
  
  // 决策输出
  output_data: {
    decision: string;
    confidence: number;
    reasoning: string;
    alternatives: Array<{
      option: string;
      score: number;
    }>;
    expected_result: Record<string, any>;
  };
  
  // 执行结果
  execution_result?: {
    success: boolean;
    actual_result: Record<string, any>;
    deviation: number;
    execution_time: number;
    error_message?: string;
  };
  
  // 人工干预
  human_intervention?: {
    operator_id: string;
    operator_name: string;
    action: 'APPROVE' | 'REJECT' | 'MODIFY' | 'ROLLBACK';
    comment: string;
    timestamp: Date;
  };
  
  // 时间戳
  created_at: Date;
  updated_at: Date;
  executed_at?: Date;
  completed_at?: Date;
}

// 查询参数
export interface DecisionLogQueryParams {
  tenant_id?: string;
  shop_id?: string;
  decision_type?: DecisionType;
  status?: DecisionStatus;
  business_type?: 'TOC' | 'TOB';
  start_time?: Date;
  end_time?: Date;
  trace_id?: string;
  task_id?: string;
  page?: number;
  pageSize?: number;
}

// 统计结果
export interface DecisionStatistics {
  total_count: number;
  success_count: number;
  failed_count: number;
  rejected_count: number;
  success_rate: number;
  avg_execution_time: number;
  by_type: Record<DecisionType, {
    count: number;
    success_rate: number;
  }>;
  by_day: Array<{
    date: string;
    count: number;
    success_count: number;
  }>;
}

export class AIDecisionLogService {
  private static readonly TABLE_NAME = 'cf_ai_decision_logs';
  private static readonly CACHE_PREFIX = 'ai_decision_log:';
  private static readonly CACHE_TTL = 3600; // 1小时

  /**
   * [BE-AILOG-002] 初始化数据库表
   */
  static async initTables() {
    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.string('id', 50).primary();
        table.string('tenant_id', 50).notNullable().index();
        table.string('shop_id', 50).notNullable().index();
        table.string('task_id', 50).notNullable().index();
        table.string('trace_id', 100).notNullable().index();
        table.enum('decision_type', [
          'PRICING', 'INVENTORY', 'AD_OPTIMIZE', 'PRODUCT_SELECT',
          'LOGISTICS', 'RISK_CONTROL', 'CUSTOMER_SERVICE', 'SETTLEMENT', 'OTHER'
        ]).notNullable().index();
        table.enum('business_type', ['TOC', 'TOB']).notNullable();
        table.enum('status', [
          'PENDING', 'EXECUTING', 'SUCCESS', 'FAILED', 'REJECTED', 'ROLLED_BACK'
        ]).notNullable().index();
        
        // JSON字段存储复杂数据
        table.json('input_data').notNullable();
        table.json('output_data').notNullable();
        table.json('execution_result').nullable();
        table.json('human_intervention').nullable();
        
        // 时间戳
        table.timestamp('created_at').notNullable().defaultTo(db.fn.now());
        table.timestamp('updated_at').notNullable().defaultTo(db.fn.now());
        table.timestamp('executed_at').nullable();
        table.timestamp('completed_at').nullable();
        
        // 复合索引
        table.index(['tenant_id', 'created_at']);
        table.index(['decision_type', 'status']);
        table.index(['trace_id', 'created_at']);
      });
      logger.info(`${this.TABLE_NAME} table created successfully`);
    }
  }

  /**
   * [BE-AILOG-003] 创建决策日志
   */
  static async createLog(
    tenantId: string,
    shopId: string,
    taskId: string,
    traceId: string,
    decisionType: DecisionType,
    businessType: 'TOC' | 'TOB',
    inputData: AIDecisionLog['input_data'],
    outputData: AIDecisionLog['output_data']
  ): Promise<AIDecisionLog> {
    const id = `ADL-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    
    const log: AIDecisionLog = {
      id,
      tenant_id: tenantId,
      shop_id: shopId,
      task_id: taskId,
      trace_id: traceId,
      decision_type: decisionType,
      business_type: businessType,
      status: 'PENDING',
      input_data: inputData,
      output_data: outputData,
      created_at: new Date(),
      updated_at: new Date(),
    };

    await db(this.TABLE_NAME).insert({
      ...log,
      input_data: JSON.stringify(inputData),
      output_data: JSON.stringify(outputData),
    });

    // 发布事件
    await EventBusService.publish('ai.decision.created', {
      logId: id,
      tenantId,
      shopId,
      decisionType,
      status: 'PENDING',
      timestamp: new Date(),
    });

    logger.info(`[AIDecisionLog] Created log ${id} for ${decisionType}`);
    return log;
  }

  /**
   * [BE-AILOG-004] 更新决策执行状态
   */
  static async updateExecutionStatus(
    logId: string,
    status: DecisionStatus,
    executionResult?: AIDecisionLog['execution_result']
  ): Promise<void> {
    const updateData: any = {
      status,
      updated_at: new Date(),
    };

    if (status === 'EXECUTING') {
      updateData.executed_at = new Date();
    }

    if (status === 'SUCCESS' || status === 'FAILED' || status === 'REJECTED') {
      updateData.completed_at = new Date();
    }

    if (executionResult) {
      updateData.execution_result = JSON.stringify(executionResult);
    }

    await db(this.TABLE_NAME)
      .where('id', logId)
      .update(updateData);

    // 清除缓存
    await RedisService.del(`${this.CACHE_PREFIX}${logId}`);

    // 发布状态变更事件
    await EventBusService.publish('ai.decision.status_changed', {
      logId,
      status,
      timestamp: new Date(),
    });

    logger.info(`[AIDecisionLog] Updated log ${logId} status to ${status}`);
  }

  /**
   * [BE-AILOG-005] 记录人工干预
   */
  static async recordHumanIntervention(
    logId: string,
    operatorId: string,
    operatorName: string,
    action: 'APPROVE' | 'REJECT' | 'MODIFY' | 'ROLLBACK',
    comment: string
  ): Promise<void> {
    const intervention = {
      operator_id: operatorId,
      operator_name: operatorName,
      action,
      comment,
      timestamp: new Date(),
    };

    await db(this.TABLE_NAME)
      .where('id', logId)
      .update({
        human_intervention: JSON.stringify(intervention),
        updated_at: new Date(),
      });

    // 清除缓存
    await RedisService.del(`${this.CACHE_PREFIX}${logId}`);

    logger.info(`[AIDecisionLog] Recorded human intervention for ${logId}: ${action}`);
  }

  /**
   * [BE-AILOG-006] 查询决策日志列表
   */
  static async queryLogs(params: DecisionLogQueryParams): Promise<{
    list: AIDecisionLog[];
    total: number;
    page: number;
    pageSize: number;
  }> {
    const {
      tenant_id,
      shop_id,
      decision_type,
      status,
      business_type,
      start_time,
      end_time,
      trace_id,
      task_id,
      page = 1,
      pageSize = 20,
    } = params;

    let query = db(this.TABLE_NAME);

    if (tenant_id) {
      query = query.where('tenant_id', tenant_id);
    }
    if (shop_id) {
      query = query.where('shop_id', shop_id);
    }
    if (decision_type) {
      query = query.where('decision_type', decision_type);
    }
    if (status) {
      query = query.where('status', status);
    }
    if (business_type) {
      query = query.where('business_type', business_type);
    }
    if (trace_id) {
      query = query.where('trace_id', trace_id);
    }
    if (task_id) {
      query = query.where('task_id', task_id);
    }
    if (start_time) {
      query = query.where('created_at', '>=', start_time);
    }
    if (end_time) {
      query = query.where('created_at', '<=', end_time);
    }

    // 获取总数
    const countResult = await query.clone().count('id as count').first();
    const total = parseInt(countResult?.count as string, 10) || 0;

    // 获取列表
    const list = await query
      .orderBy('created_at', 'desc')
      .offset((page - 1) * pageSize)
      .limit(pageSize);

    return {
      list: list.map(this.parseLogRecord),
      total,
      page,
      pageSize,
    };
  }

  /**
   * [BE-AILOG-007] 获取决策日志详情
   */
  static async getLogById(logId: string): Promise<AIDecisionLog | null> {
    // 尝试从缓存获取
    const cached = await RedisService.get(`${this.CACHE_PREFIX}${logId}`);
    if (cached) {
      return JSON.parse(cached);
    }

    const record = await db(this.TABLE_NAME)
      .where('id', logId)
      .first();

    if (!record) {
      return null;
    }

    const log = this.parseLogRecord(record);

    // 缓存结果
    await RedisService.setex(
      `${this.CACHE_PREFIX}${logId}`,
      this.CACHE_TTL,
      JSON.stringify(log)
    );

    return log;
  }

  /**
   * [BE-AILOG-008] 获取决策统计
   */
  static async getStatistics(
    tenantId: string,
    shopId?: string,
    startTime?: Date,
    endTime?: Date
  ): Promise<DecisionStatistics> {
    let query = db(this.TABLE_NAME)
      .where('tenant_id', tenantId);

    if (shopId) {
      query = query.where('shop_id', shopId);
    }
    if (startTime) {
      query = query.where('created_at', '>=', startTime);
    }
    if (endTime) {
      query = query.where('created_at', '<=', endTime);
    }

    const records = await query;

    const total_count = records.length;
    const success_count = records.filter(r => r.status === 'SUCCESS').length;
    const failed_count = records.filter(r => r.status === 'FAILED').length;
    const rejected_count = records.filter(r => r.status === 'REJECTED').length;

    // 按类型统计
    const by_type: DecisionStatistics['by_type'] = {} as any;
    const typeGroups = this.groupBy(records, 'decision_type');
    for (const [type, items] of Object.entries(typeGroups)) {
      const typeRecords = items as any[];
      const typeSuccess = typeRecords.filter(r => r.status === 'SUCCESS').length;
      by_type[type as DecisionType] = {
        count: typeRecords.length,
        success_rate: typeRecords.length > 0 
          ? Math.round((typeSuccess / typeRecords.length) * 100) 
          : 0,
      };
    }

    // 按天统计
    const byDayGroups = this.groupBy(records, (r: any) => 
      new Date(r.created_at).toISOString().split('T')[0]
    );
    const by_day = Object.entries(byDayGroups)
      .map(([date, items]) => ({
        date,
        count: (items as any[]).length,
        success_count: (items as any[]).filter((r: any) => r.status === 'SUCCESS').length,
      }))
      .sort((a, b) => a.date.localeCompare(b.date));

    // 计算平均执行时间
    const executionTimes = records
      .filter(r => r.execution_result)
      .map(r => JSON.parse(r.execution_result).execution_time || 0);
    const avg_execution_time = executionTimes.length > 0
      ? executionTimes.reduce((a, b) => a + b, 0) / executionTimes.length
      : 0;

    return {
      total_count,
      success_count,
      failed_count,
      rejected_count,
      success_rate: total_count > 0 ? Math.round((success_count / total_count) * 100) : 0,
      avg_execution_time: Math.round(avg_execution_time * 100) / 100,
      by_type,
      by_day,
    };
  }

  /**
   * [BE-AILOG-009] 获取决策链路（通过trace_id）
   */
  static async getDecisionChain(traceId: string): Promise<AIDecisionLog[]> {
    const records = await db(this.TABLE_NAME)
      .where('trace_id', traceId)
      .orderBy('created_at', 'asc');

    return records.map(this.parseLogRecord);
  }

  /**
   * 解析数据库记录
   */
  private static parseLogRecord(record: any): AIDecisionLog {
    return {
      ...record,
      input_data: typeof record.input_data === 'string' 
        ? JSON.parse(record.input_data) 
        : record.input_data,
      output_data: typeof record.output_data === 'string' 
        ? JSON.parse(record.output_data) 
        : record.output_data,
      execution_result: record.execution_result 
        ? (typeof record.execution_result === 'string' 
          ? JSON.parse(record.execution_result) 
          : record.execution_result)
        : undefined,
      human_intervention: record.human_intervention 
        ? (typeof record.human_intervention === 'string' 
          ? JSON.parse(record.human_intervention) 
          : record.human_intervention)
        : undefined,
    };
  }

  /**
   * 分组辅助函数
   */
  private static groupBy<T>(array: T[], key: keyof T | ((item: T) => string)): Record<string, T[]> {
    return array.reduce((result, item) => {
      const groupKey = typeof key === 'function' ? key(item) : String(item[key]);
      result[groupKey] = result[groupKey] || [];
      result[groupKey].push(item);
      return result;
    }, {} as Record<string, T[]>);
  }
}
