<?php


namespace App\Models\PaymentManagement\Traits;


use App\Exceptions\InsuffisantFundsException;
use App\Models\PaymentManagement\Payment;
use App\Models\PaymentManagement\PaymentMethod;
use App\Models\PaymentManagement\PaymentUsage;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\File;
use Throwable;


trait HasPaymentsUsages{

    /**
     * @return mixed
     */
    public function paymentUsages(){
        return $this->morphMany(
            PaymentUsage::class,
            PaymentUsage::MORPH_FUNCTION_NAME,
            PaymentUsage::MORPH_TYPE_COLUMN,
            PaymentUsage::MORPH_ID_COLUMN
        );
    }


    /**
     * @return mixed
     */
    public function payments(){
        return $this->morphMany(
            Payment::class,
            PaymentUsage::MORPH_FUNCTION_NAME,
            PaymentUsage::MORPH_TYPE_COLUMN,
            PaymentUsage::MORPH_ID_COLUMN
        );
    }

    /** Consomme les paiements disponibles du payer
     * @param Model $payer
     * @param float $consumedAmount montant à débité sur les paiements disponibles du payeur
     * @return bool
     * @throws InsuffisantFundsException
     * @throws Throwable
     */
    public function consumePayments($payer, $consumedAmount){

        throw_if(
           blank($payer) , /*si le solde du compte  est insuffisant*/
            new InsuffisantFundsException(__("Missing payer account."))
        );

        //paiements disponibles du payeur
        $payments = $payer->payments()->availables()->get();

        /*solde du compte du payeur*/
        $balance = $payer->balance;
        $message = __("Insufficient payment(s) to validate the transaction. Please recharge this and try again. :balance < :consumedAmount" ,
            [
                'balance' => $balance,
                'consumedAmount' => $consumedAmount,
            ]
        );

        throw_if(
            $balance < $consumedAmount , /*si le solde du compte  est insuffisant*/
//            new InsuffisantFundsException(__("Insufficient payment(s) to validate the transaction. Please recharge this and try again."))
            new InsuffisantFundsException($message)
        );


        /*si le solde du compte peut payer la commande*/
        if ( $balance >= $consumedAmount){
            if ($payments->isNotEmpty()){
                $totalConsumed =  0;  //total déja débité

                $totalRemaining = $consumedAmount;   //total restant à débiter "5000"
                $stop = false;

                // pour chaque paiement disponible
                foreach($payments as $payment){
                     $payment_id = $payment->id;

                    $availableAmount = $payment->remaining_amount; // montant dispo sur le paiement "5000"
                    $totalConsumed +=  $availableAmount; // "5000"

                    /*le total deja débiter est >= au montant à débiter*/
                    if ($totalConsumed >= $consumedAmount) {
                        $currentUsedAmount = $totalRemaining;
                        $balancePayment = $availableAmount - $currentUsedAmount;
                        $stop = true;
                    }else{
                        $balancePayment = 0; // montant restant sur le paiement
                        $currentUsedAmount =  $availableAmount; // montant utilisé sur le paiement
                        // montant total restantant à débiter
                        $totalRemaining = $totalRemaining - $currentUsedAmount;
                    }

                    // toutes les utilisations de ce paiement non supprimés
                    $usages = $payment->usages()->where('deleted',false)->get();

                    //enregistre le paiemnt sur la commande
                     $this->paymentUsages()->create([
                                "payment_id" => $payment_id,
                                "amount_used" => $currentUsedAmount,
                                //"remaining_amount_before" => $availableAmount,
                                //"remaining_amount_after" => $balancePayment,
                                "is_first_usage" => blank($usages),
                            ]);
                    //decremente le montant restant sur le paiement
                 //   $payment->decrement('remaining_amount',$balancePayment);
                    $payment->update([
                        'remaining_amount' => $balancePayment,
                        //'visible' => ($balancePayment > 0),
                    ]);

                    if ($stop)  {
                      return true;
                    }
                }
            }else{
                throw new InsuffisantFundsException(__("Aucun paiement disponible pour valider l'opération"));
            }
        }

        return false;
    }
}
