<?php

namespace App\Models;

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

class Transaction extends Model
{
    use HasFactory;

    protected $fillable = [
        'type',
        'status',
        'transaction_id',
        'external_transaction_id',
        'merchant_trx_id',
        'finance_group_id',
        'bank_account_id',
        'crypto_account_id',
        'site_id',
        'amount',
        'amount_changed_from',
        'currency',
        'customer_name',
        'customer_email',
        'customer_phone',
        'customer_middle_name',
        'customer_surname',
        'customer_tc',
        'customer_iban',
        'customer_bank_name',
        'customer_account_holder',
        'customer_player_id',
        'sid',
        'api_key',
        'hash',
        'notify_url',
        'callback_response',
        'ip_address',
        'approved_by',
        'approved_by_name',
        'approved_at',
        'amount_changed_by_name',
        'amount_changed_at',
        'notes',
        'description',
        'source',
        'payment_method',
        'is_crypto',
        'crypto_coin_name',
        'crypto_address',
        'created_by_name',
    ];

    protected $casts = [
        'amount' => 'decimal:2',
        'amount_changed_from' => 'decimal:2',
        'callback_response' => 'array',
        'approved_at' => 'datetime',
        'amount_changed_at' => 'datetime',
        'is_crypto' => 'boolean',
    ];

    /**
     * Get the finance group assigned to this transaction
     */
    public function financeGroup()
    {
        return $this->belongsTo(FinanceGroup::class);
    }

    /**
     * Get the bank account used for this transaction
     */
    public function bankAccount()
    {
        return $this->belongsTo(BankAccount::class);
    }

    /**
     * Get the crypto account used for this transaction
     */
    public function cryptoAccount()
    {
        return $this->belongsTo(CryptoAccount::class);
    }

    /**
     * Get the site assigned to this transaction
     */
    public function site()
    {
        return $this->belongsTo(Site::class);
    }

    /**
     * Get the user who approved this transaction
     */
    public function approvedBy()
    {
        return $this->belongsTo(User::class, 'approved_by');
    }

    /**
     * Get API logs for this transaction
     */
    public function apiLogs()
    {
        return $this->hasMany(ApiLog::class);
    }

    /**
     * Generate unique transaction ID
     */
    public static function generateTransactionId($prefix = 'TXN')
    {
        return $prefix . now()->format('YmdHisv') . random_int(1000, 9999);
    }

    /**
     * Generate a unique transaction ID with a prefix
     */
    public static function generateUniqueTransactionId($prefix)
    {
        do {
            $transactionId = static::generateTransactionId($prefix);
        } while (static::where('transaction_id', $transactionId)->exists());

        return $transactionId;
    }

    /**
     * Scope for pending transactions
     */
    public function scopePending($query)
    {
        return $query->where('status', 'pending');
    }

    /**
     * Scope for deposits
     */
    public function scopeDeposits($query)
    {
        return $query->where('type', 'deposit');
    }

    /**
     * Scope for withdrawals
     */
    public function scopeWithdrawals($query)
    {
        return $query->where('type', 'withdrawal');
    }

    /**
     * Scope for specific finance group
     */
    public function scopeForFinanceGroup($query, $financeGroupId)
    {
        return $query->where('finance_group_id', $financeGroupId);
    }

    /**
     * Scope for date range
     */
    public function scopeDateRange($query, $startDate, $endDate)
    {
        return $query->whereBetween('created_at', [$startDate, $endDate]);
    }

    /**
     * Check if transaction is pending
     */
    public function isPending()
    {
        return $this->status === 'pending';
    }

    /**
     * Check if transaction is approved
     */
    public function isApproved()
    {
        return $this->status === 'approved';
    }

    /**
     * Check if transaction is completed
     */
    public function isCompleted()
    {
        return $this->status === 'completed';
    }

    /**
     * Get full customer name
     */
    public function getFullCustomerNameAttribute()
    {
        $parts = array_filter([
            $this->customer_name,
            $this->customer_middle_name,
            $this->customer_surname,
        ]);

        return implode(' ', $parts);
    }
}
