import { Injectable, Logger, NotFoundException, ConflictException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { SystemSecret } from '@/entities/system-secret.entity';
import { encrypt, decrypt, maskValue } from '@/common/utils/crypto.util';

@Injectable()
export class SecretService {
  private readonly logger = new Logger(SecretService.name);

  constructor(
    @InjectRepository(SystemSecret)
    private readonly secretRepo: Repository<SystemSecret>,
  ) {}

  /**
   * 获取所有密钥列表（脱敏）
   */
  async findAll(query?: { groupName?: string; env?: string }) {
    const where: any = {};
    if (query?.groupName) where.groupName = query.groupName;
    if (query?.env) where.env = query.env;

    const secrets = await this.secretRepo.find({ where, order: { groupName: 'ASC', secretKey: 'ASC' } });
    return secrets.map(s => ({
      id: s.id,
      secretKey: s.secretKey,
      maskedValue: maskValue(decrypt(s.secretValue)),
      description: s.description,
      groupName: s.groupName,
      env: s.env,
      createdAt: s.createdAt,
      updatedAt: s.updatedAt,
    }));
  }

  /**
   * 获取单个密钥详情（脱敏）
   */
  async findOne(id: number) {
    const secret = await this.secretRepo.findOne({ where: { id } });
    if (!secret) throw new NotFoundException('密钥不存在');
    return {
      id: secret.id,
      secretKey: secret.secretKey,
      maskedValue: maskValue(decrypt(secret.secretValue)),
      description: secret.description,
      groupName: secret.groupName,
      env: secret.env,
      createdAt: secret.createdAt,
      updatedAt: secret.updatedAt,
    };
  }

  /**
   * 获取解密后的密钥值（供其他服务调用）
   */
  async getDecryptedValue(secretKey: string, env: string = 'all'): Promise<string | null> {
    const secret = await this.secretRepo.findOne({
      where: [
        { secretKey, env: 'all' },
        { secretKey, env },
      ],
    });
    if (!secret) return null;
    return decrypt(secret.secretValue);
  }

  /**
   * 创建密钥
   */
  async create(data: { secretKey: string; secretValue: string; description?: string; groupName?: string; env?: string }) {
    // 检查是否已存在
    const existing = await this.secretRepo.findOne({
      where: { secretKey: data.secretKey, env: (data.env as any) || 'all' },
    });
    if (existing) throw new ConflictException(`密钥 ${data.secretKey} 已存在`);

    const secret = this.secretRepo.create({
      secretKey: data.secretKey,
      secretValue: encrypt(data.secretValue),
      description: data.description,
      groupName: data.groupName || 'default',
      env: data.env || 'all',
    });
    return this.secretRepo.save(secret);
  }

  /**
   * 更新密钥
   */
  async update(id: number, data: { secretValue?: string; description?: string; groupName?: string; env?: string }) {
    const secret = await this.secretRepo.findOne({ where: { id } });
    if (!secret) throw new NotFoundException('密钥不存在');

    if (data.secretValue !== undefined) {
      secret.secretValue = encrypt(data.secretValue);
    }
    if (data.description !== undefined) secret.description = data.description;
    if (data.groupName !== undefined) secret.groupName = data.groupName;
    if (data.env !== undefined) secret.env = data.env as any;

    return this.secretRepo.save(secret);
  }

  /**
   * 删除密钥
   */
  async remove(id: number) {
    const secret = await this.secretRepo.findOne({ where: { id } });
    if (!secret) throw new NotFoundException('密钥不存在');
    await this.secretRepo.remove(secret);
  }

  /**
   * 获取所有分组
   */
  async getGroups() {
    const result = await this.secretRepo
      .createQueryBuilder('s')
      .select('DISTINCT s.groupName', 'groupName')
      .getRawMany();
    return result.map(r => r.groupName);
  }
}
