using Lada.Framework.Data.Domains.Cms;
using Lada.Framework.Data.Repositories;
using Lada.Framework.DTO;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.DTO;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Cms;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Cms;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Cms;
using Microsoft.EntityFrameworkCore;
using Lada.Framework.Data.Domains;
using Ladaer.BackEnd.Infrastructures.AppSettings;
using Microsoft.Extensions.Options;

namespace Ladaer.BackEnd.Infrastructures.Services.Cms
{
    public interface ITopicService
    {
        /// <summary>
        /// Tìm kiếm topic
        /// </summary>
        /// <param name="param">Thông số tìm kiếm.</param>
        /// <returns>Kết quả tìm kiếm dịch vụ.</returns>
        Task<SmartTableResult<TopicItem>> Search(SmartTableParam param);

        Task<TopicResult> CreateOrUpdate(TopicModel model);

        Task<TopicModel> GetById(int topicId);

        /// <summary>
        /// Xóa bài viết
        /// </summary>
        /// <param name="topicId">Id của bài viết.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<BaseResult> DeleteAsync(int topicId);
    }
    public class TopicService : ITopicService
    {
        private readonly IRepository<Topic> _topicRepository;
        private readonly IUrlRecordService _urlRecordService;
        private CmsSetting _cmsSettings;
        private readonly IRepository<UrlRecord> _urlRecordRepository;

        public TopicService(IOptions<CmsSetting> cmsSettings, IRepository<Topic> topicRepository, IUrlRecordService urlRecordService, IRepository<UrlRecord> urlRecordRepository)
        {
            _topicRepository = topicRepository;
            _urlRecordService = urlRecordService;
            _cmsSettings = cmsSettings.Value;
            _urlRecordRepository = urlRecordRepository;
        }

        #region Search
        public async Task<SmartTableResult<TopicItem>> Search(SmartTableParam param)
        {
            var query = _topicRepository.Query();
            if (param.Search.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;
                if (search.Keyword != null)
                {
                    string keyword = search.Keyword;
                    keyword = keyword.Trim().ToLower();
                    query = query.Where(x => x.Title.ToLower().Contains(keyword));
                }
                if (search.CreatedStart != null && search.CreatedEnd != null)
                {
                    DateTimeOffset start = search.CreatedStart;
                    DateTimeOffset end = search.CreatedEnd;
                    DateTimeOffset startParam = start.ToLocalTime().StartOfDay();
                    DateTimeOffset endParam = end.EndOfDay().ToLocalTime().EndOfDay();
                    query = query.Where(x => x.CreatedTime >= startParam && x.CreatedTime <= endParam);
                }
            }
            param.Sort = new Sort() { Predicate = "Id", Reverse = true };
            var gridData = await query.Include(p => p.UrlRecord).ToSmartTableResultAsync(param, x => x.ToItem());
            return gridData;
        }
        #endregion


        /// <summary>
        /// Lấy thông tin dịch vụ qua Id
        /// </summary>
        /// <param name="topicId">Id của dịch vụ.</param>
        /// <returns>Thông tin dịch vụ.</returns>
        public async Task<TopicModel> GetById(int topicId)
        {
            var model = new TopicModel();
            if (topicId <= 0) return model;
            var topic = await _topicRepository.Query()
                .FirstOrDefaultAsync(c => c.Id == topicId);
            if (topic != null && topic.Id > 0)
            {
                model = topic.ToModel();
            }
            return model;
        }

        #region CreateOrUpdate
        /// <summary>
        /// Tạo hoặc cập nhật dịch vụ
        /// </summary>
        /// <param name="model">Thông tin dịch vụ.</param>
        /// <returns>Kết quả của thao tác.</returns>
        public async Task<TopicResult> CreateOrUpdate(TopicModel model)
        {
            var topic = model.ToEntity();
            // Cập nhật thông tin chung của thực thể
            //topic = topic.UpdateCommonInt(model.UpdatedBy, model.UpdatedByUserName);

            if (topic.Id > 0)
            {
                // Cập nhật
                return await Update(model);
            }
            else
            {
                // Thêm mới
                return await Create(model);
            }
        }

