import { Injectable, Logger } from '@nestjs/common';
import { CreateImprintDto } from './dto/create-imprint.dto';
import { UpdateImprintDto } from './dto/update-imprint.dto';
import { PrismaService } from 'src/prisma/prisma.service';

@Injectable()
export class ImprintsService {
	constructor(private prisma: PrismaService) {}
	private readonly logger = new Logger(ImprintsService.name);
	create(createImprintDto: CreateImprintDto) {
		const transaction = this.prisma.$transaction(async (tx) => {
			this.logger.log({ level: 'info', message: `Imprint created with ${createImprintDto.inks}`, refCode: '33201' });
			return tx.imprint.create({
				data: {
					type: createImprintDto.type,
					location: createImprintDto.location,
					designId: createImprintDto.designId,
					pricingType: createImprintDto.pricingType,
					images: { create: createImprintDto.images },
					height: createImprintDto.height,
					width: createImprintDto.width,
					inks: {
						// add multiple inks to the imprint
						create: createImprintDto.inks.map((ink) => ({
							mesh: ink.mesh,
							ink: {
								connect: {
									id: ink.inkId,
								},
							},
						})),
					},
				},
			});
		});
		return transaction;
	}

	findAll() {
		const transaction = this.prisma.$transaction(async (tx) => {
			// this.logger.log({ level: 'info', message: 'Returning all imprints', refCode: '33202' });
			return tx.imprint.findMany();
		});
		return transaction;
	}

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

				include: {
					inks: {
						include: {
							ink: true,
						},
					},
					images: true,
				},
			});
		});
		return transaction;
	}

	update(id: number, updateImprintDto: UpdateImprintDto) {
		const transaction = this.prisma.$transaction(async (tx) => {
			this.logger.log({ level: 'info', message: `Updating one imprint ${id} with ${JSON.stringify(updateImprintDto)}`, refCode: '33203' });
			return tx.imprint.update({
				where: { id },
				data: {
					type: updateImprintDto.type,
					location: updateImprintDto.location,
					designId: updateImprintDto.designId,
					pricingType: updateImprintDto.pricingType,
					images: {
						upsert: updateImprintDto.images.map((image) => ({
							where: {
								id: image.id,
							},
							update: {
								url: image.url,
							},
							create: {
								url: image.url,
							},
						})),
					},
					height: updateImprintDto.height,
					width: updateImprintDto.width,
					inks: {
						upsert: updateImprintDto.inks.map((ink) => ({
							where: {
								id: ink.id,
							},
							update: {
								mesh: ink.mesh,
								ink: {
									connect: {
										id: ink.inkId,
									},
								},
							},
							create: {
								mesh: ink.mesh,
								ink: {
									connect: {
										id: ink.inkId,
									},
								},
							},
						})),
					},
				},
			});
		});
		return transaction;
	}

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