using Lada.Framework.Data.Domains;
using Lada.Framework.Data.Repositories;
using Lada.Framework.DTO;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.DTO.Items.AppConfig;
using Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig;
using Ladaer.BackEnd.Infrastructures.DTO.Profiles;
using Ladaer.BackEnd.Infrastructures.DTO.Results.AppConfig;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;

namespace Ladaer.BackEnd.Infrastructures.Services
{
    /// <summary>
    /// Interface cho service quản lý AppConfig
    /// </summary>
    public interface IAppConfigManagementService
    {
        /// <summary>
        /// Tìm kiếm AppConfig với SmartTable
        /// </summary>
        /// <param name="param">Tham số tìm kiếm</param>
        /// <returns>Kết quả tìm kiếm</returns>
        Task<SmartTableResult<AppConfigItem>> Search(SmartTableParam param);

        /// <summary>
        /// Tạo hoặc cập nhật AppConfig
        /// </summary>
        /// <param name="model">Model AppConfig</param>
        /// <returns>Kết quả thao tác</returns>
        Task<AppConfigResult> CreateOrUpdate(CreateAppConfigModel model);

        /// <summary>
        /// Lấy AppConfig theo Id
        /// </summary>
        /// <param name="id">Id của AppConfig</param>
        /// <returns>AppConfig model</returns>
        Task<CreateAppConfigModel> GetById(int id);

        /// <summary>
        /// Xóa AppConfig
        /// </summary>
        /// <param name="id">Id của AppConfig</param>
        /// <returns>Kết quả xóa</returns>
        Task<BaseResult> Delete(int id);

        /// <summary>
        /// Reload cache cho tất cả applications
        /// </summary>
        /// <returns>Kết quả reload</returns>
        Task<BaseResult> ReloadCache();
    }

    /// <summary>
    /// Implementation của AppConfigManagementService
    /// </summary>
    public class AppConfigManagementService : IAppConfigManagementService
    {
        private readonly IRepository<AppConfig> _appConfigRepository;
        private readonly IMemoryCache _memoryCache;
        private readonly string _cacheKeyPrefix = "AppConfig_";

        public AppConfigManagementService(
            IRepository<AppConfig> appConfigRepository,
            IMemoryCache memoryCache)
        {
            _appConfigRepository = appConfigRepository;
            _memoryCache = memoryCache;
        }

        /// <summary>
        /// Tìm kiếm AppConfig với SmartTable
        /// </summary>
        /// <param name="param">Tham số tìm kiếm</param>
        /// <returns>Kết quả tìm kiếm</returns>
        public async Task<SmartTableResult<AppConfigItem>> Search(SmartTableParam param)
        {
            var query = _appConfigRepository.Query();

            // Apply search filters
            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.Key.ToLower().Contains(keyword) ||
                                           x.Value.ToLower().Contains(keyword) ||
                                           x.Description.ToLower().Contains(keyword));
                }

