import { ConflictException, Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';

@Injectable()
export class CaisseService {

    constructor(private readonly prismaService: PrismaService){}

    async create(userId: any, fastFoodId: any) {
        const caisseOpened = await this.prismaService.caisse.findFirst({where:{fastFoodId,statut:'OPEN'}})
        if (caisseOpened) throw new ConflictException('Une caisse est deja ouverte pour')
        await this.prismaService.caisse.create({data:{
            libelle:'caisse du '+this.formatDate(new Date()),
            fastFoodId,
            userId
            
        }})

        return {
            status: 'SUCCESS',
            message: 'Caisse created succesfully',
          };
    }


    async getCurrent(fastFoodId: any) {
        const caisseOpened = await this.prismaService.caisse.findFirst({where:{fastFoodId,statut:'OPEN'}})
        if (!caisseOpened) throw new ConflictException('Pas de caisse ouverte')
        return {
            caisse: caisseOpened,
            status: 'SUCCESS'
        }
    }

    async getCaissesByFastFood(fastFoodId: any, page:number,size:number) {
        return {
            data: await this.prismaService.caisse.findMany({where:{fastFoodId}, skip:size*page,take:size, orderBy:{createdAt:'desc'}})
        } 
    }

    async getOperationsCurrentCaisse(fastFoodId: any) {
        const caisseOpened = await this.prismaService.caisse.findFirst({where:{fastFoodId,statut:'OPEN'}})
        if (!caisseOpened) throw new ConflictException('Pas de caisse ouverte')

        return {
            data: await this.prismaService.vente.findMany({
              where:{
                caisseId:caisseOpened.id,
                deleted:false
              }
            }),
            statut: 'SUCCESS'
        } 
    }

    async getOperationsByCaisse(id: number, fastFoodId:any) {
        const caisse = await this.prismaService.caisse.findUnique({where:{id}})
        if (!caisse) throw new NotFoundException('Caisse introuvable')
        if(caisse.fastFoodId!=fastFoodId) throw new ConflictException('cette n\'appartient pas à ce FF')

        const operations = await this.prismaService.vente.findMany({
            where:{
              caisseId:caisse.id,
              deleted:false
            },
            include:{
                modePayment:true,
                user:{
                    select:{
                        prenom:true,
                        nom:true
                    }
                }
            },
            orderBy:{createdAt:'desc'}
        })

        const detailsMontant = await this.prismaService.vente.groupBy({
            by:['modePaymentId'],
            where:{caisseId:id, deleted:false},
            _sum:{montant:true},
            _count:{modePaymentId:true},
        }).then((groupedMP) => {
            const modePaymentIds = groupedMP.map(group => group.modePaymentId);
            return this.prismaService.modePayment.findMany({
              where: {
                id: {
                  in: modePaymentIds,
                },
              },
            }).then((modePayments) => {
              return groupedMP.map(group => {
                const modePayment = modePayments.find(modePayment => modePayment.id === group.modePaymentId);
                return { ...group, modePayment };
              });
            });
          });

        return {
            data: operations,
            detailsMontant,
            caisse,
            statut: 'SUCCESS'
        } 
    }


    async fermetureCaisse(fastFoodId: any, montantCash:number){
        const caisseOpened = await this.prismaService.caisse.findFirst({where:{fastFoodId,statut:'OPEN'}})
        if (!caisseOpened) throw new ConflictException('Pas de caisse ouverte')

        await this.prismaService.arreteCaisse.create({data:{caisseId:caisseOpened.id, fastFoodId, montantCash}})

        await this.prismaService.caisse.update({where:{id:caisseOpened.id},data:{statut:'CLOSE'}})

        return {
            status: 'SUCCESS',
            message: 'Caisse closed succesfully',
          };

    }

    padTo2Digits(num: number) {
        return num.toString().padStart(2, '0');
      }
      
    formatDate(date: Date) {
        return (
          [
            date.getFullYear(),
            this.padTo2Digits(date.getMonth() + 1),
            this.padTo2Digits(date.getDate()),
          ].join('-') +
          ' ' +
          [
            this.padTo2Digits(date.getHours()),
            this.padTo2Digits(date.getMinutes()),
            this.padTo2Digits(date.getSeconds()),
          ].join(':')
        );
      }
    
}
