<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;

class Booking extends Model
{
    use HasFactory;
    use SoftDeletes;

    protected $fillable = [
        'account_id',
        'payment_id',
        'amount_cents',
        'type',
        'description',
        'booked_at',
    ];

    protected function casts(): array
    {
        return [
            'booked_at' => 'datetime',
            'amount_cents' => 'integer',
        ];
    }

    public function account(): BelongsTo
    {
        return $this->belongsTo(Account::class);
    }

    public function payment(): BelongsTo
    {
        return $this->belongsTo(Payment::class);
    }

    protected static function booted(): void
    {
        static::created(function (Booking $booking): void {
            $booking->applyToAccountBalance(+1);
        });

        static::deleted(function (Booking $booking): void {
            // Soft delete should revert the effect on balance
            $booking->applyToAccountBalance(-1);
        });

        static::restored(function (Booking $booking): void {
            // Re-apply when restored
            $booking->applyToAccountBalance(+1);
        });
    }

    /**
     * Apply or revert the booking effect on account balance.
     *
     * @param  int  $multiplier  +1 to apply, -1 to revert
     */
    protected function applyToAccountBalance(int $multiplier = 1): void
    {
        $account = $this->account;
        if (! $account) {
            return;
        }

        $delta = ($this->amount_cents / 100.0);
        if ($this->type === 'credit') {
            // Credit decreases the receivable (balance goes down)
            $delta = -$delta;
        }
        // Debit increases receivable (balance up), credit decreases
        $account->forceFill([
            'balance_amount' => (float) ($account->balance_amount ?? 0) + ($multiplier * $delta),
        ])->save();
    }
}
