using Flyshot.Server.Host;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;

namespace Flyshot.Server.Host.Controllers;

/// <summary>
/// 提供浏览器调试页所需的运行时配置 API。
/// </summary>
/// <remarks>
/// 本控制器自身不进入 Swagger 文档（<see cref="ApiExplorerSettingsAttribute.IgnoreApi"/>）。
/// 调试页静态资源位于 wwwroot，Swagger 地址由配置 API 下发。
/// </remarks>
[ApiController]
[ApiExplorerSettings(IgnoreApi = true)]
[Tags("基础与状态")]
public sealed class DebugConsoleController : ControllerBase
{
    /// <summary>
    /// Swagger 配置项，用于决定调试页是否对外暴露以及拼接 OpenAPI JSON 地址。
    /// </summary>
    private readonly HostSwaggerOptions _swaggerOptions;

    /// <summary>
    /// 初始化在线调试页控制器。
    /// </summary>
    /// <param name="swaggerOptions">来自 <c>Swagger</c> 配置节的标准选项。</param>
    public DebugConsoleController(IOptions<HostSwaggerOptions> swaggerOptions)
    {
        ArgumentNullException.ThrowIfNull(swaggerOptions);
        _swaggerOptions = swaggerOptions.Value ?? new HostSwaggerOptions();
    }

    /// <summary>
    /// 返回静态调试页启动时所需的 Swagger 文档地址。
    /// </summary>
    /// <returns>当 Swagger 启用时返回配置；否则返回 404，与 Swagger UI 保持一致的可见性策略。</returns>
    [HttpGet("/api/debug/config")]
    public IActionResult GetDebugConfig()
    {
        if (!_swaggerOptions.Enabled)
        {
            return NotFound();
        }

        return Ok(new
        {
            SwaggerJsonUrl = ResolveSwaggerJsonUrl(_swaggerOptions)
        });
    }

    /// <summary>
    /// 根据 <see cref="HostSwaggerOptions.JsonRouteTemplate"/> 与 <see cref="HostSwaggerOptions.DocumentName"/> 解析出 Swagger JSON 实际地址。
    /// </summary>
    /// <param name="options">Swagger 配置选项。</param>
    /// <returns>形如 <c>/swagger/v1/swagger.json</c> 的绝对路径。</returns>
    private static string ResolveSwaggerJsonUrl(HostSwaggerOptions options)
    {
        // Swashbuckle 的 RouteTemplate 不带前导斜杠，这里统一加上保证前端 fetch 走绝对路径。
        var template = options.JsonRouteTemplate ?? "swagger/{documentName}/swagger.json";
        var path = template.Replace("{documentName}", options.DocumentName ?? "v1", StringComparison.Ordinal);
        return path.StartsWith('/') ? path : "/" + path;
    }
}
