<?php

namespace Modules\Payment\Models;

use App\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Modules\Booking\Models\Booking;
use Modules\Payment\Database\Factories\RefundFactory;
use Modules\Payment\Enums\RefundStatus;
use Spatie\Activitylog\Models\Concerns\LogsActivity;
use Spatie\Activitylog\Support\LogOptions;

/**
 * A reversal against a specific successful Payment (not against the Booking
 * directly) — a Payment can have more than one Refund row for partial
 * refunds (domain.md §1, §6).
 */
class Refund extends Model
{
    /** @use HasFactory<RefundFactory> */
    use HasFactory, LogsActivity;

    /**
     * Audit trail on status transitions only (domain.md §6; T6.2).
     */
    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->logOnly(['status'])
            ->logOnlyDirty()
            ->dontLogEmptyChanges()
            ->useLogName('refund');
    }

    /**
     * @var list<string>
     */
    protected $fillable = [
        'payment_id',
        'booking_id',
        'status',
        'amount',
        'reason',
        'gateway_refund_id',
        'gateway_payload',
        'requested_by',
        'requested_at',
        'completed_at',
    ];

    /**
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'status' => RefundStatus::class,
            'amount' => 'decimal:2',
            'gateway_payload' => 'array',
            'requested_at' => 'datetime',
            'completed_at' => 'datetime',
        ];
    }

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

    /**
     * The leg actually being refunded/cancelled — not necessarily
     * payment->booking, since a round trip's return leg refunds against the
     * primary leg's shared Payment (domain.md §2b).
     */
    public function booking(): BelongsTo
    {
        return $this->belongsTo(Booking::class);
    }

    public function requestedBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'requested_by');
    }
}
