<?php

namespace App\Models\PaymentManagement;

use App\Models\Traits\Bootables\Auditable;
use App\Models\Traits\CanUploadFiles;
use Axn\EloquentAuthorable\AuthorableTrait;
use Database\Factories\PaymentFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\MediaLibrary\HasMedia as SpatieHasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class Payment extends Model implements SpatieHasMedia{
    use HasFactory,Auditable,SoftDeletes,
        AuthorableTrait,InteractsWithMedia,Auditable, CanUploadFiles;

    protected $guarded = ['id',"created_at"];
    protected $table = "payment_mgt__payments";
    const MORPH_ID_COLUMN = "payer_id";
    const MORPH_TYPE_COLUMN = "payer_type";
    const MORPH_FUNCTION_NAME = "payer";


    protected $dates = [
        'expired_at',
    ];

    protected static function booted(){
       // static::addGlobalScope(new PaymentGlobalScope);
    }

    protected static function newFactory(){
        return PaymentFactory::new();
    }


    public static function findByReference($reference){
        return self::firstWhere("provider_reference",$reference);
    }

    public static function validations_attributes(){
        return [
            "internal_reference" => __("Internal Reference"),
            "provider_reference" => __("Provider Reference"),
            "provider_reference_confirmation" => __("Provider Reference Confirmation"),
            "payment_method_id" => __("Payment Method"),
            "image" => __("Image"),
            "paid_at" => __("Paid At"),
            "paid_amount" => __("Paid Amount"),
            "remaining_amount" => __("Remaining Amount"),
        ];
    }

    public static function validations_messages(){
        return  [

        ];
    }

    //RELATIONS

    /** Le Payeur
     * @return MorphTo
     */
    public function payer(){
        return $this->morphTo(__FUNCTION__,
            self::MORPH_TYPE_COLUMN,self::MORPH_ID_COLUMN);
    }

    /** La methode de paiement
     * @return BelongsTo
     */
    public function paymentMethod(){
        return $this->belongsTo(PaymentMethod::class,"payment_method_id");
    }

    /** La methode de paiement
     * @return BelongsTo
     */
    public function method(){
        return $this->belongsTo(PaymentMethod::class,"payment_method_id");
    }

    /** Les utilisations
     * @return HasMany
     */
    public function usages(){
        return $this->hasMany(PaymentUsage::class,"payment_id");
    }


    //SCOPES

    /**les paiements disponibles
     * @param $query
     * @return mixed
     */
    public function scopeAvailables($query){
        return $query
            ->whereDate('expired_at','>=',date('Y-m-d')) // a partir d'aujourdhui
        //    ->whereDate('expired_at','>=',date('Y-m-d',strtotime("-30 days"))) // et 30 jr en arriere
            ->where('remaining_amount','>',0) // montant restant > 0
            ->where('visible',true) // est visible
            ->orderBy('remaining_amount','asc') // ordonné par montant restant
            ;
    }

    public function scopeVisibles($query){
        return $query->where('visible',true); // est visible
    }


    // GETTERS
    /** Determine si  le paiement est utilisé
     * @return bool
     */
    public function getIsUsedAttribute() {
        return $this->usages->contains( fn(PaymentUsage $usage) => !$usage->deleted);
    }

    /**Determinbe si le paiement est transférable
     * @return bool
     */
    public function getIsTransferableAttribute(){
        return ( ($this->remaining_amount > 0) and !$this->is_used );
    }

    /** Determine si c'est expiré
     * @return bool
     */
    public function getIsExpiredAttribute(){
        return (date_format($this->expired_at,'Y-m-d') < date('Y-m-d'));
    }

    //ACTIONS

    public function registerMediaCollections(): void{
        $this->addMediaCollection('payments')
            ->singleFile() // ne doit contenir qu'un seul fichier sur la collection ( utilisateur n'a qu'un seul avatar )
//            ->useFallbackUrl(get_gravatar($this->email)) // retouné lorsque getUrl = null
          //  ->useFallbackUrl(url("img/avatar.png")) // retouné lorsque getUrl = null
        ;

    }


}
