<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\DB;

final class Event extends Model
{
    protected $table = 'events';

    protected $fillable = [
        'name',
        'type',
        'milestone',
        'min_level',
        'item_id',
        'item_name',
        'item_count',
        'protect_type',
        'octet',
        'mask',
        'mail_title',
        'mail_message',
        'is_active',
        'start_date',
        'end_date',
        'created_by',
    ];

    protected $casts = [
        'milestone' => 'integer',
        'min_level' => 'integer',
        'item_id' => 'integer',
        'item_count' => 'integer',
        'protect_type' => 'integer',
        'mask' => 'integer',
        'is_active' => 'boolean',
        'start_date' => 'datetime',
        'end_date' => 'datetime',
    ];

    /**
     * Get claims for this event
     */
    public function claims(): HasMany
    {
        return $this->hasMany(EventClaim::class, 'event_id');
    }

    /**
     * Get the admin who created this event
     */
    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by', 'ID');
    }

    public function scopeActive(Builder $query): Builder
    {
        return $query->where('is_active', true);
    }

    public function scopeWithinPeriod(Builder $query): Builder
    {
        return $query->where(function (Builder $q): void {
            $q->whereNull('start_date')
                ->orWhere('start_date', '<=', now());
        })->where(function (Builder $q): void {
            $q->whereNull('end_date')
                ->orWhere('end_date', '>=', now());
        });
    }

    /**
     * Get all active events
     */
    public static function getActiveEvents()
    {
        return self::active()
            ->withinPeriod()
            ->orderBy('milestone')
            ->get();
    }

    /**
     * Get current registration count
     */
    public static function getCurrentRegistrationCount(): int
    {
        return DB::table('users')->count();
    }

    /**
     * Check if a user is eligible for this event (milestone reached globally)
     */
    public function isUserEligible(int $userId): bool
    {
        // Check if the milestone has been reached globally
        // All users can claim once the total registration count reaches the milestone
        return $this->isMilestoneReached();
    }

    /**
     * Get the user ID who is the milestone user
     */
    public function getMilestoneUserId(): ?int
    {
        // Get the Nth user by ID order
        $user = DB::table('users')
            ->orderBy('ID')
            ->skip($this->milestone - 1)
            ->first();

        return $user ? $user->ID : null;
    }

    /**
     * Check if milestone is reached
     */
    public function isMilestoneReached(): bool
    {
        return self::getCurrentRegistrationCount() >= $this->milestone;
    }

    /**
     * Get events where user is eligible to claim
     */
    public static function getClaimableEventsForUser(int $userId): array
    {
        $events = self::getActiveEvents();
        $claimableEvents = [];

        foreach ($events as $event) {
            if ($event->isUserEligible($userId)) {
                // Check if not already claimed
                $claimed = EventClaim::where('event_id', $event->id)
                    ->where('user_id', $userId)
                    ->whereNotNull('claimed_at')
                    ->exists();

                if (!$claimed) {
                    $claimableEvents[] = $event;
                }
            }
        }

        return $claimableEvents;
    }

    /**
     * Get auto-generated mail title
     */
    public function getMailTitleAttribute($value): string
    {
        return $value ?? "Event Reward - {$this->name}";
    }
}
