using Lada.Framework.Data.Domains.Categories;
using Lada.Framework.Data.Domains.Crm;
using Lada.Framework.Data.Enums;
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.Categories;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Crm;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Categories;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Crm;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Hr;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Categories;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Crm;
using Microsoft.EntityFrameworkCore;

namespace Ladaer.BackEnd.Infrastructures.Services.Crm
{
    public interface ILeadService
    {
        /// <summary>
        /// Tìm kiếm lead
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<SmartTableResult<LeadItem>> Search(SmartTableParam param);

        /// <summary>
        /// Tạo/cập nhật đại lý
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        Task<LeadResult> CreateOrUpdate(LeadModel model);

        /// <summary>
        /// Tạo lead.
        /// </summary>
        /// <param name="model">Thông tin lead.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<LeadResult> Create(LeadModel model);

        /// <summary>
        /// Cập nhật trạng thái của Lead
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        Task<BaseResult> UpdateLeadStatus(LeadStatusModel model);


        /// <summary>
        /// Lấy thông tin đánh giá lead theo ID.
        /// </summary>
        /// <param name="id">ID của lead.</param>
        /// <returns>Thông tin đánh giá lead.</returns>
        Task<LeadStatusModel> GetReviewModelById(int id);

    }
    public class LeadService : ILeadService
    {
        private readonly IRepository<Lead> _leadRepository;

        public LeadService(IRepository<Lead> leadRepository)
        {
            _leadRepository = leadRepository;
        }

        public async Task<SmartTableResult<LeadItem>> Search(SmartTableParam param)
        {
            var query = _leadRepository.Query();
            if (param.Search.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;
                if (search.Keyword != null)
                {
                    string keyword = search.Keyword;
                    keyword = keyword.Trim().ToLower();
                    if (!string.IsNullOrEmpty(keyword))
                    {
                        query = query.Where(x => x.FullName.ToLower().Contains(keyword)
                                    || x.PhoneNumber.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);
                }
                if (search.Status != null)
                {
                    LeadStatus status = search.Status;
                    query = query.Where(x => x.LeadStatus == status);
                }


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

            return gridData;
        }



        public async Task<LeadResult> Create(LeadModel model)
        {
            var result = new LeadResult();
            var currentTime = DateTimeHelper.CurrentTime();


            var lead = model.ToEntity();
            lead.CreatedTime = currentTime;
            lead.UpdatedTime = currentTime;
            try
            {

                await _leadRepository.InsertAsync(lead);
                result.Id = lead.Id;
            }
            catch (Exception e)
            {
                result.Result = Result.SystemError;
                result.Message = e.ToString();
                result.Id = 0;
            }
            return result;
        }

        public async Task<LeadResult> CreateOrUpdate(LeadModel model)
        {
            var lead = model.ToEntity();



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


        private async Task<LeadResult> Create(Lead lead)
        {
            var result = new LeadResult();
            var currentTime = DateTimeHelper.CurrentTime();
            try
            {
                lead.CreatedTime = currentTime;
                lead.UpdatedTime = currentTime;

                await _leadRepository.InsertAsync(lead);
                result.Id = lead.Id;

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

        private async Task<LeadResult> Update(Lead lead)
        {
            var result = new LeadResult() { Result = Result.Success };
            var currentTime = DateTimeHelper.CurrentTime();


            var leadForUpdate = await _leadRepository.Query().FirstOrDefaultAsync(c => c.Id == lead.Id);
            if (leadForUpdate == null || lead.Id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy hồ sơ yêu cầu!";
                return result;
            }

            try
            {
                leadForUpdate.FullName = lead.FullName;
                leadForUpdate.PhoneNumber = lead.PhoneNumber;
                leadForUpdate.SourcePath = lead.SourcePath;
                leadForUpdate.Message = lead.Message;
                lead.UpdatedTime = currentTime;
                await _leadRepository.UpdateAsync(leadForUpdate);
                result.Id = leadForUpdate.Id;
            }
            catch (Exception e)
            {
                result.Result = Result.SystemError;
                result.Message = e.ToString();
            }

            return result;
        }


        /// <summary>
        /// Cập nhật trạng thái lead.
        /// </summary>
        /// <param name="id">Id của lead.</param>
        /// <param name="status">Trạng thái lead.</param>
        /// <returns>Kết quả của thao tác.</returns>
        public async Task<BaseResult> UpdateLeadStatus(LeadStatusModel model)
        {
            var result = new BaseResult();

            var leadForUpdate = await _leadRepository.Query().FirstOrDefaultAsync(c => c.Id == model.Id);
            if (leadForUpdate == null)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy lead yêu cầu";
            }
            else
            {
                try
                {
                    //Gán người phụ trách
                    if (model.PicId > 0)
                    {
                        //Kiểm tra đã tồn tại người phụ trách chưa?
                        if (leadForUpdate.PicId > 0)
                        {
                            result.Result = Result.Failed;
                            result.Message = "Lead đã có người phụ trách";
                            return result;
                        }
                        else
                        {
                            leadForUpdate.PicId = model.UpdatedBy;
                            leadForUpdate.PicUserName = model.UpdatedByUserName;
                        }
                            
                    }
                    leadForUpdate.LeadStatus = model.LeadStatus;
                    leadForUpdate.StatusContent = model.StatusContent;
                    leadForUpdate.UpdatedBy = model.UpdatedBy;
                    leadForUpdate.UpdatedByUserName = model.UpdatedByUserName;
                    await _leadRepository.UpdateAsync(leadForUpdate);

                    return result;
                }
                catch (Exception ex)
                {
                    result.Result = Result.Failed;
                    result.Message = ex.Message;
                }
            }
            return result;

        }

        /// <summary>
        /// Lấy thông tin đánh giá lead theo ID.
        /// </summary>
        /// <param name="id">ID của lead.</param>
        /// <returns>Thông tin đánh giá lead.</returns>
        public async Task<LeadStatusModel> GetReviewModelById(int id)
        {
            var result = new LeadStatusModel();
            if (id <= 0)
            {
                return result;
            }
            var lead = await _leadRepository.Query().FirstOrDefaultAsync(c => c.Id == id);
            if (lead == null || lead.Id <= 0)
            {
                return result;
            }
            result = lead.ToStatusModel();

            return result;
        }
    }
}
