import { Injectable, Logger } from '@nestjs/common';
import { CreateProductDto } from './dto/create-product.dto';
import { UpdateProductDto } from './dto/update-product.dto';
import { PrismaService } from 'src/prisma/prisma.service';

@Injectable()
export class ProductsService {
	constructor(private prisma: PrismaService) {}
	private readonly logger = new Logger(ProductsService.name);
	create(createProductDto: CreateProductDto) {
		const transaction = this.prisma.$transaction(async (tx) => {
			this.logger.log({ level: 'info', message: `Product created with ${JSON.stringify(createProductDto)}`, refCode: '31201' });
			return tx.product.create({ data: createProductDto });
		});
		return transaction;
	}

	findAll(skip = 0, take = 10, sortBy: string = 'brandId', sortOrder: string = 'asc', search: string = '') {
		const transaction = this.prisma.$transaction(async (tx) => {
			if (take < 0) {
				take = 100;
			}

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

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

                query.where.OR = [
                    { 
                        brandId: { equals: search } 
                    }, 
                    { 
                        title: { contains: search } 
                    }, 
                    { 
                        description: { contains: search } 
                    }
                ];
			}

			return tx.product.findManyAndCount(query);
		});
		return transaction;
	}

	findAllSimple(params: any) {
		const transaction = this.prisma.$transaction(async (tx) => {
			// this.logger.log({ level: 'info', message: 'Returning all products simply', refCode: '31202' });

            let whereQuery = {};

            if (params.brandId) {
				whereQuery = { ...whereQuery, brandId: params.brandId };
			}

            if (params.title) {
				whereQuery = { ...whereQuery, title: params.title };
			}

            if (params.brand) {
				whereQuery = { ...whereQuery, brand: params.brand };
			}

            if (params.categoryId) {
                whereQuery = { ...whereQuery, categoryId: params.categoryId };
            }
            
			return tx.product.findMany({
                where: whereQuery,
				select: {
					id: true,
					title: true,
					brandId: true,
				},
			});
		});
		return transaction;
	}

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

	update(id: number, updateProductDto: UpdateProductDto) {
		const transaction = this.prisma.$transaction(async (tx) => {
			this.logger.log({ level: 'info', message: `Updating one product ${id} with ${updateProductDto}`, refCode: '31203' });
			return tx.product.update({ where: { id }, data: updateProductDto });
		});
		return transaction;
	}

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