using Common;
using Common.Constant;
using Common.Http;
using Common.Logic;
using Esim.Apis.Singleton;
using Database.Database;
using log4net;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace Esim.Apis.Business
{
    public class ArticleBusinessImpl : IArticleBusiness
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(
            typeof(ArticleBusinessImpl)
        );

        private ModelContext dbContext;
        IConfiguration configuration;

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

        private string GetParameter(string key)
        {
            return configuration.GetSection(key).Value ?? "";
        }

        /// <summary>
        /// Load article categories with pagination
        /// </summary>
        public async Task<IActionResult> ArticleCategory(HttpRequest httpRequest, ArticleCategoryReq 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 ? 10 : request.pageSize;

                // Query categories
                var query = dbContext.ArticleCategories
                    .Where(c => c.Status.HasValue && c.Status.Value);

                // Filter by parent category
                if (request.parentId.HasValue)
                {
                    query = query.Where(c => c.ParentId == request.parentId);
                }
                else
                {
                    query = query.Where(c => c.ParentId == null); // Root categories
                }

                // Get total count for pagination
                int totalCount = query.Count();
                int totalPages = (int)Math.Ceiling((double)totalCount / pageSize);

                // Apply pagination and ordering
                var categories = query
                    .OrderBy(c => c.DisplayOrder)
                    .ThenBy(c => c.Id)
                    .Skip(pageNumber * pageSize)
                    .Take(pageSize)
                    .Select(c => new
                    {
                        c.Id,
                        categoryName = lang == "en" ? (c.CategoryNameEn ?? c.CategoryName)
                                     : lang == "vi" ? c.CategoryName
                                     : (c.CategoryNameLo ?? c.CategoryName),
                        c.CategorySlug,
                        description = lang == "en" ? (c.DescriptionEn ?? c.Description)
                                    : lang == "vi" ? c.Description
                                    : (c.DescriptionLo ?? c.Description),
                        c.IconUrl,
                        c.ParentId,
                        c.DisplayOrder
                    })
                    .ToList();

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

        /// <summary>
        /// Load articles with pagination and filters
        /// </summary>
        public async Task<IActionResult> ArticleLoad(HttpRequest httpRequest, ArticleLoadReq 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 ? 10 : request.pageSize;

                // Query articles list
                var query = dbContext.Articles
                    .Where(a => a.Status.HasValue && a.Status.Value);

                // Filter by category
                if (request.categoryId.HasValue)
                {
                    query = query.Where(a => a.CategoryId == request.categoryId);
                }

                // Filter by featured
                if (request.isFeatured.HasValue && request.isFeatured.Value)
                {
                    query = query.Where(a => a.IsFeatured.HasValue && a.IsFeatured.Value);
                }

                // Get total count for pagination
                int totalCount = query.Count();
                int totalPages = (int)Math.Ceiling((double)totalCount / pageSize);

                // Apply pagination and ordering (pinned first, then by published date)
                var articles = query
                    .OrderByDescending(a => a.IsPinned)
                    .ThenByDescending(a => a.PublishedDate)
                    .ThenByDescending(a => a.CreatedDate)
                    .Skip(pageNumber * pageSize)
                    .Take(pageSize)
                    .Select(a => new
                    {
                        a.Id,
                        title = lang == "en" ? (a.TitleEn ?? a.Title)
                              : lang == "vi" ? a.Title
                              : (a.TitleLo ?? a.Title),
                        a.Slug,
                        summary = lang == "en" ? (a.SummaryEn ?? a.Summary)
                                : lang == "vi" ? a.Summary
                                : (a.SummaryLo ?? a.Summary),
                        a.ThumbnailUrl,
                        a.CategoryId,
                        a.ViewCount,
                        a.IsFeatured,
                        a.IsPinned,
                        a.PublishedDate
                    })
                    .ToList();

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

        /// <summary>
        /// Get article detail by ID or slug
        /// </summary>
        public async Task<IActionResult> ArticleDetail(HttpRequest httpRequest, ArticleDetailReq request)
        {
            var url = httpRequest.Path;
            var json = JsonConvert.SerializeObject(request);
            log.Debug("URL: " + url + " => Request: " + json);
            try
            {
                // Validate request - must have either id or slug
                if (!request.id.HasValue)
                {
                    return DotnetLib.Http.HttpResponse.BuildResponse(
                        log,
                        url,
                        json,
                        CommonErrorCode.RequiredFieldMissing,
                        ConfigManager.Instance.GetConfigWebValue("REQUIRED_FIELD_MISSING"),
                        new { }
                    );
                }

                string lang = CommonLogic.GetLanguage(httpRequest, request.lang);

                // Query by ID or slug
                var query = dbContext.Articles.Where(a => a.Status.HasValue && a.Status.Value);

                if (request.id.HasValue)
                {
                    query = query.Where(a => a.Id == request.id.Value);
                }
                else if (!string.IsNullOrEmpty(request.slug))
                {
                    query = query.Where(a => a.Slug == request.slug);
                }

                var article = query
                    .Select(a => new
                    {
                        a.Id,
                        title = lang == "en" ? (a.TitleEn ?? a.Title)
                              : lang == "vi" ? a.Title
                              : (a.TitleLo ?? a.Title),
                        a.Slug,
                        summary = lang == "en" ? (a.SummaryEn ?? a.Summary)
                                : lang == "vi" ? a.Summary
                                : (a.SummaryLo ?? a.Summary),
                        content = lang == "en" ? (a.ContentEn ?? a.Content)
                                : lang == "vi" ? a.Content
                                : (a.ContentLo ?? a.Content),
                        a.ThumbnailUrl,
                        a.CoverImageUrl,
                        metaDescription = lang == "en" ? (a.MetaDescriptionEn ?? a.MetaDescription)
                                        : lang == "vi" ? a.MetaDescription
                                        : (a.MetaDescriptionLo ?? a.MetaDescription),
                        a.MetaKeywords,
                        a.CategoryId,
                        a.ViewCount,
                        a.IsFeatured,
                        a.PublishedDate,
                        a.CreatedDate
                    })
                    .FirstOrDefault();

                if (article == null)
                {
                    return DotnetLib.Http.HttpResponse.BuildResponse(
                        log,
                        url,
                        json,
                        CommonErrorCode.Error,
                        ConfigManager.Instance.GetConfigWebValue("ARTICLE_NOT_FOUND", lang),
                        new { }
                    );
                }

                // Increment view count
                var articleEntity = request.id.HasValue
                    ? dbContext.Articles.FirstOrDefault(a => a.Id == request.id.Value)
                    : dbContext.Articles.FirstOrDefault(a => a.Slug == request.slug);

                if (articleEntity != null)
                {
                    articleEntity.ViewCount = (articleEntity.ViewCount ?? 0) + 1;
                    await dbContext.SaveChangesAsync();
                }

                return DotnetLib.Http.HttpResponse.BuildResponse(
                    log,
                    url,
                    json,
                    CommonErrorCode.Success,
                    ConfigManager.Instance.GetConfigWebValue("LOAD_SUCCESS", lang),
                    new { article }
                );
            }
            catch (Exception exception)
            {
                log.Error("Exception: ", exception);
            }
            return DotnetLib.Http.HttpResponse.BuildResponse(
                log,
                url,
                json,
                CommonErrorCode.SystemError,
                ConfigManager.Instance.GetConfigWebValue("SYSTEM_FAILURE"),
                new { }
            );
        }

    }
}
