<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Transaction extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'cryptoasset_id',
        'type',
        'which_crypto',
        'from_crypto', // For swaps
        'to_crypto',   // For swaps
        'transaction_hash',
        'from_address',
        'to_address',
        'amount_in',
        'amount_out',
        'network_fee',
        'rate',
        'status',
        'metadata',
        'related_transaction_id',
    ];

    protected $casts = [
        'amount_in' => 'decimal:8',
        'amount_out' => 'decimal:8',
        'network_fee' => 'decimal:8',
        'rate' => 'decimal:8',
        'metadata' => 'json',
        'processed_at' => 'datetime',
    ];

    // Define constants for types
    const TYPE_DEPOSIT = 'deposit';
    const TYPE_WITHDRAWAL = 'withdrawal';
    const TYPE_SWAP = 'swap';
    const TYPE_FUNDING = 'funding';
    const TYPE_REFUND = 'refund';

    // Define constants for statuses
    const STATUS_PENDING = 'pending';
    const STATUS_PROCESSING = 'processing';
    const STATUS_COMPLETED = 'completed';
    const STATUS_FAILED = 'failed';
    const STATUS_CANCELLED = 'cancelled';
    const STATUS_REVERSED = 'reversed';

    // Get valid types
    public static function getValidTypes()
    {
        return [
            self::TYPE_DEPOSIT,
            self::TYPE_WITHDRAWAL,
            self::TYPE_SWAP,
            self::TYPE_FUNDING,
            self::TYPE_REFUND,
        ];
    }

    // Get valid statuses
    public static function getValidStatuses()
    {
        return [
            self::STATUS_PENDING,
            self::STATUS_PROCESSING,
            self::STATUS_COMPLETED,
            self::STATUS_FAILED,
            self::STATUS_CANCELLED,
            self::STATUS_REVERSED,
        ];
    }

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

    public function cryptoAsset()
    {
        return $this->belongsTo(CryptoAsset::class, 'cryptoasset_id');
    }

    public function relatedTransaction()
    {
        return $this->belongsTo(self::class, 'related_transaction_id');
    }

    // Scopes for easy querying
    public function scopeOfType($query, $type)
    {
        return $query->where('type', $type);
    }

    public function scopeOfStatus($query, $status)
    {
        return $query->where('status', $status);
    }

    public function scopeOfCrypto($query, $crypto)
    {
        return $query->where('which_crypto', $crypto);
    }

    // Helper methods
    public function isCompleted()
    {
        return $this->status === self::STATUS_COMPLETED;
    }

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

    public function isSwap()
    {
        return $this->type === self::TYPE_SWAP;
    }
}