import { Inject, Injectable } from '@nestjs/common';
import { Prisma, RoleResource } from '@prisma/client';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { PrismaService } from 'nestjs-prisma';
import { Logger } from 'winston';

import { ConfigService } from '@nestjs/config';
import { createSafeLogData } from '../../lib/safe-log.util';

@Injectable()
export class RoleResourceService {
  constructor(
    private prisma: PrismaService,
    private readonly config: ConfigService,
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
  ) {}

  async createOne(roleResourceCreateArgs: Prisma.RoleResourceCreateArgs) {
    this.logger.info(
      '[RoleResource] Creating role resource',
      createSafeLogData({
        operation: 'CREATE',
        table: 'roleResource',
        data: roleResourceCreateArgs.data,
      }),
    );
    const result = await this.prisma.roleResource.create(
      roleResourceCreateArgs,
    );
    this.logger.info(
      '[RoleResource] Role resource created successfully',
      createSafeLogData({
        operation: 'CREATE',
        table: 'roleResource',
        result: result,
      }),
    );
    return result;
  }

  async createMany(data: Prisma.RoleResourceCreateManyArgs['data']) {
    this.logger.info(
      '[RoleResource] Creating multiple role resources',
      createSafeLogData({
        operation: 'CREATE_MANY',
        table: 'roleResource',
        count: Array.isArray(data) ? data.length : 1,
        data: data,
      }),
    );
    const result = await this.prisma.roleResource.createMany({
      data,
      skipDuplicates: true,
    });
    this.logger.info(
      '[RoleResource] Multiple role resources created successfully',
      createSafeLogData({
        operation: 'CREATE_MANY',
        table: 'roleResource',
        count: result.count,
      }),
    );
    return result;
  }

  async findMany(
    roleResourceFindManyArgs: Prisma.RoleResourceFindManyArgs,
  ): Promise<{ itemCount: number; entities: RoleResource[] }> {
    const itemCount = await this.prisma.roleResource.count({
      where: roleResourceFindManyArgs.where,
    });
    const entities = await this.prisma.roleResource.findMany(
      roleResourceFindManyArgs,
    );
    return { itemCount, entities };
  }

  async findUnique(
    id: number,
    select: Prisma.RoleResourceFindUniqueArgs['select'],
  ) {
    return await this.prisma.roleResource.findUnique({
      where: { id: id },
      select,
    });
  }

  async updateMany(
    roleResourceUpdateManyArgs: Prisma.RoleResourceUpdateManyArgs,
  ) {
    this.logger.info(
      '[RoleResource] Updating multiple role resources',
      createSafeLogData({
        operation: 'UPDATE_MANY',
        table: 'roleResource',
        where: roleResourceUpdateManyArgs.where,
        data: roleResourceUpdateManyArgs.data,
      }),
    );
    const result = await this.prisma.roleResource.updateMany(
      roleResourceUpdateManyArgs,
    );
    this.logger.info(
      '[RoleResource] Multiple role resources updated successfully',
      createSafeLogData({
        operation: 'UPDATE_MANY',
        table: 'roleResource',
        count: result.count,
      }),
    );
    return result;
  }

  async updateUnique(
    id: number,
    data: Prisma.RoleResourceUpdateManyArgs['data'],
  ) {
    const oldData = await this.prisma.roleResource.findUnique({
      where: { id },
    });
    this.logger.info(
      '[RoleResource] Updating role resource',
      createSafeLogData({
        operation: 'UPDATE',
        table: 'roleResource',
        id: id,
        oldData: oldData,
        newData: data,
      }),
    );
    const result = await this.prisma.roleResource.update({
      where: { id: id },
      data,
    });
    this.logger.info(
      '[RoleResource] Role resource updated successfully',
      createSafeLogData({
        operation: 'UPDATE',
        table: 'roleResource',
        id: id,
        result: result,
      }),
    );
    return result;
  }

  async deleteMany(
    roleResourceDeleteManyArgs: Prisma.RoleResourceDeleteManyArgs,
  ) {
    const oldData = await this.prisma.roleResource.findMany({
      where: roleResourceDeleteManyArgs.where,
    });
    this.logger.info(
      '[RoleResource] Deleting multiple role resources',
      createSafeLogData({
        operation: 'DELETE_MANY',
        table: 'roleResource',
        where: roleResourceDeleteManyArgs.where,
        oldData: oldData,
      }),
    );
    const result = await this.prisma.roleResource.deleteMany(
      roleResourceDeleteManyArgs,
    );
    this.logger.info(
      '[RoleResource] Multiple role resources deleted successfully',
      createSafeLogData({
        operation: 'DELETE_MANY',
        table: 'roleResource',
        count: result.count,
      }),
    );
    return result;
  }

  async deleteUnique(id: number) {
    const oldData = await this.prisma.roleResource.findUnique({
      where: { id },
    });
    this.logger.info(
      '[RoleResource] Deleting role resource',
      createSafeLogData({
        operation: 'DELETE',
        table: 'roleResource',
        id: id,
        oldData: oldData,
      }),
    );
    await this.prisma.roleResource.delete({
      where: { id: id },
    });
    this.logger.info(
      '[RoleResource] Role resource deleted successfully',
      createSafeLogData({
        operation: 'DELETE',
        table: 'roleResource',
        id: id,
      }),
    );
    return { count: 1 };
  }

  async count(roleResourceCountArgs?: Prisma.RoleResourceCountArgs) {
    return await this.prisma.roleResource.count(roleResourceCountArgs);
  }

  async groupBy(roleResourceGroupByArgs: Prisma.RoleResourceGroupByArgs) {
    return await this.prisma.roleResource.groupBy(
      roleResourceGroupByArgs as any,
    );
  }

  async aggregate(roleResourceAggregateArgs: Prisma.RoleResourceAggregateArgs) {
    return await this.prisma.roleResource.aggregate(roleResourceAggregateArgs);
  }
}
