<?php

/**
 * 文件功能：系统参数配置控制器
 * (替代原版 VIEWSYS.ASP / SetSYS.ASP)
 * 运维工具已迁移至 OpsController
 *
 * @author   ChatRoom Laravel
 *
 * @version  1.1.0
 */

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\SysParam;
use App\Services\ChatStateService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\View\View;

/**
 * 类功能：后台通用系统参数配置控制器
 * 仅允许维护低敏公共参数，站长专属敏感配置需走各自独立页面。
 */
class SystemController extends Controller
{
    /**
     * 构造函数注入聊天室状态服务
     */
    public function __construct(
        private readonly ChatStateService $chatState
    ) {}

    /**
     * 显示通用系统参数配置表单
     */
    public function edit(): View
    {
        $editableAliases = $this->editableSystemAliases();

        // 通用系统页仅加载白名单字段，避免站长专属配置被普通高管查看。
        $systemParams = SysParam::query()
            ->whereIn('alias', $editableAliases)
            ->orderBy('id')
            ->get(['alias', 'body', 'guidetxt']);

        $params = $systemParams->pluck('body', 'alias')->all();
        $descriptions = $systemParams->pluck('guidetxt', 'alias')->all();

        return view('admin.system.edit', compact('params', 'descriptions'));
    }

    /**
     * 更新全局参数，并刷新全站 Cache 缓存
     */
    public function update(Request $request): RedirectResponse
    {
        // 只接受通用系统页白名单内的字段，忽略任何伪造提交的敏感键。
        $data = $request->only($this->editableSystemAliases());

        foreach ($data as $alias => $body) {
            $normalizedBody = (string) $body;

            SysParam::updateOrCreate(
                ['alias' => $alias],
                ['body' => $normalizedBody]
            );

            // 仅对白名单字段同步缓存，杜绝越权请求覆盖站长专属配置。
            $this->chatState->setSysParam($alias, $normalizedBody);

            // 同时清除 Sysparam 模型的内部缓存
            SysParam::clearCache($alias);
        }

        return redirect()->route('admin.system.edit')->with('success', '系统参数已成功更新并生效！');
    }

    /**
     * 获取通用系统页允许维护的参数别名白名单
     *
     * @return array<int, string>
     */
    private function editableSystemAliases(): array
    {
        return SysParam::query()
            ->orderBy('id')
            ->pluck('alias')
            ->filter(fn (string $alias): bool => ! $this->isSensitiveAlias($alias))
            ->values()
            ->all();
    }

    /**
     * 判断参数是否属于站长专属敏感配置
     */
    private function isSensitiveAlias(string $alias): bool
    {
        if (Str::startsWith($alias, ['smtp_', 'vip_payment_', 'wechat_bot_', 'chatbot_'])) {
            return true;
        }

        return Str::endsWith($alias, ['_password', '_secret', '_token', '_key']);
    }
}
