import { ConflictException, Injectable, NotFoundException } from '@nestjs/common';
import { FastFoodDto } from './DTO/fastFoodDto';
import { PrismaService } from 'src/prisma/prisma.service';
import { ProductDto } from './DTO/productDto';
import { VenteDto } from './DTO/venteDto';
import { LinkModePaymentDto } from './DTO/linkModePaymentDto';

@Injectable()
export class FastFoodService {

    constructor(private readonly prismaService: PrismaService){}

    async create(fastFoodDto: FastFoodDto) {

        const {libelle, adresse, telephone} = fastFoodDto

        await this.prismaService.fastFood.create({data:{libelle, adresse, telephone}})

        return {
            status:'SUCCESS',
            message:'Success'
        }
    }

    async addProduct(productDto: ProductDto, fastFoodId: any) {

        const {libelle, prixUnitaire} = productDto

        await this.prismaService.produit.create({data:{prixUnitaire,libelle, fastFoodId}})

        return {
            status:'SUCCESS',
            message:'Success'
        }
    }

    async vente(venteDto: VenteDto, fastFoodId: any, userId: any) {

        const caisseOpened = await this.prismaService.caisse.findFirst({where:{fastFoodId,statut:'OPEN'}})
        if (!caisseOpened) throw new ConflictException('Aucune caisse ouverte pour effectuer cette opération')

        var montant = 0

        for (const element of venteDto.produits) {

            const product = await this.prismaService.produit.findUnique({ where: { id: element.id } });

            if (!product) {
                throw new NotFoundException('produit introuvable');
            }
        
            montant = montant + (product.prixUnitaire * element.quantite);
        }

        const modePayment = await this.prismaService.modePayment.findUnique({where:{id:venteDto.modePaymentId}})

        if (!modePayment) {
            throw new NotFoundException('mode de paiement introuvable');
        }

        const vente = await this.prismaService.vente.create({data:{userId,fastFoodId,caisseId:caisseOpened.id, montant, modePaymentId: modePayment.id}})

        venteDto.produits.forEach(async element => {
            const product = await this.prismaService.produit.findUnique({where:{id:element.id}})

            await this.prismaService.venteDetail.create({data:{produitId:element.id, quantite:element.quantite, prixUnitaire:product.prixUnitaire,venteId:vente.id}})
        });

        await this.prismaService.caisse.update({where:{id:caisseOpened.id}, data:{montant:montant+caisseOpened.montant}})

        return {
            status:'SUCCESS',
            message:'Success'
        }
    }

    async getVenteDetails(venteId:number){
        const venteDetails = await this.prismaService.venteDetail.findMany({where:{venteId}})

        var data = []

        for (const vd of venteDetails) {
            const product = await this.prismaService.produit.findUnique({ where: { id: vd.produitId } });
            const element = {
                product: product.libelle,
                prixU: vd.prixUnitaire,
                quantite: vd.quantite,
                total: vd.quantite*vd.prixUnitaire,
            };
            data.push(element);
        }

        const vente = await this.prismaService.vente.findUnique({where:{id:venteId}, include:{modePayment:true}})

        return {
            status:'SUCCESS',
            message:'Success',
            data: data,
            caisseId:vente.caisseId,
            modePayment: vente.modePayment
        }
    }

    async cancelVente(venteId:number){

        const vente = await this.prismaService.vente.findUnique({
            where:{
                id:venteId
            }
        })

        if (!vente) {
            throw new NotFoundException('Vente introuvable');
        }

        const caisse = await this.prismaService.caisse.findUnique({
            where:{
                id:vente.caisseId
            }
        })

        if (!caisse) {
            throw new NotFoundException('Caisse introuvable');
        }

        await this.prismaService.caisse.update({
            where:{
                id:vente.caisseId
            },
            data:{
                montant:caisse.montant-vente.montant
            }
        })

        await this.prismaService.vente.update({
            where:{
                id:venteId
            }, 
            data:{
                deleted:true
            }
        })

        return {
            status:'SUCCESS',
            message:'Success'
        }
    }

    async products(fastFoodId: any) {
        const products = await this.prismaService.produit.findMany({where:{fastFoodId}, orderBy:{createdAt:'desc'}})
        return {
            status:'SUCCESS',
            message:'Success',
            data: products
        }
    }

    async getPaymentModeByFastFood(fastFoodId: any){
        const fastFoodWithModePayment = await this.prismaService.fastFood.findUnique({
            where:{
                id:fastFoodId
            }, 
            include:{
                fastFoodModePayment:{
                    include:{
                        modePayment:true
                    }
                }
            }
        })

        var modePayments = []

        fastFoodWithModePayment.fastFoodModePayment.forEach(fm => {
            modePayments.push(fm.modePayment)
        })

        return {
            status:'SUCCESS',
            message:'Success',
            data: modePayments
        }
    }

    async linkPaymentMode(linkModePaymentDto: LinkModePaymentDto){

        const modePayment = await this.prismaService.modePayment.findUnique({where:{id:linkModePaymentDto.modePaymentId}})

        if (!modePayment) {
            throw new NotFoundException('mode de paiement introuvable');
        }

        const fastFood = await this.prismaService.fastFood.findUnique({where:{id:linkModePaymentDto.fastFoodId}})

        if (!fastFood) {
            throw new NotFoundException('FastFood introuvable');
        }

        await this.prismaService.fastFoodModePayment.create({data:{fastFoodId:fastFood.id, modePaymentId:modePayment.id}})

        return {
            status:'SUCCESS',
            message:'Success'
        }
    }
}
