<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;

class Giveaway extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'title',
        'slug',
        'description',
        'image',
        'prize_type',
        'prize_value',
        'prize_description',
        'car_id',
        'entry_requirement',
        'max_entries',
        'starts_at',
        'ends_at',
        'status',
        'featured',
    ];

    protected $casts = [
        'prize_value' => 'decimal:2',
        'max_entries'  => 'integer',
        'starts_at'    => 'datetime',
        'ends_at'      => 'datetime',
        'featured'     => 'boolean',
    ];

    // ---------- boot ----------
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($giveaway) {
            if (empty($giveaway->slug)) {
                $giveaway->slug = Str::slug($giveaway->title);
                $original = $giveaway->slug;
                $count = 1;
                while (static::withTrashed()->where('slug', $giveaway->slug)->exists()) {
                    $giveaway->slug = $original . '-' . $count++;
                }
            }
        });
    }

    // ---------- relationships ----------
    public function entries()
    {
        return $this->hasMany(GiveawayEntry::class);
    }

    public function winner()
    {
        return $this->hasOne(GiveawayWinner::class);
    }

    public function car()
    {
        return $this->belongsTo(Car::class);
    }

    // ---------- scopes ----------
    public function scopeActive($query)
    {
        return $query->where('status', 'active')
                     ->where('starts_at', '<=', now())
                     ->where('ends_at', '>', now());
    }

    public function scopeUpcoming($query)
    {
        return $query->where('status', 'active')
                     ->where('starts_at', '>', now());
    }

    public function scopeEnded($query)
    {
        return $query->where('ends_at', '<=', now());
    }

    public function scopeFeatured($query)
    {
        return $query->where('featured', true);
    }

    public function scopeNeedsWinner($query)
    {
        return $query->where('status', 'ended')
                     ->doesntHave('winner')
                     ->has('entries');
    }

    // ---------- accessors ----------
    public function getImageUrlAttribute()
    {
        return $this->image ? asset('dash/' . $this->image) : null;
    }

    public function getDaysRemainingAttribute()
    {
        if (!$this->ends_at) return 0;
        return max(0, (int) now()->diffInDays($this->ends_at, false));
    }

    public function getIsActiveAttribute()
    {
        return $this->status === 'active'
            && $this->starts_at && $this->starts_at->lte(now())
            && $this->ends_at && $this->ends_at->gt(now());
    }

    public function getIsEndedAttribute()
    {
        return $this->ends_at && $this->ends_at->lte(now());
    }

    public function getIsFullAttribute()
    {
        return $this->max_entries && $this->entries()->count() >= $this->max_entries;
    }

    public function getEntryCountAttribute()
    {
        return $this->entries()->count();
    }

    public function getTotalTicketsAttribute()
    {
        return (int) $this->entries()->sum('entries_count');
    }

    // ---------- methods ----------

    /**
     * Weighted random draw — each entry's entries_count represents tickets.
     */
    public function selectWinner()
    {
        $entries = $this->entries()->get();
        if ($entries->isEmpty()) {
            return null;
        }

        $totalTickets = $entries->sum('entries_count');
        $randomTicket = random_int(1, $totalTickets);
        $cumulative = 0;
        $winningEntry = null;

        foreach ($entries as $entry) {
            $cumulative += $entry->entries_count;
            if ($randomTicket <= $cumulative) {
                $winningEntry = $entry;
                break;
            }
        }

        if (!$winningEntry) {
            $winningEntry = $entries->last();
        }

        return GiveawayWinner::create([
            'giveaway_id'      => $this->id,
            'user_id'          => $winningEntry->user_id,
            'giveaway_entry_id' => $winningEntry->id,
            'prize_status'     => 'selected',
            'notified_at'      => now(),
        ]);
    }

    /**
     * Check if a user can enter this giveaway.
     */
    public function userCanEnter($user)
    {
        if (!$this->is_active) return false;
        if ($this->is_full) return false;
        if ($this->userHasEntered($user->id)) return false;

        $eligibility = $this->getUserEligibility($user);
        return $eligibility['eligible'];
    }

    /**
     * Check if user already entered.
     */
    public function userHasEntered($userId)
    {
        return $this->entries()->where('user_id', $userId)->exists();
    }

    /**
     * Detailed eligibility check.
     */
    public function getUserEligibility($user)
    {
        if (!$user) {
            return ['eligible' => false, 'reason' => 'You must be logged in.'];
        }

        $hasVip = VipCardOrder::forUser($user->id)->active()->exists();
        $hasPurchase = CarOrder::forUser($user->id)->completed()->exists();

        switch ($this->entry_requirement) {
            case 'anyone':
                return ['eligible' => true, 'reason' => 'Anyone can enter.', 'has_vip' => $hasVip, 'has_purchase' => $hasPurchase];

            case 'vip_only':
                return [
                    'eligible'     => $hasVip,
                    'reason'       => $hasVip ? 'VIP membership verified.' : 'Active VIP membership required.',
                    'has_vip'      => $hasVip,
                    'has_purchase' => $hasPurchase,
                ];

            case 'purchase_required':
                return [
                    'eligible'     => $hasPurchase,
                    'reason'       => $hasPurchase ? 'Car purchase verified.' : 'Completed car purchase required.',
                    'has_vip'      => $hasVip,
                    'has_purchase' => $hasPurchase,
                ];

            case 'vip_and_purchase':
                $eligible = $hasVip && $hasPurchase;
                $reasons = [];
                if (!$hasVip) $reasons[] = 'Active VIP membership required';
                if (!$hasPurchase) $reasons[] = 'Completed car purchase required';
                return [
                    'eligible'     => $eligible,
                    'reason'       => $eligible ? 'All requirements met.' : implode('. ', $reasons) . '.',
                    'has_vip'      => $hasVip,
                    'has_purchase' => $hasPurchase,
                ];

            default:
                return ['eligible' => true, 'reason' => 'Open entry.', 'has_vip' => $hasVip, 'has_purchase' => $hasPurchase];
        }
    }
}
