<?php

namespace App\Models;

use App\Enums\BillingStatus;
use Database\Factories\BillingFactory;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Carbon;

/**
 * Invoice deposit credit (RPD §12.2, BR-04).
 *
 * @property int $id
 * @property string $no_invoice
 * @property int $jumlah_credit
 * @property int $rate
 * @property int $total
 * @property int|null $bank_id
 * @property BillingStatus $status
 * @property string $payment_method
 * @property int $user_id
 * @property Carbon|null $paid_at
 *
 * @method static Builder|self pending()
 */
class Billing extends Model
{
    /** @use HasFactory<BillingFactory> */
    use HasFactory;

    protected $fillable = [
        'no_invoice', 'jumlah_credit', 'rate', 'total',
        'bank_id', 'status', 'payment_method', 'user_id', 'paid_at',
        'duitku_reference', 'duitku_payment_url', 'duitku_payment_method',
        'duitku_status_code', 'duitku_status_message', 'duitku_requested_at',
        'duitku_callback_received_at', 'duitku_response', 'duitku_callback_payload',
    ];

    protected function casts(): array
    {
        return [
            'jumlah_credit' => 'integer',
            'rate' => 'integer',
            'total' => 'integer',
            'status' => BillingStatus::class,
            'paid_at' => 'datetime',
            'duitku_requested_at' => 'datetime',
            'duitku_callback_received_at' => 'datetime',
            'duitku_response' => 'array',
            'duitku_callback_payload' => 'array',
        ];
    }

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

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

    public function scopePending(Builder $query): Builder
    {
        return $query->where('status', BillingStatus::Pending);
    }

    /**
     * Apakah invoice masih bisa diubah/dihapus? (BR-04) Hanya saat Pending.
     */
    public function isMutable(): bool
    {
        return $this->status === BillingStatus::Pending;
    }

    /**
     * Apakah invoice dibayar via gateway Duitku?
     */
    public function isDuitku(): bool
    {
        return $this->payment_method === 'duitku';
    }

    /**
     * Apakah sudah ada URL pembayaran Duitku yang bisa dipakai (re)pay?
     */
    public function hasDuitkuPaymentUrl(): bool
    {
        return $this->isDuitku() && filled($this->duitku_payment_url);
    }
}
