<?php

/**
 * 文件功能：钓鱼事件模型
 *
 * 对应 fishing_events 表，每条记录是一个钓鱼随机奖惩事件。
 * 概率由 weight（权重）字段决定，权重越大被选中概率越高。
 *
 * @author   ChatRoom Laravel
 *
 * @version  1.0.0
 */

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class FishingEvent extends Model
{
    /**
     * 可批量赋值字段
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'emoji',
        'name',
        'message',
        'exp',
        'jjb',
        'weight',
        'is_active',
        'sort',
    ];

    /**
     * 字段类型转换
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'exp' => 'integer',
            'jjb' => 'integer',
            'weight' => 'integer',
            'is_active' => 'boolean',
            'sort' => 'integer',
        ];
    }

    /**
     * 作用域：只查询已启用的事件
     */
    public function scopeActive(Builder $query): Builder
    {
        return $query->where('is_active', true);
    }

    /**
     * 根据权重随机抽取一个激活的钓鱼事件
     *
     * 实现加权随机：权重越大，被选中概率越高。
     * 若无任何激活事件，返回 null。
     */
    public static function rollOne(): ?static
    {
        $events = static::active()->orderBy('sort')->get();
        if ($events->isEmpty()) {
            return null;
        }

        // 计算总权重后加权随机
        $totalWeight = $events->sum('weight');
        $roll = random_int(1, max($totalWeight, 1));
        $cumulative = 0;

        foreach ($events as $event) {
            $cumulative += $event->weight;
            if ($roll <= $cumulative) {
                return $event;
            }
        }

        // 兜底：返回最后一个
        return $events->last();
    }
}
