using Lada.Framework.Data.Domains.Cms;
using Lada.Framework.Data.Enums;
using Lada.Framework.Data.Repositories;
using Lada.Framework.DTO;
using Lada.Framework.DTO.SmartTable;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Cms;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Cms;
using Ladaer.BackEnd.Infrastructures.DTO;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System;
using Lada.Framework.Data.Domains;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Cms;
using Lada.Framework.Infrastructures.Helpers;


namespace Ladaer.BackEnd.Infrastructures.Services.Cms
{
    public interface IScriptConfigService
    {
        Task<List<ScriptConfig>> GetAllAsync(bool onlyActive = false);
        Task<ScriptConfig> GetByIdAsync(int id);
        Task<ScriptConfigResult> CreateOrUpdate(ScriptConfigModel model);
        Task DeleteAsync(int id);
        Task<SmartTableResult<ScriptConfigItem>> Search(SmartTableParam param);
        Task<ScriptConfigResult> Create(ScriptConfigModel model);
        Task<ScriptConfigResult> Update(ScriptConfigModel model);
    }

    public class ScriptConfigService : IScriptConfigService
    {
        private readonly IRepository<ScriptConfig> _repository;
        public ScriptConfigService(IRepository<ScriptConfig> repository)
        {
            _repository = repository;
        }

        public async Task<List<ScriptConfig>> GetAllAsync(bool onlyActive = false)
        {
            var query = _repository.Query();
            if (onlyActive)
                query = query.Where(x => x.IsActive);
            return await Task.FromResult(query.ToList());
        }

        public async Task<ScriptConfig> GetByIdAsync(int id)
        {
            return await _repository.GetByIdAsync(id);
        }

        public async Task DeleteAsync(int id)
        {
            var entity = await _repository.GetByIdAsync(id);
            if (entity != null)
            {
                await _repository.DeleteAsync(entity);
            }
        }

        public async Task<ScriptConfigResult> CreateOrUpdate(ScriptConfigModel model)
        {
            var entity = model.ToEntity();
            entity = entity.UpdateCommonInt(model.UpdatedBy ?? 0, model.UpdatedByUserName);
            var result = new ScriptConfigResult();
            if (entity.Id > 0)
            {
                result = await Update(model);
            }
            else
            {
                result = await Create(model);
            }
            return result;
        }

        public async Task<SmartTableResult<ScriptConfigItem>> Search(SmartTableParam param)
        {
            var query = _repository.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.Name.ToLower().Contains(keyword) || x.Description.ToLower().Contains(keyword));
                }
                if (search.IsActive != null)
                {
                    bool isActive = search.IsActive;
                    query = query.Where(x => x.IsActive == isActive);
                }
                if (search.Position != null)
                {
                    int pos = search.Position;
                    query = query.Where(x => (int)x.Position == pos);
                }
            }
            param.Sort = new Sort() { Predicate = "Id", Reverse = true };
            var gridData = await query.ToSmartTableResultAsync(param, x => x.ToItem());
            return gridData;
        }

        public async Task<ScriptConfigResult> Create(ScriptConfigModel model)
        {
            var result = new ScriptConfigResult();
            try
            {
                var entity = model.ToEntity();
                entity = entity.UpdateCommonInt(model.UpdatedBy ?? 0, model.UpdatedByUserName);
                await _repository.InsertAsync(entity);
                result.Id = entity.Id;
            }
            catch (Exception e)
            {
                result.Result = Result.SystemError;
                result.Message = e.ToString() + model.UpdatedBy + model.UpdatedByUserName;
                result.Id = 0;
            }
            return result;
        }

        public async Task<ScriptConfigResult> Update(ScriptConfigModel model)
        {
            var result = new ScriptConfigResult() { Result = Result.Success };
            var entity = await _repository.GetByIdAsync(model.Id);
            if (entity == null || model.Id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy ScriptConfig yêu cầu!";
                return result;
            }
            try
            {
                entity.Name = model.Name;
                entity.ScriptContent = model.ScriptContent;
                entity.Description = model.Description;
                entity.Position = model.Position;
                entity.IsActive = model.IsActive;
                entity = entity.UpdateCommonInt(model.UpdatedBy ?? 0, model.UpdatedByUserName);
                await _repository.UpdateAsync(entity);
                result.Id = entity.Id;
            }
            catch (Exception e)
            {
                result.Result = Result.SystemError;
                result.Message = e.ToString();
            }
            return result;
        }
    }
}