import db from '../config/database';
import { v4 as uuidv4 } from 'uuid';

export interface ComplianceRule {
  id: string;
  tenantId: string;
  platform: string;
  ruleName: string;
  ruleType: 'PRODUCT' | 'AD' | 'ORDER' | 'DATA' | 'OTHER';
  severity: 'LOW' | 'MEDIUM' | 'HIGH';
  description: string;
  ruleExpression: string;
  action: 'BLOCK' | 'WARNING' | 'MONITOR';
  status: 'ACTIVE' | 'INACTIVE' | 'DEPRECATED';
  createdAt: Date;
  updatedAt: Date;
  effectiveDate: Date;
  expirationDate?: Date;
}

export interface ComplianceRuleViolation {
  id: string;
  tenantId: string;
  shopId: string;
  ruleId: string;
  violationType: string;
  targetId: string; // 商品ID、广告ID等
  violationDetails: string;
  status: 'PENDING' | 'RESOLVED' | 'IGNORED';
  resolvedAt?: Date;
  createdAt: Date;
  updatedAt: Date;
}

export interface ComplianceRuleAudit {
  id: string;
  tenantId: string;
  ruleId: string;
  action: 'CREATED' | 'UPDATED' | 'DELETED' | 'ENABLED' | 'DISABLED';
  performedBy: string;
  details: string;
  createdAt: Date;
}

export class ComplianceRuleModel {
  private static readonly TABLE_RULE = 'cf_compliance_rules';
  private static readonly TABLE_VIOLATION = 'cf_compliance_rule_violations';
  private static readonly TABLE_AUDIT = 'cf_compliance_rule_audits';

  // ==================== 规则管理 ====================

  static async createRule(ruleData: Partial<ComplianceRule>): Promise<ComplianceRule> {
    const id = uuidv4();
    await db(this.TABLE_RULE).insert({
      id,
      ...ruleData,
      created_at: new Date(),
      updated_at: new Date()
    });
    return (await this.getRuleById(id))!;
  }

  static async getRuleById(id: string): Promise<ComplianceRule | null> {
    return await db(this.TABLE_RULE).where({ id }).first();
  }

  static async getRulesByPlatform(platform: string): Promise<ComplianceRule[]> {
    return await db(this.TABLE_RULE)
      .where({ platform })
      .where({ status: 'ACTIVE' })
      .orderBy('severity', 'desc');
  }

  static async getRulesByType(ruleType: string): Promise<ComplianceRule[]> {
    return await db(this.TABLE_RULE)
      .where({ ruleType })
      .where({ status: 'ACTIVE' })
      .orderBy('severity', 'desc');
  }

  static async updateRule(id: string, ruleData: Partial<ComplianceRule>): Promise<ComplianceRule | null> {
    await db(this.TABLE_RULE).where({ id }).update({
      ...ruleData,
      updated_at: new Date()
    });
    return await this.getRuleById(id);
  }

  static async deleteRule(id: string): Promise<boolean> {
    const result = await db(this.TABLE_RULE).where({ id }).delete();
    return result > 0;
  }

  static async enableRule(id: string): Promise<ComplianceRule | null> {
    return await this.updateRule(id, { status: 'ACTIVE' });
  }

  static async disableRule(id: string): Promise<ComplianceRule | null> {
    return await this.updateRule(id, { status: 'INACTIVE' });
  }

  // ==================== 违规管理 ====================

  static async createViolation(violationData: Partial<ComplianceRuleViolation>): Promise<ComplianceRuleViolation> {
    const id = uuidv4();
    await db(this.TABLE_VIOLATION).insert({
      id,
      ...violationData,
      created_at: new Date(),
      updated_at: new Date()
    });
    return (await this.getViolationById(id))!;
  }

  static async getViolationById(id: string): Promise<ComplianceRuleViolation | null> {
    return await db(this.TABLE_VIOLATION).where({ id }).first();
  }

  static async getViolationsByShop(shopId: string, status?: 'PENDING' | 'RESOLVED' | 'IGNORED'): Promise<ComplianceRuleViolation[]> {
    let query = db(this.TABLE_VIOLATION).where({ shopId });
    if (status) {
      query = query.where({ status });
    }
    return await query.orderBy('createdAt', 'desc');
  }

  static async getViolationsByRule(ruleId: string): Promise<ComplianceRuleViolation[]> {
    return await db(this.TABLE_VIOLATION)
      .where({ ruleId })
      .orderBy('createdAt', 'desc');
  }

  static async resolveViolation(id: string): Promise<ComplianceRuleViolation | null> {
    await db(this.TABLE_VIOLATION).where({ id }).update({
      status: 'RESOLVED',
      resolvedAt: new Date(),
      updated_at: new Date()
    });
    return await this.getViolationById(id);
  }

  static async ignoreViolation(id: string): Promise<ComplianceRuleViolation | null> {
    await db(this.TABLE_VIOLATION).where({ id }).update({
      status: 'IGNORED',
      updated_at: new Date()
    });
    return await this.getViolationById(id);
  }

  // ==================== 审计管理 ====================

  static async createAudit(auditData: Partial<ComplianceRuleAudit>): Promise<ComplianceRuleAudit> {
    const id = uuidv4();
    await db(this.TABLE_AUDIT).insert({
      id,
      ...auditData,
      created_at: new Date()
    });
    return (await this.getAuditById(id))!;
  }

  static async getAuditById(id: string): Promise<ComplianceRuleAudit | null> {
    return await db(this.TABLE_AUDIT).where({ id }).first();
  }

  static async getAuditsByRule(ruleId: string): Promise<ComplianceRuleAudit[]> {
    return await db(this.TABLE_AUDIT)
      .where({ ruleId })
      .orderBy('createdAt', 'desc');
  }

  static async getAuditsByTenant(tenantId: string): Promise<ComplianceRuleAudit[]> {
    return await db(this.TABLE_AUDIT)
      .where({ tenantId })
      .orderBy('createdAt', 'desc');
  }

  // ==================== 规则评估 ====================

  static async evaluateRule(ruleId: string, targetData: any): Promise<{ violated: boolean; details?: string }> {
    const rule = await this.getRuleById(ruleId);
    if (!rule || rule.status !== 'ACTIVE') {
      return { violated: false };
    }

    // 这里可以实现具体的规则评估逻辑
    // 例如：基于规则表达式评估目标数据
    // 简单的模拟评估
    let violated = false;
    let details = '';

    switch (rule.ruleType) {
      case 'PRODUCT':
        // 模拟商品合规检查
        if (targetData.title && targetData.title.includes('违规词')) {
          violated = true;
          details = '商品标题包含违规词';
        }
        break;
      case 'AD':
        // 模拟广告合规检查
        if (targetData.content && targetData.content.includes('虚假宣传')) {
          violated = true;
          details = '广告内容包含虚假宣传';
        }
        break;
      default:
        break;
    }

    return { violated, details };
  }
}
