<?php

namespace App\Models;

use App\Traits\VisibleToAdmin;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Withdrawal extends Model
{
    use HasFactory;
    use VisibleToAdmin;

    // This tells the trait how to reach the user who controls visibility
    protected function adminVisibilityRelation(): string
    {
        return 'account.profile.user';
    }

    /** ================= STATUSES ================= */
    public const STATUS_PENDING = 'pending';
    public const STATUS_PROCESSING = 'processing';
    public const STATUS_APPROVED = 'approved';
    public const STATUS_REJECTED = 'rejected';

    protected $fillable = [
        'account_id',
        'payment_method_id',
        'crypto_wallet_id',
        'idempotency_key',
        'amount',
        'fee',
        'total',
        'meta',
        'status',
    ];

    protected $casts = [
        'amount' => 'decimal:2',
        'fee' => 'decimal:2',
        'total' => 'decimal:2',
        'meta' => 'array',
    ];

    protected $attributes = [
        'status' => self::STATUS_PENDING,
    ];

    /** ================= RELATIONSHIPS ================= */

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

    protected $cascadeDeletes = [
        'transactions',       // delete all related transactions
        // add other relations if needed in the future
    ];

    protected static function booted()
    {
        static::deleting(function ($withdrawal) {
            foreach ($withdrawal->cascadeDeletes as $relationName) {
                try {
                    $relation = $withdrawal->$relationName();

                    if ($relation instanceof Relation) {
                        // BelongsToMany → detach
                        if ($relation instanceof \Illuminate\Database\Eloquent\Relations\BelongsToMany) {
                            $relation->detach();
                        } else {
                            // HasMany, HasOne, BelongsTo → delete each related model
                            $relation->get()->each(fn($item) => $item->delete());
                        }
                    }
                } catch (\Throwable $e) {
                    // Ignore if relation doesn't exist or fails
                    continue;
                }
            }
        });
    }
    public function paymentMethod()
    {
        return $this->belongsTo(PaymentMethod::class);
    }

    public function cryptoWallet()
    {
        return $this->belongsTo(CryptoWallet::class);
    }

    public function transactions()
    {
        return $this->hasMany(Transaction::class, 'withdrawal_id');
    }

    /** ================= STATUS HELPERS ================= */

    public function isPending(): bool
    {
        return $this->status === self::STATUS_PENDING;
    }

    public function isProcessing(): bool
    {
        return $this->status === self::STATUS_PROCESSING;
    }

    public function isApproved(): bool
    {
        return $this->status === self::STATUS_APPROVED;
    }

    public function isRejected(): bool
    {
        return $this->status === self::STATUS_REJECTED;
    }

    /** ================= QUERY SCOPES ================= */

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

    public function scopeProcessing($query)
    {
        return $query->where('status', self::STATUS_PROCESSING);
    }

    public function scopeApproved($query)
    {
        return $query->where('status', self::STATUS_APPROVED);
    }

    public function scopeRejected($query)
    {
        return $query->where('status', self::STATUS_REJECTED);
    }

    /** ================= HELPERS ================= */

    public function totalWithFee(): string
    {
        return bcadd(
            (string) $this->amount,
            (string) $this->fee,
            2
        );
    }
}
