import { Injectable, Logger } from '@nestjs/common';
import { CreateFeeDto } from './dto/create-fee.dto';
import { UpdateFeeDto } from './dto/update-fee.dto';
import { PrismaService } from 'src/prisma/prisma.service';

@Injectable()
export class FeesService {
	constructor(private prisma: PrismaService) {}
	private logger = new Logger(FeesService.name);
	create(createFeeDto: CreateFeeDto) {
		const transaction = this.prisma.$transaction(async (tx) => {
			this.logger.log({ level: 'info', message: `Fee created with ${createFeeDto}`, refCode: '43201' });
			return tx.fees.create({ data: createFeeDto });
		});
		return transaction;
	}

	findAll(skip = 0, take = 10, sortBy: string, sortOrder: string, search: string = '') {
		const transaction = this.prisma.$transaction(async (tx) => {
			// this.logger.log({ level: 'info', message: 'Returning all fees', refCode: '43202' });

			if (take < 0) {
				take = 100;
			}
			let searchID = parseInt(search);

			if (Number.isNaN(searchID)) {
				searchID = 0;
			}

			// Default Query
			let query = {
				skip,
				take,
				orderBy: {
					[sortBy]: sortOrder,
				},
			} as any;

			if (search) {
				query.where = {};
			}

			// Search by ID
			if (search) {
				query.where.OR = [{ id: { equals: searchID } }, { name: { contains: search } }, { description: { contains: search } }];
			}

			return tx.fees.findManyAndCount(query);

			// return tx.fees.findManyAndCount();
		});
		return transaction;
	}

	findOne(id: number) {
		const transaction = this.prisma.$transaction(async (tx) => {
			// this.logger.log({ level: 'info', message: `Returning one fee ${id}`, refCode: '43202' });
			return tx.fees.findUnique({ where: { id } });
		});
		return transaction;
	}

	findByJobId(jobId: number) {
		const transaction = this.prisma.$transaction(async (tx) => {
			// this.logger.log({ level: 'info', message: `Returning all fees for job ${jobId}`, refCode: '43202' });
			return tx.fees.findMany({
				include: {
					jobs: true,
				},
				where: {
					jobs: {
						some: {
							jobId: jobId,
						},
					},
				},
			});
		});
		return transaction;
	}

	update(id: number, updateFeeDto: UpdateFeeDto) {
		const transaction = this.prisma.$transaction(async (tx) => {
			this.logger.log({ level: 'info', message: `Updating one fee ${id} with ${updateFeeDto}`, refCode: '43203' });
			if (updateFeeDto.jobId) {
				return tx.fees.update({
					where: { id },
					data: {
						id: id,
						name: updateFeeDto.name,
						amount: updateFeeDto.amount,
						description: updateFeeDto.description,
						modifier: updateFeeDto.modifier,
						taxable: updateFeeDto.taxable,
						type: updateFeeDto.type,

						jobs: {
							connect: {
								id: updateFeeDto.jobId,
							},
						},
					},
				});
			}

			return tx.fees.update({
				where: { id },
				data: updateFeeDto,
			});
		});
		return transaction;
	}

	remove(id: number) {
		const transaction = this.prisma.$transaction(async (tx) => {
			this.logger.log({ level: 'info', message: `Deleting one fee ${id}`, refCode: '43204' });
			return tx.fees.delete({ where: { id } });
		});
		return transaction;
	}
}
