using Common.Constant;
using Common.Logic;
using Database.Database;
using log4net;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using SicboSub.Api.DTO;
using SicboSub.Api.Singleton;

namespace SicboSub.Api.Business
{
    public class PackageBusinessImpl : IPackageBusiness
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(PackageBusinessImpl));

        private readonly ModelContext dbContext;
        private readonly IConfiguration configuration;

        public PackageBusinessImpl(ModelContext _dbContext, IConfiguration _configuration)
        {
            dbContext = _dbContext;
            configuration = _configuration;
        }

        /// <summary>
        /// Load coin packages for purchase
        /// </summary>
        public async Task<IActionResult> PackageLoad(HttpRequest httpRequest, PackageLoadReq request)
        {
            var url = httpRequest.Path;
            var json = JsonConvert.SerializeObject(request);
            log.Debug("URL: " + url + " => Request: " + json);

            try
            {
                string lang = CommonLogic.GetLanguage(httpRequest, request.lang);
                int pageNumber = request.pageNumber < 0 ? 0 : request.pageNumber;
                int pageSize = request.pageSize <= 0 ? 20 : request.pageSize;

                // Query packages
                var query = dbContext.Packgs.AsQueryable();

                int totalCount = query.Count();
                int totalPages = (int)Math.Ceiling((double)totalCount / pageSize);

                var packages = query
                    .Skip(pageNumber * pageSize)
                    .Take(pageSize)
                    .Select(p => new
                    {
                        productId = p.ProductId,
                        productName = p.ProductName,
                        fee = p.Fee,
                        numberSpin = p.NumberSpin,
                        expireDays = p.ExpireDays,
                        smsSyntax = p.SmsSyntax
                    })
                    .ToList();

                return DotnetLib.Http.HttpResponse.BuildResponse(
                    log, url, json,
                    CommonErrorCode.Success,
                    ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang),
                    new
                    {
                        packages = packages,
                        pagination = new
                        {
                            pageNumber,
                            pageSize,
                            totalCount,
                            totalPages
                        }
                    }
                );
            }
            catch (Exception ex)
            {
                log.Error("Exception: ", ex);
            }

            return DotnetLib.Http.HttpResponse.BuildResponse(
                log, url, json,
                CommonErrorCode.SystemError,
                ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"),
                new { }
            );
        }

        /// <summary>
        /// Load exchange/withdraw configurations
        /// </summary>
        public async Task<IActionResult> ExchangeConfigLoad(HttpRequest httpRequest, ExchangeConfigLoadReq request)
        {
            var url = httpRequest.Path;
            var json = JsonConvert.SerializeObject(request);
            log.Debug("URL: " + url + " => Request: " + json);

            try
            {
                string lang = CommonLogic.GetLanguage(httpRequest, request.lang);
                int pageNumber = request.pageNumber < 0 ? 0 : request.pageNumber;
                int pageSize = request.pageSize <= 0 ? 20 : request.pageSize;

                // Query exchange configs - only active ones
                var query = dbContext.ExchangeConfigs
                    .Where(e => e.IsActive.HasValue && e.IsActive == 1);

                int totalCount = query.Count();
                int totalPages = (int)Math.Ceiling((double)totalCount / pageSize);

                var exchangeConfigs = query
                    .OrderBy(e => e.CoinCost)
                    .Skip(pageNumber * pageSize)
                    .Take(pageSize)
                    .Select(e => new
                    {
                        id = e.Id,
                        productName = e.ProductName,
                        coinCost = e.CoinCost,
                        moneyReceived = e.MoneyReceived,
                        feeCoin = e.FeeCoin,
                        description = e.Description
                    })
                    .ToList();

                return DotnetLib.Http.HttpResponse.BuildResponse(
                    log, url, json,
                    CommonErrorCode.Success,
                    ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang),
                    new
                    {
                        exchangeConfigs = exchangeConfigs,
                        pagination = new
                        {
                            pageNumber,
                            pageSize,
                            totalCount,
                            totalPages
                        }
                    }
                );
            }
            catch (Exception ex)
            {
                log.Error("Exception: ", ex);
            }

            return DotnetLib.Http.HttpResponse.BuildResponse(
                log, url, json,
                CommonErrorCode.SystemError,
                ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"),
                new { }
            );
        }
    }
}
