import { Inject, Injectable } from '@nestjs/common';
import { PageResource, Prisma } 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';

import { RoleService } from '../role/role.service';

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

  async createOne(pageResourceCreateArgs: Prisma.PageResourceCreateArgs) {
    this.logger.info(
      '[PageResource] Creating page resource',
      createSafeLogData({
        operation: 'CREATE',
        table: 'pageResource',
        data: pageResourceCreateArgs.data,
      }),
    );
    const result = await this.prisma.pageResource.create(
      pageResourceCreateArgs,
    );
    this.logger.info(
      '[PageResource] Page resource created successfully',
      createSafeLogData({
        operation: 'CREATE',
        table: 'pageResource',
        result: result,
      }),
    );
    return result;
  }

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

  async findMany(
    pageResourceFindManyArgs: Prisma.PageResourceFindManyArgs,
  ): Promise<{ itemCount: number; entities: PageResource[] }> {
    const itemCount = await this.prisma.pageResource.count({
      where: pageResourceFindManyArgs.where,
    });
    const entities = await this.prisma.pageResource.findMany(
      pageResourceFindManyArgs,
    );
    return { itemCount, entities };
  }

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

  async updateMany(
    pageResourceUpdateManyArgs: Prisma.PageResourceUpdateManyArgs,
  ) {
    this.logger.info(
      '[PageResource] Updating multiple page resources',
      createSafeLogData({
        operation: 'UPDATE_MANY',
        table: 'pageResource',
        where: pageResourceUpdateManyArgs.where,
        data: pageResourceUpdateManyArgs.data,
      }),
    );
    const result = await this.prisma.pageResource.updateMany(
      pageResourceUpdateManyArgs,
    );
    this.logger.info(
      '[PageResource] Multiple page resources updated successfully',
      createSafeLogData({
        operation: 'UPDATE_MANY',
        table: 'pageResource',
        count: result.count,
      }),
    );
    return result;
  }

  async updateUnique(
    id: number,
    data: Prisma.PageResourceUpdateManyArgs['data'],
  ) {
    const oldData = await this.prisma.pageResource.findUnique({
      where: { id },
    });
    this.logger.info(
      '[PageResource] Updating page resource',
      createSafeLogData({
        operation: 'UPDATE',
        table: 'pageResource',
        id: id,
        oldData: oldData,
        newData: data,
      }),
    );
    const result = await this.prisma.pageResource.update({
      where: { id: id },
      data,
    });
    this.logger.info(
      '[PageResource] Page resource updated successfully',
      createSafeLogData({
        operation: 'UPDATE',
        table: 'pageResource',
        id: id,
        result: result,
      }),
    );
    return result;
  }

  async deleteMany(
    pageResourceDeleteManyArgs: Prisma.PageResourceDeleteManyArgs,
  ) {
    const oldData = await this.prisma.pageResource.findMany({
      where: pageResourceDeleteManyArgs.where,
    });
    this.logger.info(
      '[PageResource] Deleting multiple page resources',
      createSafeLogData({
        operation: 'DELETE_MANY',
        table: 'pageResource',
        where: pageResourceDeleteManyArgs.where,
        oldData: oldData,
      }),
    );
    const result = await this.prisma.pageResource.deleteMany(
      pageResourceDeleteManyArgs,
    );
    this.logger.info(
      '[PageResource] Multiple page resources deleted successfully',
      createSafeLogData({
        operation: 'DELETE_MANY',
        table: 'pageResource',
        count: result.count,
      }),
    );
    return result;
  }

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

  async count(pageResourceCountArgs?: Prisma.PageResourceCountArgs) {
    return await this.prisma.pageResource.count(pageResourceCountArgs);
  }

  async groupBy(pageResourceGroupByArgs: Prisma.PageResourceGroupByArgs) {
    return await this.prisma.pageResource.groupBy(
      pageResourceGroupByArgs as any,
    );
  }

  async aggregate(pageResourceAggregateArgs: Prisma.PageResourceAggregateArgs) {
    return await this.prisma.pageResource.aggregate(pageResourceAggregateArgs);
  }
}
