namespace Fengling.Console.Controllers;

using Fengling.Console.Services;

/// <summary>
/// 租户管理控制器
/// 提供租户的增删改查以及租户用户、角色、配置管理功能
/// </summary>
[ApiController]
[Route("api/console/[controller]")]
[Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)]
public class TenantsController : ControllerBase
{
    private readonly ITenantService _tenantService;
    private readonly IH5LinkService _h5LinkService;
    private readonly ILogger<TenantsController> _logger;

    public TenantsController(ITenantService tenantService, IH5LinkService h5LinkService, ILogger<TenantsController> logger)
    {
        _tenantService = tenantService;
        _h5LinkService = h5LinkService;
        _logger = logger;
    }

    /// <summary>
    /// 获取租户列表
    /// </summary>
    /// <param name="query">分页查询参数，支持按名称、租户编码和状态筛选</param>
    /// <returns>分页的租户列表，包含租户基本信息和状态</returns>
    /// <response code="200">成功返回租户分页列表</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet]
    [Produces("application/json")]
    [ProducesResponseType(typeof(PagedResultDto<TenantDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<PagedResultDto<TenantDto>>> GetTenants([FromQuery] TenantQueryDto query)
    {
        try
        {
            var (items, totalCount) = await _tenantService.GetTenantsAsync(query.Page, query.PageSize, query.Name,
                query.TenantId, query.Status);
            var result = new PagedResultDto<TenantDto>
            {
                Items = items.ToList(),
                TotalCount = totalCount,
                Page = query.Page,
                PageSize = query.PageSize
            };
            return Ok(result);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting tenants");
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 获取单个租户详情
    /// </summary>
    /// <param name="id">租户ID</param>
    /// <returns>租户的详细信息，包括配置、限额等信息</returns>
    /// <response code="200">成功返回租户详情</response>
    /// <response code="404">租户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("{id}")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(TenantDto), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<TenantDto>> GetTenant(int id)
    {
        try
        {
            var tenant = await _tenantService.GetTenantAsync(id);
            if (tenant == null)
            {
                return NotFound();
            }

            return Ok(tenant);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting tenant {TenantId}", id);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 获取指定租户的用户列表
    /// </summary>
    /// <param name="tenantId">租户ID</param>
    /// <returns>属于该租户的所有用户列表</returns>
    /// <response code="200">成功返回用户列表</response>
    /// <response code="404">租户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("{tenantId}/users")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(IEnumerable<UserDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<IEnumerable<UserDto>>> GetTenantUsers(int tenantId)
    {
        try
        {
            var users = await _tenantService.GetTenantUsersAsync(tenantId);
            return Ok(users);
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Tenant not found: {TenantId}", tenantId);
            return NotFound();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting users for tenant {TenantId}", tenantId);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 获取指定租户的角色列表
    /// </summary>
    /// <param name="tenantId">租户ID</param>
    /// <returns>属于该租户的所有角色列表</returns>
    /// <response code="200">成功返回角色列表</response>
    /// <response code="404">租户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("{tenantId}/roles")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(IEnumerable<object>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<IEnumerable<object>>> GetTenantRoles(int tenantId)
    {
        try
        {
            var roles = await _tenantService.GetTenantRolesAsync(tenantId);
            return Ok(roles);
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Tenant not found: {TenantId}", tenantId);
            return NotFound();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting roles for tenant {TenantId}", tenantId);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 获取租户配置信息
    /// </summary>
    /// <param name="id">租户ID</param>
    /// <returns>租户的详细配置信息，包括功能开关、配额限制等</returns>
    /// <response code="200">成功返回租户配置</response>
    /// <response code="404">租户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("{id}/settings")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(TenantSettingsDto), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<TenantSettingsDto>> GetTenantSettings(int id)
    {
        try
        {
            var settings = await _tenantService.GetTenantSettingsAsync(id);
            return Ok(settings);
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Tenant not found: {TenantId}", id);
            return NotFound();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting settings for tenant {TenantId}", id);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 更新租户配置
    /// </summary>
    /// <param name="id">租户ID</param>
    /// <param name="settings">需要更新的租户配置信息</param>
    /// <returns>无内容响应</returns>
    /// <response code="204">成功更新租户配置</response>
    /// <response code="404">租户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPut("{id}/settings")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<IActionResult> UpdateTenantSettings(int id, [FromBody] TenantSettingsDto settings)
    {
        try
        {
            await _tenantService.UpdateTenantSettingsAsync(id, settings);
            return NoContent();
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Tenant not found: {TenantId}", id);
            return NotFound();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error updating settings for tenant {TenantId}", id);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 创建新租户
    /// </summary>
    /// <param name="dto">创建租户所需的配置信息</param>
    /// <returns>创建的租户详情</returns>
    /// <response code="201">成功创建租户</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost]
    [Produces("application/json")]
    [ProducesResponseType(typeof(TenantDto), StatusCodes.Status201Created)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<TenantDto>> CreateTenant([FromBody] CreateTenantDto dto)
    {
        try
        {
            var tenant = await _tenantService.CreateTenantAsync(dto);
            return CreatedAtAction(nameof(GetTenant), new { id = tenant.Id }, tenant);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error creating tenant");
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 更新租户信息
    /// </summary>
    /// <param name="id">租户ID</param>
    /// <param name="dto">需要更新的租户配置信息</param>
    /// <returns>无内容响应</returns>
    /// <response code="204">成功更新租户</response>
    /// <response code="404">租户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPut("{id}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<IActionResult> UpdateTenant(int id, [FromBody] UpdateTenantDto dto)
    {
        try
        {
            await _tenantService.UpdateTenantAsync(id, dto);
            return NoContent();
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Tenant not found: {TenantId}", id);
            return NotFound();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error updating tenant {TenantId}", id);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 删除租户
    /// </summary>
    /// <param name="id">租户ID</param>
    /// <returns>无内容响应</returns>
    /// <response code="204">成功删除租户</response>
    /// <response code="404">租户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpDelete("{id}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<IActionResult> DeleteTenant(int id)
    {
        try
        {
            await _tenantService.DeleteTenantAsync(id);
            return NoContent();
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Tenant not found: {TenantId}", id);
            return NotFound();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error deleting tenant {TenantId}", id);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 生成H5访问链接和二维码
    /// </summary>
    /// <param name="id">租户ID</param>
    /// <returns>H5链接和二维码Base64</returns>
    /// <response code="200">成功返回链接和二维码</response>
    /// <response code="404">租户不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("{id}/h5-link")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(H5LinkResult), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<H5LinkResult>> GetH5Link(int id)
    {
        try
        {
            var result = await _h5LinkService.GenerateH5LinkAsync(id);
            return Ok(result);
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Tenant not found: {TenantId}", id);
            return NotFound(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error generating H5 link for tenant {TenantId}", id);
            return StatusCode(500, new { message = "Failed to generate H5 link" });
        }
    }
}