        /// <summary>
        /// Cập nhật dịch vụ
        /// </summary>
        /// <param name="topic">Thông tin dịch vụ.</param>
        /// <returns>Kết quả của thao tác.</returns>
        private async Task<TopicResult> Update(TopicModel model)
        {
            var result = new TopicResult() { Result = Result.Success };
            var topicForUpdate = await _topicRepository.Query().Include(p => p.UrlRecord)
                .FirstOrDefaultAsync(c => c.Id == model.Id);
            var currentTime = DateTimeHelper.CurrentTime();
            if (topicForUpdate == null || model.Id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy dịch vụ yêu cầu!";
                return result;
            }

            try
            {
                #region URLRecord
                var urlRecordId = (topicForUpdate.UrlRecord != null && topicForUpdate.UrlRecord.Id > 0) ? topicForUpdate.UrlRecord.Id : 0;
                var slug = model.Title.NormalizeUrl();
                slug = await _urlRecordService.GenerateUrlRecord(slug, UrlEntityType.Topic, urlRecordId);
                if (urlRecordId > 0)
                {
                    if (topicForUpdate.UrlRecord.Slug != slug)
                    {
                        topicForUpdate.UrlRecord.Slug = slug;
                    }
                }
                else
                {
                    //Nếu không có thì tạo
                    topicForUpdate.UrlRecord = new UrlRecord()
                    {
                        MetaTitle = model.Title,
                        MetaDescription = model.Title,
                        MetaKeywords = "",
                        Slug = slug,
                        CreatedBy = model.UpdatedBy,
                        CreatedByUserName = model.UpdatedByUserName,
                        UpdatedBy = model.UpdatedBy,
                        UpdatedByUserName = model.UpdatedByUserName,
                        CreatedTime = currentTime,
                        UpdatedTime = currentTime,
                        EntityName = "Topic",
                        EntityDescription = ""
                    };
                }
                #endregion


                // Cập nhật thông tin của dịch vụ
                topicForUpdate.Title = model.Title.Trim();
                topicForUpdate.Description = model.Description.Trim();
                topicForUpdate.TOC = model.TOC;
                topicForUpdate.IncludeInFooterBottom = model.IncludeInFooterBottom;
                topicForUpdate.IncludeInFooterColumn1 = model.IncludeInFooterColumn1;
                topicForUpdate.IncludeInFooterColumn2 = model.IncludeInFooterColumn2;
                topicForUpdate.IncludeInFooterColumn3 = model.IncludeInFooterColumn3;
                // Cập nhật thông tin chung của thực thể
                topicForUpdate = topicForUpdate.UpdateCommonInt(model.UpdatedBy, model.UpdatedByUserName);

                await _topicRepository.UpdateAsync(topicForUpdate);
                result.Id = topicForUpdate.Id;
            }
            catch (Exception e)
            {
                result.Result = Result.SystemError;
                result.Message = e.ToString();
            }

            return result;
        }

        /// <summary>
        /// Tạo dịch vụ
        /// </summary>
        /// <param name="topic">Thông tin dịch vụ.</param>
        /// <returns>Kết quả của thao tác.</returns>
        private async Task<TopicResult> Create(TopicModel model)
        {
            var result = new TopicResult();
            var currentTime = DateTimeHelper.CurrentTime();
            try
            {


                #region General
                var topic = model.ToEntity().UpdateCommonInt(model.UpdatedBy, model.UpdatedByUserName);

                #region URL Record
                var slug = model.Title.NormalizeUrl();
                slug = await _urlRecordService.GenerateUrlRecord(slug, UrlEntityType.Topic);
                topic.UrlRecord = new UrlRecord()
                {
                    MetaTitle = topic.Title.CutWordByLength(_cmsSettings.SeoSetting.MetaTitleLength),
                    MetaDescription = topic.Title.CutWordByLength(_cmsSettings.SeoSetting.MetaDescriptionLength),
                    MetaKeywords = "",
                    Slug = slug,
                    CreatedBy = topic.CreatedBy,
                    CreatedByUserName = topic.CreatedByUserName,
                    UpdatedBy = topic.UpdatedBy,
                    UpdatedByUserName = topic.UpdatedByUserName,
                    CreatedTime = topic.CreatedTime,
                    UpdatedTime = topic.UpdatedTime,
                    EntityName = "Topic",
                    EntityDescription = ""
                };
                #endregion

                await _topicRepository.InsertAsync(topic);
                #endregion



                result.Id = topic.Id;
            }
            catch (Exception e)
            {
                result.Result = Result.SystemError;
                result.Message = e.ToString();
                result.Id = 0;
            }
            return result;
        }
        #endregion




        /// <summary>
        /// Xóa bài viết
        /// </summary>
        /// <param name="topicId">Id của bài viết.</param>
        /// <returns>Kết quả của thao tác.</returns>
        public async Task<BaseResult> DeleteAsync(int topicId)
        {
            var result = new BaseResult();
            if (topicId <= 0) return result;
            var post = await _topicRepository.Query().FirstOrDefaultAsync(c => c.Id == topicId);

            if (post != null && post.Id > 0)
            {
                var deleteResult = await _topicRepository.DeleteAsync(post);
                if (deleteResult <= 0)
                {
                    result.Result = Result.SystemError;
                    result.Message = "Không thể xóa được";
                }

                var urlRecord = await _urlRecordRepository.Query().FirstOrDefaultAsync(u => u.TopicId == topicId);
                if (urlRecord != null && urlRecord.Id > 0)
                {
                    var deleteUrlResult = await _urlRecordRepository.DeleteAsync(urlRecord);
                    if (deleteUrlResult <= 0)
                    {
                        result.Result = Result.SystemError;
                        result.Message = "Không thể xóa urlrecord";
                    }
                }
            }
            else
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy bài viết yêu cầu";
            }
            return result;
        }
    }
}
