<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

final class TripayTransaction extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'character_id',
        'reference',
        'merchant_ref',
        'amount',
        'gold_amount',
        'streamer_code',
        'payment_method',
        'status',
        'payment_url',
        'checkout_url',
        'response_data',
        'expired_at',
        'paid_at',
    ];

    protected $casts = [
        'amount' => 'integer',
        'gold_amount' => 'integer',
        'response_data' => 'array',
        'expired_at' => 'datetime',
        'paid_at' => 'datetime',
    ];

    /**
     * Get the user that owns the transaction.
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id', 'ID');
    }

    /**
     * Get the streamer associated with this transaction.
     */
    public function streamer(): BelongsTo
    {
        return $this->belongsTo(Streamer::class, 'streamer_code', 'code');
    }

    /**
     * Scope to filter by status.
     */
    public function scopeStatus(Builder $query, string $status): Builder
    {
        return $query->where('status', $status);
    }

    /**
     * Scope to get pending transactions.
     */
    public function scopePending(Builder $query): Builder
    {
        return $query->where('status', 'pending');
    }

    /**
     * Scope to get paid transactions.
     */
    public function scopePaid(Builder $query): Builder
    {
        return $query->where('status', 'paid');
    }

    /**
     * Scope to get failed transactions.
     */
    public function scopeFailed(Builder $query): Builder
    {
        return $query->where('status', 'failed');
    }

    /**
     * Scope to get expired transactions.
     */
    public function scopeExpired(Builder $query): Builder
    {
        return $query->where('status', 'expired');
    }

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

    /**
     * Check if transaction is paid.
     */
    public function isPaid(): bool
    {
        return $this->status === 'paid';
    }

    /**
     * Check if transaction has expired.
     */
    public function isExpired(): bool
    {
        return $this->status === 'expired' || 
               ($this->expired_at && now()->greaterThan($this->expired_at));
    }

    /**
     * Update transaction status.
     */
    public function updateStatus(string $status, array $responseData = null): bool
    {
        $data = ['status' => $status];
        
        if ($status === 'paid' && !$this->paid_at) {
            $data['paid_at'] = now();
        }
        
        if ($responseData) {
            $data['response_data'] = $responseData;
        }
        
        return $this->update($data);
    }

    /**
     * Add gold to user and process streamer reward.
     */
    public function processPayment(): bool
    {
        if (!$this->isPending()) {
            return false;
        }

        try {
            // Update transaction status
            $this->updateStatus('paid');

            // Use PaymentService to handle payment processing
            $paymentService = app(\App\Services\Commerce\PaymentService::class);
            $settings = TripaySettings::first();
            
            return $paymentService->processSuccessfulPayment($this, $settings);
        } catch (\Exception $e) {
            \Log::error('Failed to process Tripay payment', [
                'transaction_id' => $this->id,
                'error' => $e->getMessage(),
            ]);
            return false;
        }
    }
}
