using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace DeviceSDK
{
    public class DeviceClient : IDisposable
    {
        private readonly string _baseUrl;
        private readonly string _encryptKey;
        private readonly HttpClient _httpClient;
        private bool _disposed;

        public DeviceClient(string baseUrl, string encryptKey)
        {
            _baseUrl = baseUrl.TrimEnd('/');
            _encryptKey = encryptKey;
            _httpClient = new HttpClient
            {
                Timeout = TimeSpan.FromSeconds(30)
            };
        }

        // 设备注册
        public async Task<DeviceRegisterResponse> RegisterDeviceAsync(DeviceRegisterRequest request)
        {
            try
            {
                var response = await PostAsync("/api/devices/register", request);
                return JsonSerializer.Deserialize<DeviceRegisterResponse>(response);
            }
            catch (Exception ex)
            {
                throw new DeviceSDKException("设备注册失败", ex);
            }
        }

        // 设备验证
        public async Task<DeviceValidateResponse> ValidateDeviceAsync(string uid)
        {
            try
            {
                var response = await GetAsync($"/api/devices/{uid}/validate");
                var result = JsonSerializer.Deserialize<ApiResponse>(response);
                
                if (result.Code != 0)
                {
                    throw new DeviceSDKException(result.Error);
                }

                var decrypted = DecryptResponse(result.Data);
                return JsonSerializer.Deserialize<DeviceValidateResponse>(decrypted);
            }
            catch (Exception ex)
            {
                throw new DeviceSDKException("设备验证失败", ex);
            }
        }

        // 更新启动次数
        public async Task<StartCountResponse> UpdateStartCountAsync(string uid)
        {
            try
            {
                var response = await PostAsync($"/api/devices/{uid}/start", null);
                return JsonSerializer.Deserialize<StartCountResponse>(response);
            }
            catch (Exception ex)
            {
                throw new DeviceSDKException("更新启动次数失败", ex);
            }
        }

        // 绑定授权码
        public async Task BindLicenseAsync(string uid, string licenseCode)
        {
            try
            {
                var request = new { license_code = licenseCode };
                var response = await PostAsync($"/api/devices/{uid}/license", request);
                var result = JsonSerializer.Deserialize<ApiResponse>(response);
                
                if (result.Code != 0)
                {
                    throw new DeviceSDKException(result.Error);
                }
            }
            catch (Exception ex)
            {
                throw new DeviceSDKException("绑定授权码失败", ex);
            }
        }

        private async Task<string> GetAsync(string path)
        {
            var response = await _httpClient.GetAsync(_baseUrl + path);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }

        private async Task<string> PostAsync(string path, object data)
        {
            var content = data == null ? null : 
                new StringContent(JsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
            
            var response = await _httpClient.PostAsync(_baseUrl + path, content);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }

        private string DecryptResponse(string encrypted)
        {
            try
            {
                var cipherBytes = Convert.FromBase64String(encrypted);
                var keyBytes = Encoding.UTF8.GetBytes(_encryptKey);

                using var aes = Aes.Create();
                aes.Key = keyBytes;
                
                var iv = new byte[16];
                Array.Copy(cipherBytes, 0, iv, 0, 16);
                aes.IV = iv;

                using var decryptor = aes.CreateDecryptor();
                var cipher = new byte[cipherBytes.Length - 16];
                Array.Copy(cipherBytes, 16, cipher, 0, cipher.Length);
                
                var plainBytes = decryptor.TransformFinalBlock(cipher, 0, cipher.Length);
                return Encoding.UTF8.GetString(plainBytes);
            }
            catch (Exception ex)
            {
                throw new DeviceSDKException("解密响应失败", ex);
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    _httpClient?.Dispose();
                }
                _disposed = true;
            }
        }
    }

    // 请求和响应模型
    public class DeviceRegisterRequest
    {
        public string Uid { get; set; }
        public string DeviceModel { get; set; }
        public string LicenseCode { get; set; }
    }

    public class DeviceRegisterResponse
    {
        public int Code { get; set; }
        public string Message { get; set; }
        public DeviceRegisterData Data { get; set; }
    }

    public class DeviceRegisterData
    {
        public string Uid { get; set; }
        public string DeviceModel { get; set; }
        public string Status { get; set; }
    }

    public class DeviceValidateResponse
    {
        public string Status { get; set; }
        public string LicenseType { get; set; }
        public DateTime ExpireTime { get; set; }
        public int StartCount { get; set; }
        public int MaxUses { get; set; }
        public long Timestamp { get; set; }
    }

    public class StartCountResponse
    {
        public int Code { get; set; }
        public string Message { get; set; }
        public StartCountData Data { get; set; }
    }

    public class StartCountData
    {
        public int StartCount { get; set; }
        public string Status { get; set; }
        public DateTime LastActiveAt { get; set; }
    }

    internal class ApiResponse
    {
        public int Code { get; set; }
        public string Error { get; set; }
        public string Data { get; set; }
    }

    // 自定义异常
    public class DeviceSDKException : Exception
    {
        public DeviceSDKException(string message) : base(message) { }
        public DeviceSDKException(string message, Exception innerException) 
            : base(message, innerException) { }
    }
} 