using System.Text.Json;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MiGu.Server.Configs;

namespace MiGu.Server.Controllers;

// AR-4: 全 class 加 [Authorize] —— 替代会话21 点名的「ConfigController 无鉴权 PUT 任意 section」漏洞。
// GET (List/Get) 只要登录就放；PUT 按 scope 收紧：Platform 任意节，RCSMonitor 仅 ops 白名单。
[ApiController]
[Authorize]
[Route("api/config")]
public class ConfigController : ControllerBase
{
    private readonly ConfigStore _store;

    public ConfigController(ConfigStore store)
    {
        _store = store;
    }

    [HttpGet]
    public IActionResult List()
    {
        var envs = _store.List().Select(e => new
        {
            section = e.Section,
            version = e.Version,
            updatedAt = e.UpdatedAt
        });
        return Ok(envs);
    }

    [HttpGet("{section}")]
    public IActionResult Get(string section)
    {
        if (!ConfigStore.AllSections.Contains(section, StringComparer.OrdinalIgnoreCase))
            return NotFound(new { message = $"未知 section: {section}" });

        var env = _store.Get(section);
        return Ok(new
        {
            section = env.Section,
            version = env.Version,
            updatedAt = env.UpdatedAt,
            payload = env.Payload
        });
    }

    /// <summary>RCSMonitor scope 允许写入的 section 白名单（地图监控动作备份等运营自有配置）。</summary>
    private static readonly string[] MonitorWritableSections = { "ops" };

    // Platform scope 可写任意 section；RCSMonitor 仅允许写 ops（保留运营端
    // 「地图监控动作 ops.monitor 备份」既有功能），其余 section（routing/auth/system 等）一律 403。
    [HttpPut("{section}")]
    public IActionResult Put(string section, [FromBody] JsonElement payload)
    {
        if (!ConfigStore.AllSections.Contains(section, StringComparer.OrdinalIgnoreCase))
            return NotFound(new { message = $"未知 section: {section}" });

        var scope = User.FindFirst("scope")?.Value;
        if (!string.Equals(scope, "Platform", StringComparison.OrdinalIgnoreCase)
            && !MonitorWritableSections.Contains(section, StringComparer.OrdinalIgnoreCase))
        {
            return StatusCode(403, new { message = $"当前账号无权修改配置节 {section}（需要 Platform 管理端权限）" });
        }

        var env = _store.Put(section, payload);
        return Ok(new
        {
            section = env.Section,
            version = env.Version,
            updatedAt = env.UpdatedAt,
            payload = env.Payload
        });
    }
}
