<?php

namespace App\Models;

use App\Models\Concerns\BelongsToTenant;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class MemberTransfer extends Model
{
    use BelongsToTenant;

    public const TYPE_INTERNAL = 'internal';
    public const TYPE_BANK = 'bank';

    public const STATUS_PENDING = 'pending';
    public const STATUS_POSTED = 'posted';
    public const STATUS_REJECTED = 'rejected';
    public const STATUS_CANCELED = 'canceled';
    public const STATUS_FAILED = 'failed';

    protected $fillable = [
        'tenant_id',
        'sender_customer_id',
        'sender_savings_account_id',
        'recipient_customer_id',
        'recipient_savings_account_id',
        'initiated_by',
        'approved_by',
        'rejected_by',
        'canceled_by',
        'sender_transaction_id',
        'recipient_transaction_id',
        'transfer_type',
        'reference',
        'amount',
        'fee',
        'total_amount',
        'recipient_account_number',
        'recipient_account_name',
        'recipient_bank_name',
        'recipient_bank_code',
        'narration',
        'status',
        'provider_reference',
        'provider_response',
        'approved_at',
        'rejected_at',
        'canceled_at',
        'posted_at',
        'rejected_reason',
        'canceled_reason',
    ];

    protected function casts(): array
    {
        return [
            'amount' => 'decimal:2',
            'fee' => 'decimal:2',
            'total_amount' => 'decimal:2',
            'provider_response' => 'array',
            'approved_at' => 'datetime',
            'rejected_at' => 'datetime',
            'canceled_at' => 'datetime',
            'posted_at' => 'datetime',
        ];
    }

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

    public function sender(): BelongsTo
    {
        return $this->belongsTo(Customer::class, 'sender_customer_id');
    }

    public function sourceAccount(): BelongsTo
    {
        return $this->belongsTo(SavingsAccount::class, 'sender_savings_account_id');
    }

    public function recipient(): BelongsTo
    {
        return $this->belongsTo(Customer::class, 'recipient_customer_id');
    }

    public function recipientAccount(): BelongsTo
    {
        return $this->belongsTo(SavingsAccount::class, 'recipient_savings_account_id');
    }

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

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

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

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

    public function senderTransaction(): BelongsTo
    {
        return $this->belongsTo(SavingsTransaction::class, 'sender_transaction_id');
    }

    public function recipientTransaction(): BelongsTo
    {
        return $this->belongsTo(SavingsTransaction::class, 'recipient_transaction_id');
    }

    public function typeLabel(): string
    {
        return match ($this->transfer_type) {
            self::TYPE_INTERNAL => 'Internal transfer',
            self::TYPE_BANK => 'Bank transfer',
            default => str($this->transfer_type)->headline()->toString(),
        };
    }

    public function statusLabel(): string
    {
        return str($this->status)->headline()->toString();
    }

    public function statusBadge(): string
    {
        return match ($this->status) {
            self::STATUS_POSTED => 'success',
            self::STATUS_PENDING => 'warning',
            self::STATUS_REJECTED, self::STATUS_FAILED => 'danger',
            self::STATUS_CANCELED => 'secondary',
            default => 'light',
        };
    }
}
