namespace Fengling.Console.Controllers;

/// <summary>
/// 网关管理控制器
/// 提供网关服务、路由、集群实例等配置管理功能
/// </summary>
[ApiController]
[Route("api/console/[controller]")]
[Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)]
public class GatewayController(IGatewayService gatewayService, ILogger<GatewayController> logger)
    : ControllerBase
{
    /// <summary>
    /// 获取网关统计数据
    /// </summary>
    /// <returns>网关的整体统计信息，包括请求量、响应时间等指标</returns>
    /// <response code="200">成功返回网关统计数据</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("statistics")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(GatewayStatisticsDto), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<GatewayStatisticsDto>> GetStatistics()
    {
        try
        {
            var statistics = await gatewayService.GetStatisticsAsync();
            return Ok(statistics);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error getting gateway statistics");
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 获取网关服务列表
    /// </summary>
    /// <param name="globalOnly">是否只返回全局服务，默认为false</param>
    /// <param name="tenantCode">租户编码，用于筛选特定租户的服务</param>
    /// <returns>网关服务列表，包含服务名称、地址、健康状态等信息</returns>
    /// <response code="200">成功返回网关服务列表</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("services")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(List<GatewayServiceDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<List<GatewayServiceDto>>> GetServices(
        [FromQuery] bool globalOnly = false,
        [FromQuery] string? tenantCode = null)
    {
        try
        {
            var services = await gatewayService.GetServicesAsync(globalOnly, tenantCode);
            return Ok(services);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error getting gateway services");
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 获取单个网关服务详情
    /// </summary>
    /// <param name="serviceName">服务名称</param>
    /// <param name="tenantCode">租户编码，用于筛选特定租户的服务</param>
    /// <returns>网关服务的详细信息</returns>
    /// <response code="200">成功返回服务详情</response>
    /// <response code="404">服务不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("services/{serviceName}")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(GatewayServiceDto), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<GatewayServiceDto>> GetService(
        string serviceName,
        [FromQuery] string? tenantCode = null)
    {
        try
        {
            var service = await gatewayService.GetServiceAsync(serviceName, tenantCode);
            if (service == null)
            {
                return NotFound(new { message = $"Service {serviceName} not found" });
            }
            return Ok(service);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error getting service {ServiceName}", serviceName);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 注册新的网关服务
    /// </summary>
    /// <param name="dto">创建服务所需的配置信息</param>
    /// <returns>创建的服务详情</returns>
    /// <response code="201">成功创建服务</response>
    /// <response code="400">请求参数无效或服务已存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost("services")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(GatewayServiceDto), StatusCodes.Status201Created)]
    [ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<GatewayServiceDto>> RegisterService([FromBody] CreateGatewayServiceDto dto)
    {
        try
        {
            var service = await gatewayService.RegisterServiceAsync(dto);
            return CreatedAtAction(nameof(GetService), new { serviceName = service.ServicePrefix }, service);
        }
        catch (InvalidOperationException ex)
        {
            logger.LogWarning(ex, "Validation error registering service");
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error registering service");
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 注销网关服务
    /// </summary>
    /// <param name="serviceName">要注销的服务名称</param>
    /// <param name="tenantCode">租户编码，用于筛选特定租户的服务</param>
    /// <returns>无内容响应</returns>
    /// <response code="200">成功注销服务</response>
    /// <response code="404">服务不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpDelete("services/{serviceName}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult> UnregisterService(
        string serviceName,
        [FromQuery] string? tenantCode = null)
    {
        try
        {
            var result = await gatewayService.UnregisterServiceAsync(serviceName, tenantCode);
            if (!result)
            {
                return NotFound(new { message = $"Service {serviceName} not found" });
            }
            return Ok(new { message = "Service unregistered successfully" });
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error unregistering service {ServiceName}", serviceName);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 获取网关路由列表
    /// </summary>
    /// <param name="globalOnly">是否只返回全局路由，默认为false</param>
    /// <returns>网关路由列表，包含路径匹配规则、转发目标等信息</returns>
    /// <response code="200">成功返回网关路由列表</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("routes")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(List<GatewayRouteDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<List<GatewayRouteDto>>> GetRoutes([FromQuery] bool globalOnly = false)
    {
        try
        {
            var routes = await gatewayService.GetRoutesAsync(globalOnly);
            return Ok(routes);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error getting gateway routes");
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 创建新的网关路由
    /// </summary>
    /// <param name="dto">创建路由所需的配置信息</param>
    /// <returns>创建的路由详情</returns>
    /// <response code="201">成功创建路由</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost("routes")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(GatewayRouteDto), StatusCodes.Status201Created)]
    [ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<GatewayRouteDto>> CreateRoute([FromBody] CreateGatewayRouteDto dto)
    {
        try
        {
            var route = await gatewayService.CreateRouteAsync(dto);
            return Ok(route);
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error creating gateway route");
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 获取集群实例列表
    /// </summary>
    /// <param name="clusterId">集群ID</param>
    /// <returns>指定集群下的所有服务实例列表</returns>
    /// <response code="200">成功返回实例列表</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("clusters/{clusterId}/instances")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(List<GatewayInstanceDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<List<GatewayInstanceDto>>> GetInstances(string clusterId)
    {
        try
        {
            var instances = await gatewayService.GetInstancesAsync(clusterId);
            return Ok(instances);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error getting instances for cluster {ClusterId}", clusterId);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 添加服务实例到集群
    /// </summary>
    /// <param name="dto">创建实例所需的配置信息</param>
    /// <returns>创建的实例详情</returns>
    /// <response code="201">成功添加实例</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost("instances")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(GatewayInstanceDto), StatusCodes.Status201Created)]
    [ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<GatewayInstanceDto>> AddInstance([FromBody] CreateGatewayInstanceDto dto)
    {
        try
        {
            var instance = await gatewayService.AddInstanceAsync(dto);
            return CreatedAtAction(nameof(GetInstances), new { clusterId = dto.ClusterId }, instance);
        }
        catch (InvalidOperationException ex)
        {
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error adding instance to cluster {ClusterId}", dto.ClusterId);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 移除服务实例
    /// </summary>
    /// <param name="instanceId">实例ID</param>
    /// <returns>无内容响应</returns>
    /// <response code="200">成功移除实例</response>
    /// <response code="404">实例不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpDelete("instances/{instanceId}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult> RemoveInstance(long instanceId)
    {
        try
        {
            var result = await gatewayService.RemoveInstanceAsync(instanceId);
            if (!result)
            {
                return NotFound(new { message = $"Instance {instanceId} not found" });
            }
            return Ok(new { message = "Instance removed successfully" });
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error removing instance {InstanceId}", instanceId);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 更新实例权重
    /// 用于负载均衡策略中调整实例的请求分发权重
    /// </summary>
    /// <param name="instanceId">实例ID</param>
    /// <param name="dto">包含新权重值的请求体</param>
    /// <returns>无内容响应</returns>
    /// <response code="200">成功更新权重</response>
    /// <response code="404">实例不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPut("instances/{instanceId}/weight")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult> UpdateWeight(long instanceId, [FromBody] GatewayUpdateWeightDto dto)
    {
        try
        {
            var result = await gatewayService.UpdateInstanceWeightAsync(instanceId, dto.Weight);
            if (!result)
            {
                return NotFound(new { message = $"Instance {instanceId} not found" });
            }
            return Ok(new { message = "Weight updated successfully" });
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error updating weight for instance {InstanceId}", instanceId);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 重新加载网关配置
    /// 触发网关重新加载所有配置，包括路由、服务、集群等配置
    /// </summary>
    /// <returns>无内容响应</returns>
    /// <response code="200">成功重新加载配置</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost("reload")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult> ReloadGateway()
    {
        try
        {
            await gatewayService.ReloadGatewayAsync();
            return Ok(new { message = "Gateway configuration reloaded successfully" });
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error reloading gateway configuration");
            return StatusCode(500, new { message = ex.Message });
        }
    }
}
