using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

namespace goods.Models.Coupang
{
    public class CoupangModel
    {
        private readonly CoupangPartners _coupangPartners;
        private string _ChannelID;

        public CoupangModel(CoupangPartners coupangPartners)
        {
            _coupangPartners = coupangPartners;
            _ChannelID = "goods202410";
        }

        /// <summary>
        /// Generate HMAC signature for Coupang API.
        /// </summary>
        public static String GenerateHmac(String method, String url, String accessKey, String secretKey)
        {
            var dateTimeStamp = DateTime.Now.ToUniversalTime().ToString("yyMMddTHHmmssZ");
            var message = String.Format("{0}{1}{2}", dateTimeStamp, method, url.Replace("?", String.Empty));

            var keyBytes = ASCIIEncoding.Default.GetBytes(secretKey);
            var messageBytes = ASCIIEncoding.Default.GetBytes(message);

            var hashBytes = default(Byte[]);
            using (var hash = new HMACSHA256(keyBytes))
            {
                hashBytes = hash.ComputeHash(messageBytes);
            }

            var signature = BitConverter.ToString(hashBytes).Replace("-", String.Empty).ToLower();
            return String.Format("CEA algorithm=HmacSHA256, access-key={0}, signed-date={1}, signature={2}", accessKey, dateTimeStamp, signature);
        }

        // 골드박스
        public async Task<Product.Response> GetGoldBoxProduct()
        {
            Product.Response parseData = new();

            try
            {
                var urlPath = $"/v2/providers/affiliate_open_api/apis/openapi/v1/products/goldbox?subId={_ChannelID}"; // URI 경로만 전달

                // Step 1: URI 생성
                var baseUri = new Uri(_coupangPartners.APIUrl);
                var fullUri = baseUri + urlPath;

                // Step 2: HMAC 서명 생성
                var method = "GET";
                var signature = GenerateHmac(method, urlPath, _coupangPartners.APIKey, _coupangPartners.APISecret);

                // Step 3: HttpRequestMessage 생성
                using var request = new HttpRequestMessage(HttpMethod.Get, fullUri);
                request.Headers.Add("Authorization", signature);

                // Content-Type을 설정하려면 HttpContent를 추가
                request.Content = new StringContent(string.Empty); // 빈 본문

                // Step 4: HTTP 요청 보내기
                var response = await _coupangPartners.httpClient.SendAsync(request);

                if (response.IsSuccessStatusCode)
                {
                    var jsonString = await response.Content.ReadAsStringAsync();
                    parseData = JsonSerializer.Deserialize<Product.Response>(jsonString);

                    if (parseData is null)
                    {
                        return new Product.Response();
                    }
                }

                response.EnsureSuccessStatusCode();
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Request error: {e.Message}");
            }

            return parseData;
        }

        // 카테고리 별 상품
        public async Task<Product.Response> GetCategoryProduct(int categoryID)
        {
            Product.Response parseData = new();

            try
            {
                var urlPath = $"/v2/providers/affiliate_open_api/apis/openapi/v1/products/bestcategories/{categoryID}?limit=100&subId={_ChannelID}";

                // Step 1: URI 생성
                var baseUri = new Uri(_coupangPartners.APIUrl);
                var fullUri = baseUri + urlPath;

                // Step 2: HMAC 서명 생성
                var method = "GET";
                var signature = GenerateHmac(method, urlPath, _coupangPartners.APIKey, _coupangPartners.APISecret);

                // Step 3: HttpRequestMessage 생성
                using var request = new HttpRequestMessage(HttpMethod.Get, fullUri);
                request.Headers.Add("Authorization", signature);

                // Content-Type을 설정하려면 HttpContent를 추가
                request.Content = new StringContent(string.Empty); // 빈 본문

                // Step 4: HTTP 요청 보내기
                var response = await _coupangPartners.httpClient.SendAsync(request);

                var content = await response.Content.ReadAsStringAsync() ?? string.Empty;

                if (response.IsSuccessStatusCode)
                {
                    if (!string.IsNullOrWhiteSpace(content))
                    {
                        var temp = JsonSerializer.Deserialize<Product.Response?>(content);

                        if (temp != null)
                        {
                            parseData = temp;
                        }
                    }
                }
                else
                {
                    Console.WriteLine($"Coupang API error ({response.StatusCode}): {content}");
                }

                response.EnsureSuccessStatusCode();
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Request error: {e.Message}");
            }

            return parseData;
        }

