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;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Finances;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Finances;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Finances;
using Microsoft.EntityFrameworkCore;
using Route = Lada.Framework.Data.Domains.Finance.Quotations.Route;

namespace Ladaer.BackEnd.Infrastructures.Services.Finances
{
    /// <summary>
    /// Giao diện cho dịch vụ quản lý tuyến vận tải.
    /// </summary>
    public interface IRouteService
    {
        /// <summary>
        /// Tìm kiếm tuyến vận tải.
        /// </summary>
        /// <param name="param">Thông số tìm kiếm.</param>
        /// <returns>Kết quả tìm kiếm tuyến vận tải.</returns>
        Task<SmartTableResult<RouteItem>> Search(SmartTableParam param);

        /// <summary>
        /// Tạo mới hoặc cập nhật thông tin tuyến vận tải.
        /// </summary>
        /// <param name="model">Thông tin tuyến vận tải.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<RouteResult> CreateOrUpdate(RouteModel model);

        /// <summary>
        /// Lấy thông tin tuyến vận tải theo ID.
        /// </summary>
        /// <param name="routeId">ID của tuyến vận tải.</param>
        /// <returns>Thông tin tuyến vận tải.</returns>
        Task<RouteModel> GetById(int routeId);

        /// <summary>
        /// Xóa tuyến vận tải theo ID.
        /// </summary>
        /// <param name="routeId">ID của tuyến vận tải.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<BaseResult> Delete(int routeId);
    }


    /// <summary>
    /// Triển khai dịch vụ quản lý tuyến vận tải.
    /// </summary>
    public class RouteService : IRouteService
    {
        private readonly IRepository<Route> _routeRepository;

        /// <summary>
        /// Khởi tạo một thể hiện của <see cref="RouteService"/>.
        /// </summary>
        /// <param name="routeRepository">Đối tượng IRepository của Route.</param>
        public RouteService(IRepository<Route> routeRepository)
        {
            _routeRepository = routeRepository;
        }

        #region SEARCH
        /// <summary>
        /// Tìm kiếm tuyến vận tải.
        /// </summary>
        /// <param name="param">Thông số tìm kiếm.</param>
        /// <returns>Kết quả tìm kiếm tuyến vận tải.</returns>
        public async Task<SmartTableResult<RouteItem>> Search(SmartTableParam param)
        {
            var query = _routeRepository.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));
                }
                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);
                }
            }
            param.Sort = new Sort() { Predicate = "DisplayOrder", Reverse = false };
            var gridData = await query.ToSmartTableResultAsync(param, x => x.ToItem());

            return gridData;
        }
        #endregion

        #region CRUD
        /// <summary>
        /// Tạo mới hoặc cập nhật thông tin tuyến vận tải.
        /// </summary>
        /// <param name="model">Thông tin tuyến vận tải.</param>
        /// <returns>Kết quả của thao tác.</returns>
        public async Task<RouteResult> CreateOrUpdate(RouteModel model)
        {
            var route = model.ToEntity();

            // Cập nhật thông tin chung của thực thể
            route = route.UpdateCommonInt(model.UpdatedBy, model.UpdatedByUserName);

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

        /// <summary>
        /// Tạo mới tuyến vận tải.
        /// </summary>
        /// <param name="route">Thông tin tuyến vận tải.</param>
        /// <returns>Kết quả của thao tác.</returns>
        private async Task<RouteResult> Create(Route route)
        {
            var result = new RouteResult();
            try
            {
                await _routeRepository.InsertAsync(route);
                result.Id = route.Id;
            }
            catch (Exception e)
            {
                result.Result = Result.SystemError;
                result.Message = e.ToString();
                result.Id = 0;
            }
            return result;
        }

        /// <summary>
        /// Cập nhật thông tin tuyến vận tải.
        /// </summary>
        /// <param name="route">Thông tin tuyến vận tải.</param>
        /// <returns>Kết quả của thao tác.</returns>
        private async Task<RouteResult> Update(Route route)
        {
            var result = new RouteResult() { Result = Result.Success };
            var routeForUpdate = await _routeRepository.Query().FirstOrDefaultAsync(c => c.Id == route.Id);
            if (routeForUpdate == null || route.Id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy hồ sơ yêu cầu!";
                return result;
            }

            try
            {
                routeForUpdate.Name = route.Name;
                routeForUpdate.Description = route.Description;
                routeForUpdate.DisplayOrder = route.DisplayOrder;
                routeForUpdate.DistanceMax = route.DistanceMax;
                routeForUpdate.DistanceMin = route.DistanceMin;
                // Cập nhật thông tin chung của thực thể
                routeForUpdate = routeForUpdate.UpdateCommonInt();
                await _routeRepository.UpdateAsync(routeForUpdate);
                result.Id = routeForUpdate.Id;
            }
            catch (Exception e)
            {
                result.Result = Result.SystemError;
                result.Message = e.ToString();
            }

            return result;
        }

        /// <summary>
        /// Lấy thông tin tuyến vận tải theo ID.
        /// </summary>
        /// <param name="routeId">ID của tuyến vận tải.</param>
        /// <returns>Thông tin tuyến vận tải.</returns>
        public async Task<RouteModel> GetById(int routeId)
        {
            var result = new RouteModel();
            if (routeId <= 0)
            {
                return result;
            }
            var routeForUpdate = await _routeRepository.Query().FirstOrDefaultAsync(c => c.Id == routeId);
            if (routeForUpdate == null || routeForUpdate.Id <= 0)
            {
                return result;
            }
            return routeForUpdate.ToModel();
        }

        /// <summary>
        /// Xóa tuyến vận tải theo ID.
        /// </summary>
        /// <param name="routeId">ID của tuyến vận tải.</param>
        /// <returns>Kết quả của thao tác.</returns>
        public async Task<BaseResult> Delete(int routeId)
        {
            var result = new BaseResult();
            if (routeId <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Yêu cầu xóa tuyến không hợp lệ";
                return result;
            }
            var routeForUpdate = await _routeRepository.Query().FirstOrDefaultAsync(c => c.Id == routeId);
            if (routeForUpdate == null || routeForUpdate.Id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy tuyến yêu cầu";
                return result;
            }
            try
            {
                // Cập nhật thông tin chung của thực thể
                routeForUpdate = routeForUpdate.UpdateCommonInt();
                var delResult = await _routeRepository.DeleteAsync(routeForUpdate);
                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;
        }
        #endregion
    }
}
