import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import {
  ISystemConfigRepository,
  SystemConfigEntity,
} from '../../../domain/repositories/system-config.repository';

@Injectable()
export class SystemConfigRepositoryImpl implements ISystemConfigRepository {
  constructor(private readonly prisma: PrismaService) {}

  async findByKey(key: string): Promise<SystemConfigEntity | null> {
    const config = await this.prisma.systemConfig.findUnique({
      where: { key },
    });

    return config;
  }

  async findByKeys(keys: string[]): Promise<SystemConfigEntity[]> {
    const configs = await this.prisma.systemConfig.findMany({
      where: { key: { in: keys } },
    });

    return configs;
  }

  async findAll(): Promise<SystemConfigEntity[]> {
    const configs = await this.prisma.systemConfig.findMany({
      orderBy: { key: 'asc' },
    });

    return configs;
  }

  async upsert(
    key: string,
    value: string,
    description?: string,
    updatedBy?: string,
  ): Promise<SystemConfigEntity> {
    const config = await this.prisma.systemConfig.upsert({
      where: { key },
      create: {
        key,
        value,
        description,
        updatedBy,
      },
      update: {
        value,
        description,
        updatedBy,
      },
    });

    return config;
  }

  async batchUpsert(
    configs: Array<{
      key: string;
      value: string;
      description?: string;
    }>,
    updatedBy?: string,
  ): Promise<SystemConfigEntity[]> {
    const results: SystemConfigEntity[] = [];

    // 使用事务确保批量操作的原子性
    await this.prisma.$transaction(async (tx) => {
      for (const config of configs) {
        const result = await tx.systemConfig.upsert({
          where: { key: config.key },
          create: {
            key: config.key,
            value: config.value,
            description: config.description,
            updatedBy,
          },
          update: {
            value: config.value,
            description: config.description,
            updatedBy,
          },
        });
        results.push(result);
      }
    });

    return results;
  }

  async delete(key: string): Promise<void> {
    await this.prisma.systemConfig.delete({
      where: { key },
    });
  }
}
