using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;
using InvalidOperationException = System.InvalidOperationException;

namespace Infrastructure.Helpers
{
    /// <summary>
    /// 大华平台API访问工具类
    /// </summary>
    public class DaHuaApi
    {
        private readonly HttpClient _httpClient;
        private readonly string _baseUrl = "https://icc-dev.hibetatest.com:4077";
        private readonly string _kccKey;
        private readonly string _kccSecret;
        private readonly string _kccId;
        private static OAuthTokenResponse _currentToken;
        private static DateTime _tokenExpiry;

        /// <summary>
        /// 构造函数（KCC认证方式）
        /// </summary>
        /// <param name="baseUrl">API基础URL</param>
        /// <param name="kccId">KCC ID</param>
        /// <param name="kccKey">KCC Key</param>
        /// <param name="kccSecret">KCC Secret</param>
        public DaHuaApi(string baseUrl, string kccId, string kccKey, string kccSecret)
        {
            _baseUrl = baseUrl;
            _kccId = kccId;
            _kccKey = kccKey;
            _kccSecret = kccSecret;
            _httpClient = new HttpClient();
        }

        /// <summary>
        /// 构造函数（OAuth2认证方式）
        /// </summary>
        /// <param name="baseUrl">API基础URL</param>
        public DaHuaApi(string baseUrl)
        {
            _baseUrl = baseUrl;
            _httpClient = new HttpClient();
        }

        /// <summary>
        /// 使用用户名密码方式进行OAuth2认证获取Token
        /// </summary>
        /// <param name="clientId">客户端ID</param>
        /// <param name="clientSecret">客户端密钥</param>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns>认证结果</returns>
        public async Task<OAuthTokenResponse> AuthenticateAsync(string clientId, string clientSecret, string username,
            string password)
        {
            // 1. 获取公钥
            var publicKeyResponse =
                await _httpClient.GetAsync($"{_baseUrl}/evo-apigw/evo-oauth/1.0.0/oauth/public-key");
            var publicKeyResult =
                JsonConvert.DeserializeObject<PublicKeyResponse>(await publicKeyResponse.Content.ReadAsStringAsync());

            if (!publicKeyResult.Success)
            {
                throw new InvalidOperationException($"获取公钥失败: {publicKeyResult.ErrMsg}");
            }

            var encryptedPassword = RsaHelper.Encrypt(password, publicKeyResult.Data.PublicKey);

            // 3. 获取Token
            var tokenRequest = new
            {
                grant_type = "password",
                username = username,
                password = encryptedPassword,
                client_id = clientId,
                client_secret = clientSecret,
                public_key = publicKeyResult.Data.PublicKey
            };

            var json = JsonConvert.SerializeObject(tokenRequest);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            var tokenResponse =
                await _httpClient.PostAsync($"{_baseUrl}/evo-apigw/evo-oauth/1.0.0/oauth/extend/token", content);
            var result = await tokenResponse.Content.ReadAsStringAsync();
            // {"success":true,"data":{"access_token":"2:3hRw0P7m3YD7skQwL9qNoPtcg9by378W","refresh_token":"KGnWspOzRdwFcD9D3bKztHc12H41vNjT","magicId":"TjNv14H21cHtzKb3D9DcFwdRzOpsWnGK","scope":"supplier","remainderDays":166,"token_type":"bearer","expires_in":7199,"userId":"2"},"code":"0","errMsg":""}
            var tokenResult =
                JsonConvert.DeserializeObject<OAuthTokenResponse>(result);

            if (tokenResult.success)
            {
                _currentToken = tokenResult;
                _tokenExpiry = DateTime.UtcNow.AddSeconds(tokenResult.data.expires_in - 60); // 提前60秒过期以避免边界问题
            }
            else
            {
                throw new InvalidOperationException($"获取Token失败: {tokenResult.errMsg}");
            }

            return tokenResult;
        }


        /// <summary>
        /// 确保Token有效
        /// </summary>
        private async Task EnsureValidTokenAsync()
        {
            if (_currentToken == null  || DateTime.UtcNow > _tokenExpiry)
            {
                await AuthenticateAsync("CompanyName", "42bec152-8f04-476a-9aec-e7d616ff3cb3",
                    "TEST", "OGR28u6_cc");
            }
        }