        // 쿠팡PL 상품
        public async Task<Product.Response> GetPlProduct(int brandID)
        {
            Product.Response parseData = new();

            try
            {
                var urlPath = $"/v2/providers/affiliate_open_api/apis/openapi/v1/products/coupangPL/{brandID}?limit=100&subId={_ChannelID}";

                // Step 1: URI 생성
                var baseUri = new Uri(_coupangPartners.APIUrl);
                var fullUri = baseUri + urlPath;

                // Step 2: HMAC 서명 생성
                var method = "GET";
                var signature = GenerateHmac(method, urlPath, _coupangPartners.APIKey, _coupangPartners.APISecret);

                // Step 3: HttpRequestMessage 생성
                using var request = new HttpRequestMessage(HttpMethod.Get, fullUri);
                request.Headers.Add("Authorization", signature);

                // Content-Type을 설정하려면 HttpContent를 추가
                request.Content = new StringContent(string.Empty); // 빈 본문

                // Step 4: HTTP 요청 보내기
                var response = await _coupangPartners.httpClient.SendAsync(request);

                var content = await response.Content.ReadAsStringAsync() ?? string.Empty;

                if (response.IsSuccessStatusCode)
                {
                    if (!string.IsNullOrWhiteSpace(content))
                    {
                        var temp = JsonSerializer.Deserialize<Product.Response?>(content);
                        if (temp != null)
                        {
                            parseData = temp;
                        }
                    }
                }
                else
                {
                    Console.WriteLine($"Coupang API error ({response.StatusCode}): {content}");
                }

                response.EnsureSuccessStatusCode();
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Request error: {e.Message}");
            }

            return parseData;
        }

        // 검색 상품
        public async Task<Search.Response> GetSearchProduct(string keyword)
        {
            Search.Response parseData = new();

            try
            {
                var urlPath = $"/v2/providers/affiliate_open_api/apis/openapi/v1/products/search";

                var encodedKeyword = Uri.EscapeDataString(keyword);
                var queryParams = $"?keyword={encodedKeyword}&limit=10&srpLinkOnly=false&subId={_ChannelID}";
                var fullPathWithQuery = urlPath + queryParams;

                // Step 1: URI 생성
                var baseUri = new Uri(_coupangPartners.APIUrl);
                var fullUri = new Uri(baseUri, fullPathWithQuery);

                // Step 2: HMAC 서명 생성
                var method = "GET";
                var signature = GenerateHmac(method, fullPathWithQuery, _coupangPartners.APIKey, _coupangPartners.APISecret);

                // Step 3: HttpRequestMessage 생성
                using var request = new HttpRequestMessage(HttpMethod.Get, fullUri);
                request.Headers.Add("Authorization", signature);

                // Content-Type을 설정하려면 HttpContent를 추가
                request.Content = new StringContent(string.Empty); // 빈 본문

                // Step 4: HTTP 요청 보내기
                var response = await _coupangPartners.httpClient.SendAsync(request);

                var content = await response.Content.ReadAsStringAsync() ?? string.Empty;

                if (response.IsSuccessStatusCode)
                {
                    if (!string.IsNullOrWhiteSpace(content))
                    {
                        var temp = JsonSerializer.Deserialize<Search.Response?>(content);
                        if (temp != null)
                        {
                            parseData = temp;
                        }
                    }
                }
                else
                {
                    Console.WriteLine($"Coupang API error ({response.StatusCode}): {content}");
                }

                response.EnsureSuccessStatusCode();
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Request error: {e.Message}");
            }

            return parseData;
        }
    }
}
