using System;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using CncModels.Dto;
using CncModels.Constants;

namespace CncWebApi.Infrastructure
{
    /// <summary>
    /// JWT 认证过滤器
    /// 验证请求 Header 中的 Bearer Token
    /// 管理 /api/admin/** 接口需要认证，大屏 /api/screen/** 不需要
    /// </summary>
    public class JwtAuthFilter : AuthorizationFilterAttribute
    {
        /// <inheritdoc/>
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            // 从 Header 读取 Authorization
            var authHeader = actionContext.Request.Headers.Authorization;
            if (authHeader == null || !string.Equals(authHeader.Scheme, "Bearer", StringComparison.OrdinalIgnoreCase))
            {
                Reject(actionContext, "Token缺失");
                return;
            }

            var token = authHeader.Parameter;
            if (string.IsNullOrWhiteSpace(token))
            {
                Reject(actionContext, "Token为空");
                return;
            }

            // 验证 JWT
            try
            {
                var parts = token.Split('.');
                if (parts.Length != 3)
                {
                    Reject(actionContext, "Token格式无效");
                    return;
                }

                // 从 Web.config 读取密钥
                var secret = System.Configuration.ConfigurationManager.AppSettings["JwtSecret"];
                if (string.IsNullOrEmpty(secret))
                {
                    Reject(actionContext, "服务端配置错误");
                    return;
                }

                // 验证签名
                using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
                {
                    var expectedSig = Base64UrlEncode(hmac.ComputeHash(Encoding.UTF8.GetBytes(parts[0] + "." + parts[1])));
                    if (!string.Equals(expectedSig, parts[2], StringComparison.Ordinal))
                    {
                        Reject(actionContext, "Token签名无效");
                        return;
                    }
                }

                // 检查过期
                var payloadBytes = Base64UrlDecode(parts[1]);
                var payloadJson = Encoding.UTF8.GetString(payloadBytes);
                var expMatch = System.Text.RegularExpressions.Regex.Match(payloadJson, @"""exp"":(\d+)");
                if (expMatch.Success)
                {
                    var exp = long.Parse(expMatch.Groups[1].Value);
                    var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
                    if (now > exp)
                    {
                        Reject(actionContext, "Token已过期");
                        return;
                    }
                }
            }
            catch (Exception)
            {
                Reject(actionContext, "Token验证失败");
                return;
            }
        }

        private void Reject(HttpActionContext actionContext, string message)
        {
            var response = ApiResponse<object>.Fail(ErrorCode.Unauthorized, message);
            actionContext.Response = actionContext.Request.CreateResponse(
                HttpStatusCode.OK, response);
        }

        private static string Base64UrlEncode(byte[] input)
        {
            return Convert.ToBase64String(input).Replace("+", "-").Replace("/", "_").TrimEnd('=');
        }

        private static byte[] Base64UrlDecode(string input)
        {
            var base64 = input.Replace("-", "+").Replace("_", "/");
            switch (base64.Length % 4)
            {
                case 2: base64 += "=="; break;
                case 3: base64 += "="; break;
            }
            return Convert.FromBase64String(base64);
        }
    }
}
