import { logger } from '../../../utils/logger';
import { AuditService } from '../../../services/AuditService';
import db from '../../../config/database';

export enum ApprovalStatus {
  PENDING = 'PENDING',
  APPROVED = 'APPROVED',
  REJECTED = 'REJECTED',
  EXPIRED = 'EXPIRED'
}

export interface ApprovalRequest {
  id: string;
  tenantId: string;
  requesterId: string;
  type: 'CREDENTIAL_RESET' | 'CREDENTIAL_EXPORT' | 'SYSTEM_CONFIG_CHANGE' | 'HIGH_VALUE_ORDER' | 'PRICE_CHANGE' | 'REFUND';
  resourceId: string;
  metadata: any;
  status: ApprovalStatus;
  currentStage: number;
  totalStages: number;
  approverId?: string;
  reason?: string;
  createdAt: Date;
  expiresAt: Date;
}

/**
 * [CORE_SEC_02] 授权审批服务 (Approval Service)
 * [ERP_APPROVE_01] 通用审批流引擎 (Approval Engine)
 * @description 管理高风险操作的多级审批流与规则引擎
 */
export class ApprovalService {
  private static readonly TABLE_NAME = 'cf_approval_requests';

  /**
   * [ERP_APPROVE_01] 发起多级审批请求
   */
  static async requestApproval(params: Omit<ApprovalRequest, 'id' | 'status' | 'createdAt' | 'expiresAt' | 'currentStage' | 'totalStages'>): Promise<string> {
    const id = `APPV-${Date.now()}`;
    
    // 规则引擎：根据类型与金额设定审批层级
    let totalStages = 1;
    const metadata = params.metadata || {};
    if (params.type === 'HIGH_VALUE_ORDER' || (metadata.amount && metadata.amount > 5000)) {
      totalStages = 2; // 大额订单需两级审批 (MANAGER -> FINANCE)
    }

    const request: ApprovalRequest = {
      ...params,
      id,
      status: ApprovalStatus.PENDING,
      currentStage: 1,
      totalStages,
      createdAt: new Date(),
      expiresAt: new Date(Date.now() + 48 * 3600 * 1000) // 48小时有效
    };

    logger.info(`[Approval] New ${totalStages}-stage request ${id} for ${params.type}`);
    
    await db(this.TABLE_NAME).insert({
      id: request.id,
      tenant_id: request.tenantId,
      requester_id: request.requesterId,
      type: request.type,
      resource_id: request.resourceId,
      metadata: JSON.stringify(request.metadata),
      status: request.status,
      current_stage: request.currentStage,
      total_stages: request.totalStages,
      created_at: request.createdAt,
      expires_at: request.expiresAt
    });

    return id;
  }

  /**
   * [ERP_APPROVE_01] 执行审批 (支持多级流转)
   */
  static async approve(requestId: string, approverId: string, decision: 'APPROVE' | 'REJECT', reason?: string): Promise<void> {
    logger.info(`[Approval] Deciding request ${requestId}: ${decision} by ${approverId}`);

    const request = await db(this.TABLE_NAME).where({ id: requestId }).first();
    if (!request) throw new Error('Approval request not found');

    if (decision === 'REJECT') {
      await db(this.TABLE_NAME).where({ id: requestId }).update({
        status: ApprovalStatus.REJECTED,
        approver_id: approverId,
        reason,
        updated_at: new Date()
      });
      return;
    }

    // 如果是批准，检查是否需要进入下一级
    if (request.current_stage < request.total_stages) {
      await db(this.TABLE_NAME).where({ id: requestId }).update({
        current_stage: request.current_stage + 1,
        approver_id: approverId, // 记录当前审批人
        updated_at: new Date()
      });
      logger.info(`[Approval] Request ${requestId} moved to stage ${request.current_stage + 1}`);
    } else {
      await db(this.TABLE_NAME).where({ id: requestId }).update({
        status: ApprovalStatus.APPROVED,
        approver_id: approverId,
        reason,
        updated_at: new Date()
      });
    }

    // 记录审计日志
    await AuditService.log({
      tenantId: request.tenant_id,
      traceId: `APPV-${Date.now()}`,
      userId: approverId,
      module: 'SECURITY',
      action: decision,
      resourceType: 'approval_request',
      resourceId: requestId,
      result: 'success',
      metadata: { reason, stage: request.current_stage },
      source: 'console'
    });
  }

  /**
   * 初始化表
   */
  static async initTable() {
    const exists = await db.schema.hasTable(this.TABLE_NAME);
    if (!exists) {
      logger.info(`📦 Creating ${this.TABLE_NAME} table...`);
      await db.schema.createTable(this.TABLE_NAME, (table) => {
        table.string('id', 64).primary();
        table.string('tenant_id', 64).notNullable();
        table.string('requester_id', 64).notNullable();
        table.string('type', 64).notNullable();
        table.string('resource_id', 64).notNullable();
        table.json('metadata');
        table.string('status', 16).defaultTo('PENDING');
        table.integer('current_stage').defaultTo(1);
        table.integer('total_stages').defaultTo(1);
        table.string('approver_id', 64);
        table.string('reason', 255);
        table.timestamp('expires_at');
        table.timestamps(true, true);

        table.index(['tenant_id', 'status']);
      });
      logger.info(`✅ Table ${this.TABLE_NAME} created`);
    } else {
      // 增量字段校验
      const hasCurrentStage = await db.schema.hasColumn(this.TABLE_NAME, 'current_stage');
      if (!hasCurrentStage) {
        await db.schema.alterTable(this.TABLE_NAME, (table) => {
          table.integer('current_stage').defaultTo(1).after('status');
          table.integer('total_stages').defaultTo(1).after('current_stage');
        });
      }
    }
  }
}