        /// <summary>
        /// 生成KCC签名
        /// </summary>
        /// <param name="method">HTTP方法</param>
        /// <param name="uri">请求URI</param>
        /// <param name="body">请求体</param>
        /// <param name="timestamp">时间戳</param>
        /// <returns>KCC签名字符串</returns>
        private string GenerateKccSignature(string method, string uri, string body, long timestamp)
        {
            // 构建签名原文
            var signString = $"POST\n{uri}\n{body}\n{_kccId}\n{timestamp}";

            // 使用HMAC-SHA1算法计算签名
            using (var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(_kccSecret)))
            {
                var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(signString));
                return Convert.ToBase64String(hashBytes);
            }
        }

        /// <summary>
        /// 设置请求的认证头部
        /// </summary>
        /// <param name="uri">请求URI</param>
        /// <param name="json">请求体JSON</param>
        private async Task SetAuthorizationHeaderAsync(string uri, string json)
        {
            _httpClient.DefaultRequestHeaders.Clear();
            // 如果有KCC配置，使用KCC认证
            if (!string.IsNullOrEmpty(_kccId) && !string.IsNullOrEmpty(_kccKey) && !string.IsNullOrEmpty(_kccSecret))
            {
                var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
                var signature = GenerateKccSignature("POST", uri, json, timestamp);

                _httpClient.DefaultRequestHeaders.Add("KCC-ID", _kccId);
                _httpClient.DefaultRequestHeaders.Add("KCC-TS", timestamp.ToString());
                _httpClient.DefaultRequestHeaders.Add("KCC-SIGN", signature);
            }
            // 如果有Token，使用OAuth2认证
            else
            {
                await EnsureValidTokenAsync();
                _httpClient.DefaultRequestHeaders.Add("Authorization",
                    $"{_currentToken.data.token_type} {_currentToken.data.access_token}");
            }
        }

        /// <summary>
        /// 获取设备通道分类信息
        /// 对应接口: /evo-api/go/geo-term/i.a.o/device/channel/subsystem/page
        /// </summary>
        /// <param name="request">请求参数</param>
        /// <returns>通道分类信息响应</returns>
        public async Task<ChannelCategoryResponse> GetChannelCategoriesAsync(ChannelCategoryRequest request)
        {
            var url = $"{_baseUrl}/evo-apigw/evo-brm/1.2.0/device/channel/subsystem/page";
            var uri = "/evo-apigw/evo-brm/1.2.0/device/channel/subsystem/page";

            var json = JsonConvert.SerializeObject(request);

            // 设置认证头部
            await SetAuthorizationHeaderAsync(uri, json);

            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var response = await _httpClient.PostAsync(url, content);
            var responseString = await response.Content.ReadAsStringAsync();

            if (response.IsSuccessStatusCode)
            {
                // {"success":true,
                // "data":{"pageData":
                // [{"id":110,"deviceCode":"1000102","unitType":1,
                // "unitSeq":0,"channelSeq":0,"channelCode":"1000102$1$0$0",
                // "channelName":"1.1.1.1_1","channelType":"1","cameraType":"2",
                // "ownerCode":"001001","gpsX":"","gpsY":"","isOnline":0,
                // "stat":1,"capability":"00000000000000000000000000000001","chExt":"{}",
                // "isVirtual":0,"createTime":"2025-11-11 15:43:30"},
                // {"id":108,"deviceCode":"1000099","unitType":7,"unitSeq":0,"channelSeq":0,"channelCode":"1000099$7$0$0",
                // "channelSn":"","channelName":"膨化食品测试设备-1_门禁通道_1",
                // "ownerCode":"001010","isOnline":0,"stat":1,
                // "chExt":"{\"workStatus\":5,\"psamEnable\":0,\"isUse\":\"0\",
                // \"channelBindFace\":\"\",\"channelBindOrg\":\"\",\"cpuCardEnable\":1,
                // \"physicalId\":\"\",\"channelCapacity\":5,\"channelUnii\":\"\",\"closeTimeOut\":60,\"icCardEnable\":1,\"collaborativeEnable\":0,\"snapshotUpload\":0,\"enableMode\":0,\"timeoutAlarmEnable\":0,\"manapassword\":\"12345678\",\"collectTypeFlag\":7,\"channelPersonType\":1,\"nfcAntiCopyEnable\":0,\"readerList\":[{\"name\":\"膨化食品测试设备-1_门禁通道_1读卡器1\",\"code\":1,\"openType\":26,\"businessType\":1},{\"name\":\"膨化食品测试设备-1_门禁通道_1读卡器2\",\"code\":2,\"openType\":26,\"businessType\":2}],\"icEncryptEnable\":0,\"delayTime\":3,\"status\":\"5\"}","isVirtual":0,"createTime":"2025-11-06 13:31:30"},{"id":109,"deviceCode":"1000099","unitType":1,"unitSeq":0,"channelSeq":0,"channelCode":"1000099$1$0$0","channelSn":"","channelName":"膨化食品测试设备-1_视频通道_1","channelType":"1","cameraType":"2","ownerCode":"001010","isOnline":0,"stat":1,"capability":"00000000000000000000000000000000","chExt":"{\"keyCode\":\"\"}","isVirtual":0,"createTime":"2025-11-06 13:31:30"},{"id":63,"deviceCode":"1000056","unitType":1,"unitSeq":0,"channelSeq":0,"channelCode":"1000056$1$0$0","channelName":"127.0.0.2_1","channelType":"1","cameraType":"2","ownerCode":"001006","gpsX":"","gpsY":"","isOnline":0,"stat":1,"capability":"00000000000000000000001100000001","chExt":"{\"keyCode\":\"\"}","isVirtual":0,"createTime":"2025-09-25 16:22:56"},{"id":10,"deviceCode":"1000008","unitType":1,"unitSeq":0,"channelSeq":0,"channelCode":"1000008$1$0$0","channelSn":"1007749","channelName":"IPC10001001_1","channelType":"1","cameraType":"2","ownerCode":"001002001","gpsX":"","gpsY":"","isOnline":1,"stat":1,"capability":"00000000000000000000000100000001","chExt":"{\"keyCode\":\"\"}","isVirtual":0,"createTime":"2025-09-09 16:18:44"},{"id":4,"deviceCode":"1000002","unitType":4,"unitSeq":0,"channelSeq":0,"channelCode":"1000002$4$0$0","channelName":"9G0D671YAJB4F8F_1","ownerCode":"001001","gpsX":"","gpsY":"","isOnline":1,"stat":1,"isVirtual":0,"createTime":"2025-09-08 20:36:40"},{"id":3,"deviceCode":"1000002","unitType":3,"unitSeq":0,"channelSeq":1,"channelCode":"1000002$3$0$1","channelName":"9G0D671YAJB4F8F_2","ownerCode":"001001","gpsX":"","gpsY":"","isOnline":1,"stat":1,"chExt":"{\"alarmType\":\"2\",\"alarmLevel\":\"1\"}","isVirtual":0,"createTime":"2025-09-08 20:36:40"},{"id":2,"deviceCode":"1000002","unitType":3,"unitSeq":0,"channelSeq":0,"channelCode":"1000002$3$0$0","channelName":"9G0D671YAJB4F8F_1","ownerCode":"001001","gpsX":"","gpsY":"","isOnline":1,"stat":1,"chExt":"{\"alarmType\":\"6001\",\"alarmLevel\":\"1\"}","isVirtual":0,"createTime":"2025-09-08 20:36:40"},{"id":1,"deviceCode":"1000002","unitType":1,"unitSeq":0,"channelSeq":0,"channelCode":"1000002$1$0$0","channelName":"DH-SD-6C3232-HNY-DB-EFR","channelType":"1","cameraType":"2","ownerCode":"001001","gpsX":"120.519063","gpsY":"30.381539","isOnline":1,"stat":1,"capability":"00000000000000010000000000000001","chExt":"{}","isVirtual":0,"createTime":"2025-09-08 20:36:40"}],"currentPage":1,"totalPage":1,"pageSize":10,"totalRows":9},"code":"0","errMsg":""}
                return JsonConvert.DeserializeObject<ChannelCategoryResponse>(responseString);
            }

            throw new HttpRequestException($"请求失败: {response.StatusCode}, {responseString}");
        }

        /// <summary>
        /// 启动RTSP实时预览
        /// 对应接口: /evo-api/go/admin/API/MTS/Video/StartVideo
        /// </summary>
        /// <param name="request">预览请求参数</param>
        /// <returns>RTSP预览响应</returns>
        public async Task<RtspPreviewResponse> StartRtspPreviewAsync(RtspPreviewRequest request)
        {
            var url = $"{_baseUrl}/evo-apigw/admin/API/MTS/Video/StartVideo";
            var uri = "/evo-apigw/admin/API/MTS/Video/StartVideo";

            var requestData = new Dictionary<string, object>
            {
                ["data"] = request.data
            };
            var json = JsonConvert.SerializeObject(requestData);

            // 设置认证头部
            await SetAuthorizationHeaderAsync(uri, json);

            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var response = await _httpClient.PostAsync(url, content);
            var responseString = await response.Content.ReadAsStringAsync();

            if (response.IsSuccessStatusCode)
            {
                return JsonConvert.DeserializeObject<RtspPreviewResponse>(responseString);
            }

            throw new HttpRequestException($"请求失败: {response.StatusCode}, {responseString}");
        }
    }

    #region OAuth2认证相关模型

    /// <summary>
    /// 公钥响应
    /// </summary>
    public class PublicKeyResponse
    {
        public bool Success { get; set; }
        public string Code { get; set; }
        public string ErrMsg { get; set; }
        public PublicKeyData Data { get; set; }
    }

    /// <summary>
    /// 公钥数据
    /// </summary>
    public class PublicKeyData
    {
        public string PublicKey { get; set; }
    }

    /// <summary>
    /// OAuth2 Token响应
    /// </summary>
    public class OAuthTokenResponse
    {
        public bool success { get; set; }
        public string code { get; set; }
        public string errMsg { get; set; }
        public OAuthTokenData data { get; set; }
    }

    /// <summary>
    /// OAuth2 Token数据
    /// </summary>
    public class OAuthTokenData
    {
        public string access_token { get; set; }
        public string refresh_token { get; set; }
        public string magicId { get; set; }
        public string scope { get; set; }
        public int remainderDays { get; set; }
        public string token_type { get; set; }
        public long expires_in { get; set; }
        public string userId { get; set; }
    }

    #endregion

    #region ChannelCategory相关模型定义

    /// <summary>
    /// 设备通道分类请求参数
    /// </summary>
    public class ChannelCategoryRequest
    {
        /// <summary>
        /// 当前页码
        /// </summary>
        public int pageNum { get; set; } = 1;

        /// <summary>
        /// 每页大小
        /// </summary>
        public int pageSize { get; set; } = 10;

        /// <summary>
        /// 排序字段
        /// </summary>
        public string sort { get; set; }

        /// <summary>
        /// 排序方式 ASC/DESC
        /// </summary>
        public string sortType { get; set; }

        /// <summary>
        /// 所有者编码
        /// </summary>
        public string ownerCode { get; set; }

        /// <summary>
        /// 设备编码列表
        /// </summary>
        public List<string> deviceCodeList { get; set; }

        /// <summary>
        /// 通道编码列表
        /// </summary>
        public List<string> channelCodeList { get; set; }

        /// <summary>
        /// 设备大类
        /// </summary>
        public int? deviceCategory { get; set; }

        /// <summary>
        /// 设备小类
        /// </summary>
        public int? deviceType { get; set; }

        /// <summary>
        /// 单元类型列表
        /// </summary>
        public List<int> unitTypeList { get; set; }

        /// <summary>
        /// 通道类型列表
        /// </summary>
        public List<int> channelTypeList { get; set; }

        /// <summary>
        /// 是否在线
        /// </summary>
        public int? isOnline { get; set; }

        /// <summary>
        /// 是否已接入
        /// </summary>
        public int? access { get; set; }

        /// <summary>
        /// 是否虚拟
        /// </summary>
        public int? isVirtual { get; set; }

        /// <summary>
        /// 设备通道状态
        /// </summary>
        public int? stat { get; set; }

        /// <summary>
        /// 是否包含子设备编码标签
        /// </summary>
        public bool includeSubOwnerCodeFlag { get; set; }
    }

    /// <summary>
    /// 通道分类查询响应
    /// </summary>
    public class ChannelCategoryResponse
    {
        public string errMsg { get; set; }

        public bool success { get; set; }

        /// <summary>
        /// 状态码
        /// </summary>
        public int code { get; set; }

        /// <summary>
        /// 响应数据
        /// </summary>
        public ChannelCategoryData data { get; set; }
    }

    /// <summary>
    /// 通道分类响应数据
    /// </summary>
    public class ChannelCategoryData
    {
        /// <summary>
        /// 当前页
        /// </summary>
        public int currentPage { get; set; }

        /// <summary>
        /// 总页数
        /// </summary>
        public int totalPage { get; set; }

        /// <summary>
        /// 每页大小
        /// </summary>
        public int pageSize { get; set; }

        /// <summary>
        /// 总行数
        /// </summary>
        public int totalRows { get; set; }

        /// <summary>
        /// 页面数据
        /// </summary>
        public List<ChannelInfoVO> pageData { get; set; }
    }

    /// <summary>
    /// 通道信息
    /// </summary>
    public class ChannelInfoVO
    {
        /// <summary>
        /// ID
        /// </summary>
        public long id { get; set; }

        /// <summary>
        /// 设备编码
        /// </summary>
        public string deviceCode { get; set; }

        /// <summary>
        /// 单元类型
        /// </summary>
        public int unitType { get; set; }

        /// <summary>
        /// 单元序列
        /// </summary>
        public int unitSeq { get; set; }

        /// <summary>
        /// 通道序列
        /// </summary>
        public int channelSeq { get; set; }

        /// <summary>
        /// 通道编码
        /// </summary>
        public string channelCode { get; set; }

        /// <summary>
        /// 通道序号
        /// </summary>
        public string channelSn { get; set; }

        /// <summary>
        /// 通道名称
        /// </summary>
        public string channelName { get; set; }

        /// <summary>
        /// 通道类型
        /// </summary>
        public string channelType { get; set; }

        /// <summary>
        /// 摄像头类型
        /// </summary>
        public string cameraType { get; set; }

        /// <summary>
        /// 所有者编码
        /// </summary>
        public string ownerCode { get; set; }

        /// <summary>
        /// GPS X坐标
        /// </summary>
        public string gpsX { get; set; }

        /// <summary>
        /// GPS Y坐标
        /// </summary>
        public string gpsY { get; set; }

        /// <summary>
        /// 光栅图ID
        /// </summary>
        public long mapId { get; set; }

        /// <summary>
        /// 域ID
        /// </summary>
        public long domainId { get; set; }

        /// <summary>
        /// 描述
        /// </summary>
        public string memo { get; set; }

        /// <summary>
        /// 是否在线
        /// </summary>
        public int isOnline { get; set; }

        /// <summary>
        /// 状态
        /// </summary>
        public int stat { get; set; }

        /// <summary>
        /// 能力集
        /// </summary>
        public string capability { get; set; }

        /// <summary>
        /// 是否已接入
        /// </summary>
        public int access { get; set; }

        /// <summary>
        /// 通道详情扩展信息Json体
        /// </summary>
        public string chExt { get; set; }

        /// <summary>
        /// 是否是虚拟通道
        /// </summary>
        public string isVirtual { get; set; }
    }

    #endregion

    #region RTSP预览相关模型定义

    /// <summary>
    /// RTSP预览请求参数
    /// </summary>
    public class RtspPreviewRequest
    {
        /// <summary>
        /// 数据部分
        /// </summary>
        public RtspPreviewData data { get; set; }

    }

    /// <summary>
    /// RTSP预览数据部分
    /// </summary>
    public class RtspPreviewData
    {
        /// <summary>
        /// 视频通道编码
        /// </summary>
        public string channelId { get; set; }

        /// <summary>
        /// 数据类型：1-视频
        /// </summary>
        public string dataType { get; set; } = "1";

        /// <summary>
        /// 码流类型：1-主码流，2-辅码流，3-编码流
        /// </summary>
        public string streamType { get; set; } = "1";
    }

    /// <summary>
    /// RTSP预览响应
    /// </summary>
    public class RtspPreviewResponse
    {
        /// <summary>
        /// 状态码
        /// </summary>
        public int code { get; set; }

        /// <summary>
        /// 描述信息
        /// </summary>
        public string errMsg { get; set; }
        public bool success { get; set; }

        /// <summary>
        /// 响应数据
        /// </summary>
        public RtspPreviewResult data { get; set; }
    }

    /// <summary>
    /// RTSP预览结果数据
    /// </summary>
    public class RtspPreviewResult
    {
        /// <summary>
        /// 最低帧率
        /// </summary>
        public string minRate { get; set; }

        /// <summary>
        /// 协议
        /// </summary>
        public string protocol { get; set; }

        /// <summary>
        /// IP地址
        /// </summary>
        public string ip { get; set; }

        /// <summary>
        /// 端口号
        /// </summary>
        public string port { get; set; }

        /// <summary>
        /// 是否启用STUN协议
        /// </summary>
        public string stunEnable { get; set; }

        /// <summary>
        /// STUN协议端口
        /// </summary>
        public string stunPort { get; set; }

        /// <summary>
        /// RTSP地址
        /// </summary>
        public string url { get; set; }

        /// <summary>
        /// 连接类型
        /// </summary>
        public string connectType { get; set; }

        /// <summary>
        /// 会话ID
        /// </summary>
        public string session { get; set; }

        /// <summary>
        /// 令牌
        /// </summary>
        public string token { get; set; }

        /// <summary>
        /// 轨迹ID
        /// </summary>
        public string trackId { get; set; }
    }

    #endregion
}