import { Injectable, Logger } from '@nestjs/common';

/**
 * PII (Personally Identifiable Information) 脱敏服务
 * 
 * 检测并脱敏用户输入中的敏感信息
 */
@Injectable()
export class PIIService {
  private readonly logger = new Logger(PIIService.name);

  /**
   * 敏感信息检测规则
   */
  private readonly patterns = [
    {
      name: 'idCard',
      label: '身份证号',
      // 18位身份证号 或 15位旧版身份证号
      regex: /(?<!\d)([1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dXx]|[1-9]\d{5}\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3})(?!\d)/g,
      mask: '[身份证已隐藏]',
    },
    {
      name: 'phone',
      label: '手机号',
      // 中国大陆手机号
      regex: /(?<!\d)(1[3-9]\d{9})(?!\d)/g,
      mask: '[手机号已隐藏]',
    },
    {
      name: 'bankCard',
      label: '银行卡号',
      // 16-19位银行卡号
      regex: /(?<!\d)([3-6]\d{15,18})(?!\d)/g,
      mask: '[银行卡已隐藏]',
    },
    {
      name: 'email',
      label: '邮箱地址',
      // 邮箱检测（仅警告，不脱敏）
      regex: /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/g,
      mask: null, // null 表示仅警告不脱敏
      warnOnly: true,
    },
  ];

  /**
   * 检测并脱敏敏感信息
   * 
   * @param content 原始内容
   * @returns 脱敏结果
   */
  sanitize(content: string): PIISanitizeResult {
    let sanitized = content;
    const detected: PIIDetection[] = [];
    const warnings: string[] = [];

    for (const pattern of this.patterns) {
      // 重置正则表达式状态
      pattern.regex.lastIndex = 0;
      
      const matches = content.match(pattern.regex);
      
      if (matches && matches.length > 0) {
        if (pattern.warnOnly) {
          // 仅警告不脱敏
          warnings.push(`检测到 ${pattern.label}，请注意信息安全`);
          detected.push({
            type: pattern.name,
            label: pattern.label,
            count: matches.length,
            sanitized: false,
          });
        } else if (pattern.mask) {
          // 执行脱敏
          sanitized = sanitized.replace(pattern.regex, pattern.mask);
          detected.push({
            type: pattern.name,
            label: pattern.label,
            count: matches.length,
            sanitized: true,
          });
          
          this.logger.warn(
            `PII 检测: 发现 ${matches.length} 个 ${pattern.label}，已脱敏`,
          );
        }
      }
    }

    return {
      original: content,
      sanitized,
      detected,
      warnings,
      hasSensitiveInfo: detected.length > 0,
      wasSanitized: detected.some((d) => d.sanitized),
    };
  }

  /**
   * 仅检测是否包含敏感信息（不脱敏）
   */
  detect(content: string): PIIDetection[] {
    const detected: PIIDetection[] = [];

    for (const pattern of this.patterns) {
      pattern.regex.lastIndex = 0;
      const matches = content.match(pattern.regex);
      
      if (matches && matches.length > 0) {
        detected.push({
          type: pattern.name,
          label: pattern.label,
          count: matches.length,
          sanitized: false,
        });
      }
    }

    return detected;
  }

  /**
   * 检查是否需要脱敏（排除仅警告的类型）
   */
  needsSanitization(content: string): boolean {
    for (const pattern of this.patterns) {
      if (pattern.warnOnly) continue;
      
      pattern.regex.lastIndex = 0;
      if (pattern.regex.test(content)) {
        return true;
      }
    }
    return false;
  }
}

/**
 * PII 检测结果
 */
export interface PIIDetection {
  type: string;
  label: string;
  count: number;
  sanitized: boolean;
}

/**
 * PII 脱敏结果
 */
export interface PIISanitizeResult {
  original: string;
  sanitized: string;
  detected: PIIDetection[];
  warnings: string[];
  hasSensitiveInfo: boolean;
  wasSanitized: boolean;
}
