<?php

namespace App\Models\ACCOUNTING;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\OPERATION\Operation;
use App\Models\ACCOUNTING\BankAccount;
use App\Models\ADMIN\User;
use OwenIt\Auditing\Contracts\Auditable;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;

class Payment extends Model  implements Auditable
{
    use SoftDeletes, \OwenIt\Auditing\Auditable;

    protected $fillable = [
        'uid',
        'name',
        'status',
        'reference',
        'operationType',
        'paymentmethod',
        'amount',
        'currency',
        'paymentDate',
        'counterParty',
        'operationId',
        'bankAccountId',
        'createdBy',
        'chequeNumber',
        'dueDate',
        'bankName',
        'owner',
        'beneficiary',
        'notes',
    ];

    protected $casts = [
        'currency' => 'array',
        'counterParty' => 'array',
        'paymentmethod' => 'array',
        'paymentDate' => 'date',
        'dueDate'=>'date'
    ];

    public function operation()
    {
        return $this->belongsTo(Operation::class, 'operationId');
    }

    public function bankAccount()
    {
        return $this->belongsTo(BankAccount::class, 'bankAccountId');
    }

    public function user()
    {
        return $this->belongsTo(User::class, 'createdBy');
    }

    public static function booted()
    {
        static::creating(function (Payment $payment) {
            if (empty($payment->paymentNumber)) {
                $operationId = $payment->operationId ?? 'GEN';
                $payment->paymentNumber =
                    'PAY-' .
                    now()->format('YmdHis') .
                    '-' .
                    $operationId;
                $payment->reference =$payment->operation->docId;

            }
            if (empty($payment->operationType)) {
                $operationId = $payment->operation->docType;
            }
            if (empty($payment->counter)) {
                $operationId = $payment->operation->docType;
            }
             if (empty($payment->counterParty)) {
                $payment->counterParty = $payment->operation->counterParty;
            }
            if (Auth::check()) {
                $payment->createdBy = Auth::id();
            }

            //add uid
            $payment->uid = (string) Str::uuid();
            //add name
            $payment->name = $payment->operationType .'-'. $payment->paymentNumber;

        });
    }


    public static function settleInvoices(
        float $amount,
        array $operationIds,
        array $data = []
    ): void {
        DB::transaction(function () use ($amount, $operationIds, $data) {

            $operations = Operation::whereIn('id', $operationIds)
                ->where('status', '!=', 'paid')
                ->orderBy('created_at')
                ->get();

            foreach ($operations as $operation) {

                if ($amount <= 0) {
                    break;
                }

                $alreadyPaid = $operation->payments()->sum('amount');
                $remaining   = $operation->totalTTC - $alreadyPaid;

                if ($remaining <= 0) {
                    continue;
                }

                $paymentAmount = min($amount, $remaining);

                Payment::create([
                    'paymentNumber' => 'PAY-' . now()->format('YmdHis') . '-' . $operation->id,
                    'reference'     => $data['reference'] ?? 'AUTO-' . Str::random(6),
                    'operationType' => $operation->docType,
                    'operationId'   => $operation->id,
                    'paymentMethod' => $data['paymentMethod'] ?? 'cash',
                    'amount'        => $paymentAmount,
                    'currency'      => $operation->currency ?? null,
                    'status'        => 'completed',
                    'paymentDate'   => now(),
                    'createdBy'     => auth::id(),
                ]);

                // amount reduction
                $amount -= $paymentAmount;
            }
        });
    }
}
