<?php

namespace App\Models;

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

class Referral extends Model
{
    use HasFactory;

    const STATUS_PENDING = 'pending';
    const STATUS_QUALIFIED = 'qualified';
    const STATUS_REWARDED = 'rewarded';
    const STATUS_CANCELLED = 'cancelled';

    protected $fillable = [
        'referrer_id',
        'referred_id',
        'referral_code_id',
        'status',
        'reward_amount',
        'wallet_transaction_id',
        'qualified_at',
        'rewarded_at',
    ];

    protected $casts = [
        'reward_amount' => 'decimal:2',
        'qualified_at' => 'datetime',
        'rewarded_at' => 'datetime',
    ];

    /**
     * Get the referrer (coach who shared the code).
     */
    public function referrer(): BelongsTo
    {
        return $this->belongsTo(User::class, 'referrer_id');
    }

    /**
     * Get the referred user (new coach who signed up).
     */
    public function referred(): BelongsTo
    {
        return $this->belongsTo(User::class, 'referred_id');
    }

    /**
     * Get the referral code used.
     */
    public function referralCode(): BelongsTo
    {
        return $this->belongsTo(ReferralCode::class);
    }

    /**
     * Get the wallet transaction for the reward.
     */
    public function walletTransaction(): BelongsTo
    {
        return $this->belongsTo(WalletTransaction::class);
    }

    /**
     * Mark referral as qualified (user completed required action).
     */
    public function markAsQualified(): void
    {
        $this->update([
            'status' => self::STATUS_QUALIFIED,
            'qualified_at' => now(),
        ]);
    }

    /**
     * Process the referral reward - add bonus to referrer's wallet.
     */
    public function processReward(): void
    {
        if ($this->status !== self::STATUS_QUALIFIED) {
            throw new \Exception('Referral must be qualified before rewarding');
        }

        $settings = ReferralSetting::getSettings();
        
        if (!$settings['enabled']) {
            return;
        }

        $rewardAmount = $this->calculateRewardAmount($settings);
        
        if ($rewardAmount <= 0) {
            return;
        }

        $referrer = $this->referrer;
        $wallet = $referrer->wallet ?? Wallet::create(['user_id' => $referrer->id]);
        
        $transaction = $wallet->addReferralBonus(
            $rewardAmount,
            $this->referred_id,
            "Bono por referir a {$this->referred->name}"
        );

        $this->update([
            'status' => self::STATUS_REWARDED,
            'reward_amount' => $rewardAmount,
            'wallet_transaction_id' => $transaction->id,
            'rewarded_at' => now(),
        ]);
    }

    /**
     * Calculate reward amount based on settings.
     */
    protected function calculateRewardAmount(array $settings): float
    {
        if ($settings['bonus_type'] === 'fixed') {
            return (float) $settings['bonus_amount'];
        }

        // Percentage-based reward would need the subscription amount
        // For now, return fixed amount
        return (float) $settings['bonus_amount'];
    }

    /**
     * Cancel the referral.
     */
    public function cancel(): void
    {
        $this->update([
            'status' => self::STATUS_CANCELLED,
        ]);
    }

    /**
     * Scope for pending referrals.
     */
    public function scopePending($query)
    {
        return $query->where('status', self::STATUS_PENDING);
    }

    /**
     * Scope for qualified referrals.
     */
    public function scopeQualified($query)
    {
        return $query->where('status', self::STATUS_QUALIFIED);
    }

    /**
     * Scope for rewarded referrals.
     */
    public function scopeRewarded($query)
    {
        return $query->where('status', self::STATUS_REWARDED);
    }

    /**
     * Get formatted status name.
     */
    public function getStatusNameAttribute(): string
    {
        return match($this->status) {
            self::STATUS_PENDING => 'Pendiente',
            self::STATUS_QUALIFIED => 'Calificado',
            self::STATUS_REWARDED => 'Recompensado',
            self::STATUS_CANCELLED => 'Cancelado',
            default => ucfirst($this->status),
        };
    }
}