                if (search.CreatedStart != null && search.CreatedEnd != null)
                {
                    DateTimeOffset start = search.CreatedStart;
                    DateTimeOffset end = search.CreatedEnd;
                    DateTimeOffset startParam = start.StartOfDay();
                    DateTimeOffset endParam = end.EndOfDay();
                    query = query.Where(x => x.CreatedTime >= startParam && x.CreatedTime <= endParam);
                }
            }

            // Apply sorting and pagination with AutoMapper
            var result = await query.ToSmartTableResultAsync(param, entity => entity.ToItem());

            return result;
        }

        /// <summary>
        /// Tạo hoặc cập nhật AppConfig
        /// </summary>
        /// <param name="model">Model AppConfig</param>
        /// <returns>Kết quả thao tác</returns>
        public async Task<AppConfigResult> CreateOrUpdate(CreateAppConfigModel model)
        {
            var result = new AppConfigResult();

            // Validation
            if (string.IsNullOrEmpty(model.Key))
            {
                result.Result = Result.Failed;
                result.Message = "Key không được để trống";
                return result;
            }

            if (string.IsNullOrEmpty(model.Value))
            {
                result.Result = Result.Failed;
                result.Message = "Value không được để trống";
                return result;
            }

            try
            {
                // Check if key exists
                var existingConfig = await _appConfigRepository.Query()
                    .FirstOrDefaultAsync(x => x.Key == model.Key);

                if (existingConfig != null)
                {
                    // Update existing
                    existingConfig.Value = model.Value;
                    existingConfig.Description = model.Description ?? "";
                    existingConfig = existingConfig.UpdateCommonInt(model.UpdatedBy, model.UpdatedByUserName);

                    await _appConfigRepository.UpdateAsync(existingConfig);

                    // Update cache
                    _memoryCache.Set($"{_cacheKeyPrefix}{existingConfig.Key}", existingConfig.Value, TimeSpan.FromHours(1));

                    result.Id = existingConfig.Id;
                    result.Key = existingConfig.Key;
                    result.Value = existingConfig.Value;
                    result.Description = existingConfig.Description;
                }
                else
                {
                    // Create new using AutoMapper
                    var newConfig = model.ToEntity();
                    newConfig = newConfig.UpdateCommonInt(model.UpdatedBy, model.UpdatedByUserName);

                    await _appConfigRepository.InsertAsync(newConfig);

                    // Update cache
                    _memoryCache.Set($"{_cacheKeyPrefix}{newConfig.Key}", newConfig.Value, TimeSpan.FromHours(1));

                    result.Id = newConfig.Id;
                    result.Key = newConfig.Key;
                    result.Value = newConfig.Value;
                    result.Description = newConfig.Description;
                }

                result.Result = Result.Success;
                result.Message = "Cập nhật cấu hình thành công";
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = ex.ToString();
            }

            return result;
        }

        /// <summary>
        /// Lấy AppConfig theo Id
        /// </summary>
        /// <param name="id">Id của AppConfig</param>
        /// <returns>AppConfig model</returns>
        public async Task<CreateAppConfigModel> GetById(int id)
        {
            var config = await _appConfigRepository.GetByIdAsync(id);
            if (config == null)
            {
                return null;
            }

            return config.ToModel();
        }

        /// <summary>
        /// Xóa AppConfig
        /// </summary>
        /// <param name="id">Id của AppConfig</param>
        /// <returns>Kết quả xóa</returns>
        public async Task<BaseResult> Delete(int id)
        {
            var result = new BaseResult();

            if (id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Id không hợp lệ";
                return result;
            }

            var configForDelete = await _appConfigRepository.GetByIdAsync(id);
            if (configForDelete == null)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy cấu hình yêu cầu";
                return result;
            }

            try
            {
                // Remove from cache first
                _memoryCache.Remove($"{_cacheKeyPrefix}{configForDelete.Key}");

                // Delete from database
                var deleteResult = await _appConfigRepository.DeleteAsync(configForDelete);
                if (deleteResult <= 0)
                {
                    result.Result = Result.SystemError;
                    result.Message = "Hệ thống không thể thực hiện yêu cầu lúc này, vui lòng thử lại sau!";
                    return result;
                }

                result.Result = Result.Success;
                result.Message = "Xóa cấu hình thành công";
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = ex.ToString();
            }

            return result;
        }

        /// <summary>
        /// Reload cache cho tất cả applications
        /// </summary>
        /// <returns>Kết quả reload</returns>
        public async Task<BaseResult> ReloadCache()
        {
            var result = new BaseResult();

            try
            {
                var configs = await _appConfigRepository.Query().ToListAsync();

                // Clear existing cache
                foreach (var config in configs)
                {
                    _memoryCache.Remove($"{_cacheKeyPrefix}{config.Key}");
                }

                // Reload cache
                foreach (var config in configs)
                {
                    _memoryCache.Set($"{_cacheKeyPrefix}{config.Key}", config.Value, TimeSpan.FromHours(1));
                }

                result.Result = Result.Success;
                result.Message = $"Đã reload {configs.Count} cấu hình vào cache thành công";
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = ex.ToString();
            }

            return result;
        }
    }
}