<?php

/**
 * 文件功能：后台 VIP 会员等级管理控制器
 * 提供会员等级的 CRUD（增删改查）功能
 * 后台可自由创建、修改、删除会员等级
 *
 * @author   ChatRoom Laravel
 *
 * @version  1.0.0
 */

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\VipLevel;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\View\View;

/**
 * 后台 VIP 会员等级管理控制器
 * 负责会员等级维护，以及查看各等级下的会员名单。
 */
class VipController extends Controller
{
    /**
     * 会员主题支持的特效下拉选项。
     *
     * @var array<string, string>
     */
    private const EFFECT_LABELS = [
        'none' => '无特效',
        'fireworks' => '烟花',
        'rain' => '下雨',
        'lightning' => '闪电',
        'snow' => '下雪',
        'sakura' => '樱花飘落',
        'meteors' => '流星',
        'gold-rain' => '金币雨',
        'hearts' => '爱心飘落',
        'confetti' => '彩带庆典',
        'fireflies' => '萤火虫',
    ];

    /**
     * 会员主题支持的横幅风格下拉选项。
     *
     * @var array<string, string>
     */
    private const BANNER_STYLE_LABELS = [
        'aurora' => '鎏光星幕',
        'storm' => '雷霆风暴',
        'royal' => '王者金辉',
        'cosmic' => '星穹幻彩',
        'farewell' => '告别暮光',
    ];

    /**
     * 会员等级管理列表页
     */
    public function index(): View
    {
        $levels = VipLevel::query()
            ->withCount('users')
            ->orderBy('sort_order')
            ->get();

        return view('admin.vip.index', [
            'levels' => $levels,
            'effectOptions' => self::EFFECT_LABELS,
            'bannerStyleOptions' => self::BANNER_STYLE_LABELS,
        ]);
    }

    /**
     * 查看某个会员等级下的会员名单。
     *
     * @param  Request  $request  当前筛选请求
     * @param  VipLevel  $vip  当前会员等级
     */
    public function members(Request $request, VipLevel $vip): View
    {
        $query = User::query()->where('vip_level_id', $vip->id);
        $now = now();

        if ($request->filled('keyword')) {
            $keyword = trim((string) $request->input('keyword'));

            // 支持后台按用户名快速筛选某个等级下的会员。
            $query->where('username', 'like', '%'.$keyword.'%');
        }

        if ($request->input('status') === 'active') {
            // 当前有效会员：永久会员或到期时间仍在未来。
            $query->where(function ($builder) use ($now): void {
                $builder->whereNull('hy_time')->orWhere('hy_time', '>', $now);
            });
        }

        if ($request->input('status') === 'expired') {
            // 已过期会员：到期时间存在且已经早于当前时间。
            $query->whereNotNull('hy_time')->where('hy_time', '<=', $now);
        }

        $members = $query
            ->select(['id', 'username', 'sex', 'vip_level_id', 'hy_time', 'created_at'])
            ->orderByRaw('CASE WHEN hy_time IS NULL THEN 0 WHEN hy_time > ? THEN 1 ELSE 2 END', [$now])
            ->orderByRaw('hy_time IS NULL DESC')
            ->orderByDesc('hy_time')
            ->orderBy('username')
            ->paginate(20)
            ->withQueryString();

        $totalAssignedCount = User::query()
            ->where('vip_level_id', $vip->id)
            ->count();

        $activeCount = User::query()
            ->where('vip_level_id', $vip->id)
            ->where(function ($builder) use ($now): void {
                $builder->whereNull('hy_time')->orWhere('hy_time', '>', $now);
            })
            ->count();

        return view('admin.vip.members', [
            'vip' => $vip,
            'members' => $members,
            'totalAssignedCount' => $totalAssignedCount,
            'activeCount' => $activeCount,
        ]);
    }

    /**
     * 新增会员等级
     */
    public function store(Request $request): RedirectResponse
    {
        $data = $this->validatedPayload($request);

        VipLevel::create($data);

        return redirect()->route('admin.vip.index')->with('success', '会员等级创建成功！');
    }

    /**
     * 更新会员等级
     *
     * @param  VipLevel  $vip  路由模型自动注入
     */
    public function update(Request $request, VipLevel $vip): RedirectResponse
    {
        $level = $vip;

        $data = $this->validatedPayload($request);

        $level->update($data);

        return redirect()->route('admin.vip.index')->with('success', '会员等级更新成功！');
    }

    /**
     * 删除会员等级（关联用户的 vip_level_id 会自动置 null）
     *
     * @param  VipLevel  $vip  路由模型自动注入
     */
    public function destroy(VipLevel $vip): RedirectResponse
    {
        $vip->delete();

        return redirect()->route('admin.vip.index')->with('success', '会员等级已删除！');
    }

    /**
     * 将多行文本转为 JSON 数组字符串
     * 每行一个模板，空行忽略
     *
     * @param  string  $text  多行文本
     * @return string|null JSON 字符串
     */
    private function textToJson(string $text): ?string
    {
        $lines = array_filter(
            array_map('trim', explode("\n", $text)),
            fn ($line) => $line !== ''
        );

        if (empty($lines)) {
            return null;
        }

        return json_encode(array_values($lines), JSON_UNESCAPED_UNICODE);
    }

    /**
     * 统一整理后台提交的会员等级主题配置数据。
     *
     * @return array<string, mixed>
     */
    private function validatedPayload(Request $request): array
    {
        $data = $request->validate([
            'name' => 'required|string|max:50',
            'icon' => 'required|string|max:20',
            'color' => 'required|string|max:10',
            'exp_multiplier' => 'required|numeric|min:1|max:99',
            'jjb_multiplier' => 'required|numeric|min:1|max:99',
            'sort_order' => 'required|integer|min:0',
            'price' => 'required|integer|min:0',
            'duration_days' => 'required|integer|min:0',
            'join_templates' => 'nullable|string',
            'leave_templates' => 'nullable|string',
            'join_effect' => ['required', 'string', Rule::in(VipLevel::EFFECT_OPTIONS)],
            'leave_effect' => ['required', 'string', Rule::in(VipLevel::EFFECT_OPTIONS)],
            'join_banner_style' => 'required|in:aurora,storm,royal,cosmic,farewell',
            'leave_banner_style' => 'required|in:aurora,storm,royal,cosmic,farewell',
            'allow_custom_messages' => 'nullable|boolean',
        ]);

        // 将多行文本框内容转为 JSON 数组，便于后续随机抽取模板。
        $data['join_templates'] = $this->textToJson($data['join_templates'] ?? '');
        $data['leave_templates'] = $this->textToJson($data['leave_templates'] ?? '');
        $data['allow_custom_messages'] = $request->boolean('allow_custom_messages');

        return $data;
    }
}
