import externalInvoiceModel from "./externalInvoice.model";
import { IExternalInvoice } from "./externalInvoice.interface";



export class ExternalInvoiceService {


    //Obtener todas las facturas
    async getAll() {

        return await externalInvoiceModel
            .find()
            .populate("fuelTypeId")
            .populate("createdBy")
            .populate("approvedBy")
            .sort({
                createdAt: -1
            });

    }


    // Obtener factura por ID
    async getById(
        id: string
    ) {

        return await externalInvoiceModel
            .findById(id)
            .populate("fuelTypeId")
            .populate("createdBy")
            .populate("approvedBy");

    }


     //Crear factura externa
    async create(
        data: IExternalInvoice
    ) {

        if(data.currentMileage < data.previousMileage) {
            throw new Error ("El kilometraje no puede ser menor que el anterior");
        }

        //Validar que los galones sean mayor a 0
        if(data.gallonQuantity <= 0){
            throw new Error ("La cantidad de galones debe ser mayor que 0");
        }

        // Calcular monto total
        data.totalAmount = data.gallonQuantity * data.pricePerGallon;

        //Calcular distancia recorrida
        data.distanceTraveled = data.currentMileage - data.previousMileage;

        const invoice = new externalInvoiceModel(data);

        return await invoice.save();

    }


    //Actualizar factura
    async update(
        id: string,
        data: Partial<IExternalInvoice>
    ) {

         const invoice = await externalInvoiceModel.findById(id);
        
        if(!invoice){
            return null;
        }
        
        const previousMileage = data.previousMileage ?? invoice.previousMileage;
        
        const currentMileage = data.currentMileage ?? invoice.currentMileage;
        
        const gallonQuantity = data.gallonQuantity ?? invoice.gallonQuantity;
        
        const pricePerGallon = data.pricePerGallon ?? invoice.pricePerGallon;
        
        //Recalcular distancia recorrida
        data.distanceTraveled = currentMileage - previousMileage;
        
        //Validar kilometraje
        
        if(data.distanceTraveled < 0){
            throw new Error("El kilometraje actual no puede ser menor que el anterior");
        }

        
        data.totalAmount = gallonQuantity * pricePerGallon;

        

        const updateInvoice = await externalInvoiceModel.findByIdAndUpdate(
            id,
            data,
            {
                new:true
            }
        );
        
        return updateInvoice;

    }


    // Buscar por estado
    async getByStatus(
        status: string
    ) {

        return await externalInvoiceModel
            .find({
                status
            } as any);

    }


    // Buscar por zona
    async getByZone(
        zone: string
    ) {

        return await externalInvoiceModel
            .find({
                zone
            } as any);

    }


    //Eliminar factura
    async delete(
        id: string
    ) {

        return await externalInvoiceModel
            .findByIdAndDelete(id);

    }

}