using Lada.Framework.Data.Domains.Settings;
using Lada.Framework.Data.Repositories;
using Lada.Framework.DTO;
using Lada.Framework.DTO.SmartTable;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Settings;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Settings;
using Ladaer.BackEnd.Infrastructures.DTO.Profiles;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using Lada.Framework.Data.Domains;

namespace Ladaer.BackEnd.Infrastructures.Services.Settings
{
    public interface ICallPathVersionService
    {
        /// <summary>
        /// Lấy thông tin CallPathVersion theo Id.
        /// </summary>
        Task<CallPathVersionModel> GetByIdAsync(int id);

        /// <summary>
        /// Tạo mới hoặc cập nhật CallPathVersion.
        /// </summary>
        Task<BaseResult> CreateOrUpdateAsync(CallPathVersionModel model);

        /// <summary>
        /// Xóa CallPathVersion.
        /// </summary>
        Task<BaseResult> DeleteAsync(int id);

        /// <summary>
        /// Tìm kiếm CallPathVersion theo điều kiện lọc và phân trang.
        /// </summary>
        Task<SmartTableResult<CallPathVersionItem>> SearchAsync(SmartTableParam param);

        /// <summary>
        /// Lấy tất cả CallPathVersion (dùng cho dropdown).
        /// </summary>
        Task<List<CallPathVersionItem>> GetAllAsync();
    }

    /// <summary>
    /// Triển khai dịch vụ quản lý CallPathVersion.
    /// </summary>
    public class CallPathVersionService : ICallPathVersionService
    {
        private readonly IRepository<CallPathVersion> _repository;

        public CallPathVersionService(IRepository<CallPathVersion> repository)
        {
            _repository = repository;
        }

        /// <inheritdoc/>
        public async Task<CallPathVersionModel> GetByIdAsync(int id)
        {
            var result = new CallPathVersionModel();
            if (id <= 0)
            {
                return result;
            }
            var entity = await _repository.Query()
                .FirstOrDefaultAsync(c => c.Id == id);
            if (entity == null || entity.Id <= 0)
            {
                return result;
            }
            return entity.ToModel();
        }

        /// <inheritdoc/>
        public async Task<BaseResult> CreateOrUpdateAsync(CallPathVersionModel model)
        {
            try
            {
                if (model == null)
                    ArgumentNullException.ThrowIfNull(model);

                var entity = model.ToEntity();

                // Kiểm tra trùng Version + Build
                var existing = await _repository.Query()
                    .FirstOrDefaultAsync(x => x.Version == entity.Version && x.Build == entity.Build && x.Id != entity.Id);
                if (existing != null)
                {
                    return new BaseResult
                    {
                        Result = Result.Failed,
                        Message = $"Phiên bản {entity.Version} - Build {entity.Build} đã tồn tại"
                    };
                }

                if (entity.Id > 0)
                {
                    return await UpdateAsync(entity);
                }
                else
                {
                    return await CreateAsync(entity);
                }
            }
            catch (Exception ex)
            {
                return new BaseResult
                {
                    Result = Result.Failed,
                    Message = ex.Message
                };
            }
        }

        private async Task<BaseResult> UpdateAsync(CallPathVersion entity)
        {
            try
            {
                ArgumentNullException.ThrowIfNull(entity);
                await _repository.UpdateAsync(entity);
                return new BaseResult { Result = Result.Success };
            }
            catch (Exception ex)
            {
                return new BaseResult
                {
                    Result = Result.Failed,
                    Message = ex.Message
                };
            }
        }

        private async Task<BaseResult> CreateAsync(CallPathVersion entity)
        {
            try
            {
                ArgumentNullException.ThrowIfNull(entity);
                await _repository.InsertAsync(entity);
                return new BaseResult { Result = Result.Success };
            }
            catch (Exception ex)
            {
                return new BaseResult
                {
                    Result = Result.Failed,
                    Message = ex.Message
                };
            }
        }

        /// <inheritdoc/>
        public async Task<BaseResult> DeleteAsync(int id)
        {
            var result = new BaseResult();
            if (id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Yêu cầu xóa không hợp lệ";
                return result;
            }

            var entity = await _repository.Query()
                .Include(x => x.CallPaths)
                .FirstOrDefaultAsync(c => c.Id == id);
            if (entity == null || entity.Id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy phiên bản yêu cầu";
                return result;
            }

            // Kiểm tra xem phiên bản có đang được sử dụng không
            if (entity.CallPaths != null && entity.CallPaths.Any(x => !x.IsDeleted))
            {
                result.Result = Result.Failed;
                result.Message = $"Không thể xóa phiên bản đang có {entity.CallPaths.Count(x => !x.IsDeleted)} đường dẫn sử dụng";
                return result;
            }

            try
            {
                entity = entity.UpdateCommonInt();
                var delResult = await _repository.DeleteAsync(entity);
                if (delResult <= 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;
                }
            }
            catch (Exception e)
            {
                result.Result = Result.SystemError;
                result.Message = e.ToString();
            }
            return result;
        }

        /// <inheritdoc/>
        public async Task<SmartTableResult<CallPathVersionItem>> SearchAsync(SmartTableParam param)
        {
            IQueryable<CallPathVersion> query = _repository.Query()
                .Include(x => x.CallPaths);

            if (param.Search?.PredicateObject != null)
            {
                var search = param.Search.PredicateObject as JObject;
                if (search != null)
                {
                    if (search["Keyword"] != null)
                    {
                        string keyword = search["Keyword"]?.ToString()?.Trim()?.ToLower() ?? string.Empty;
                        if (!string.IsNullOrEmpty(keyword))
                        {
                            query = query.Where(x =>
                                (x.Version != null && x.Version.ToLower().Contains(keyword)) ||
                                (x.Build != null && x.Build.ToLower().Contains(keyword)) ||
                                (x.Domain != null && x.Domain.ToLower().Contains(keyword)) ||
                                (x.Description != null && x.Description.ToLower().Contains(keyword))
                            );
                        }
                    }
                }
            }

            param.Sort = new Sort { Predicate = "Id", Reverse = true };
            var gridData = await query.ToSmartTableResultAsync(param, x => x.ToItem());
            return gridData;
        }

        /// <inheritdoc/>
        public async Task<List<CallPathVersionItem>> GetAllAsync()
        {
            IQueryable<CallPathVersion> query = _repository.Query()
                .Include(x => x.CallPaths);
            return await query.Select(x => x.ToItem()).ToListAsync();
        }
    }
}
