<?php

/**
 * 文件功能：神秘箱子模型
 *
 * 管理聊天室内投放的神秘箱记录，提供领取状态管理及类型标签工具方法。
 * 对应表：mystery_boxes
 *
 * @author  ChatRoom Laravel
 *
 * @version 1.0.0
 */

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;

class MysteryBox extends Model
{
    protected $fillable = [
        'box_type',
        'passcode',
        'reward_min',
        'reward_max',
        'status',
        'expires_at',
        'dropped_by',
    ];

    /**
     * 属性类型转换。
     */
    protected function casts(): array
    {
        return [
            'reward_min' => 'integer',
            'reward_max' => 'integer',
            'expires_at' => 'datetime',
        ];
    }

    // ─── 关联关系 ────────────────────────────────────────────────────

    /**
     * 领取记录（一个箱子只能被一人领取，但关联为 HasOne）
     */
    public function claim(): HasOne
    {
        return $this->hasOne(MysteryBoxClaim::class);
    }

    /**
     * 所有领取记录（逻辑上只有一条，保留 HasMany 供统计使用）
     */
    public function claims(): HasMany
    {
        return $this->hasMany(MysteryBoxClaim::class);
    }

    // ─── 查询作用域 ──────────────────────────────────────────────────

    /**
     * 当前可领取（open 状态 + 未过期）的箱子。
     */
    public static function currentOpenBox(): ?static
    {
        return static::query()
            ->where('status', 'open')
            ->where(fn ($q) => $q->whereNull('expires_at')->orWhere('expires_at', '>', now()))
            ->latest()
            ->first();
    }

    // ─── 工具方法 ────────────────────────────────────────────────────

    /**
     * 返回箱子类型的 emoji 前缀。
     */
    public function typeEmoji(): string
    {
        return match ($this->box_type) {
            'normal' => '📦',
            'rare' => '💎',
            'trap' => '☠️',
            default => '📦',
        };
    }

    /**
     * 返回箱子类型中文名称。
     */
    public function typeName(): string
    {
        return match ($this->box_type) {
            'normal' => '普通箱',
            'rare' => '稀有箱',
            'trap' => '黑化箱',
            default => '神秘箱',
        };
    }

    /**
     * 随机生成奖励金额（trap 类型为负数）。
     */
    public function rollReward(): int
    {
        $amount = random_int(
            min(abs($this->reward_min), abs($this->reward_max)),
            max(abs($this->reward_min), abs($this->reward_max)),
        );

        // trap 类型：倒扣金币（负数）
        return $this->box_type === 'trap' ? -$amount : $amount;
    }

    /**
     * 判断箱子是否已过期
     */
    public function isExpired(): bool
    {
        return $this->expires_at !== null && $this->expires_at->isPast();
    }
}
