using Lada.Framework.Data.Domains;
using Lada.Framework.Data.Domains.Hr;
using Lada.Framework.Data.Repositories;
using Lada.Framework.DTO;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures.Helpers;
using Lada.Framework.Infrastructures.Services;
using Ladaer.BackEnd.Infrastructures.DTO;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Hr;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Hr;
using Microsoft.EntityFrameworkCore;

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

        /// <summary>
        /// Xóa ứng viên theo ID.
        /// </summary>
        /// <param name="id">ID của ứng viên.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<BaseResult> Delete(int id);

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

        /// <summary>
        /// Cập nhật thông tin đánh giá ứng viên.
        /// </summary>
        /// <param name="model">Thông tin đánh giá ứng viên.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<BaseResult> UpdateReview(CandidateReviewModel model);

        /// <summary>
        /// Tạo ứng viên mới.
        /// </summary>
        /// <param name="model">Thông tin ứng viên.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<BaseResult> Create(CandidateModel model);

        /// <summary>
        /// Lấy thông tin ứng viên theo ID.
        /// </summary>
        /// <param name="id">ID của ứng viên.</param>
        /// <returns>Thông tin ứng viên.</returns>
        Task<CandidateModel> GetById(int id);

        /// <summary>
        /// Cập nhật thông tin ứng viên.
        /// </summary>
        /// <param name="model">Thông tin ứng viên.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<BaseResult> Update(CandidateModel model);
    }

    /// <summary>
    /// Triển khai dịch vụ quản lý ứng viên.
    /// </summary>
    public class CandidateService : ICandidateService
    {
        private readonly IRepository<Candidate> _candidateRepository;
        private readonly ICvUploadService _cvUploadService;

        /// <summary>
        /// Khởi tạo một thể hiện của <see cref="CandidateService"/>.
        /// </summary>
        /// <param name="candidateRepository">Đối tượng IRepository của Candidate.</param>
        /// <param name="cvUploadService">Dịch vụ upload CV.</param>
        public CandidateService(IRepository<Candidate> candidateRepository, ICvUploadService cvUploadService)
        {
            _candidateRepository = candidateRepository;
            _cvUploadService = cvUploadService;
        }

        /// <summary>
        /// Tìm kiếm ứng viên.
        /// </summary>
        /// <param name="param">Thông số tìm kiếm.</param>
        /// <returns>Kết quả tìm kiếm ứng viên.</returns>
        public async Task<SmartTableResult<CandidateItem>> Search(SmartTableParam param)
        {
            var query = _candidateRepository.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.ToLower().Contains(keyword) ||
                                                x.Address.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);
                }
                if (search.Status != null)
                {
                    CandidateStatus status = search.Status;
                    query = query.Where(x => x.Status == status);
                }
            }
            param.Sort = new Sort() { Predicate = "Id", Reverse = true };
            var gridData = await query.ToSmartTableResultAsync(param, x => x.ToItem());

            return gridData;
        }

        /// <summary>
        /// Xóa ứng viên theo ID.
        /// </summary>
        /// <param name="id">ID của ứng viên.</param>
        /// <returns>Kết quả của thao tác.</returns>
        public async Task<BaseResult> Delete(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 candidate = await _candidateRepository.Query().FirstOrDefaultAsync(c => c.Id == id);
            if (candidate == null || candidate.Id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy ứng viên yêu cầu";
                return result;
            }

            try
            {
                // Cập nhật thông tin chung của thực thể
                candidate = candidate.UpdateCommonInt();
                var delResult = await _candidateRepository.DeleteAsync(candidate);
                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;
        }

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

            return result;
        }

        /// <summary>
        /// Cập nhật thông tin đánh giá ứng viên.
        /// </summary>
        /// <param name="model">Thông tin đánh giá ứng viên.</param>
        /// <returns>Kết quả của thao tác.</returns>
        public async Task<BaseResult> UpdateReview(CandidateReviewModel model)
        {
            var result = new BaseResult();
            if (model.Id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Yêu cầu không hợp lệ";
                return result;
            }
            var candidate = await _candidateRepository.Query().FirstOrDefaultAsync(c => c.Id == model.Id);
            if (candidate == null || candidate.Id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "Không tìm thấy ứng viên yêu cầu";
                return result;
            }

            try
            {
                // Cập nhật thông tin chung của thực thể
                candidate = candidate.UpdateCommonInt();
                candidate.Status = model.Status;
                candidate.StatusContent = model.StatusContent;
                var updateResult = await _candidateRepository.UpdateAsync(candidate);
                if (updateResult <= 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;
        }

        /// <summary>
        /// Tạo ứng viên mới.
        /// </summary>
        /// <param name="model">Thông tin ứng viên.</param>
        /// <returns>Kết quả của thao tác.</returns>
        public async Task<BaseResult> Create(CandidateModel model)
        {
            var result = new BaseResult();

            try
            {
                // Kiểm tra trùng lặp số điện thoại
                var existingCandidate = await _candidateRepository.Query()
                    .FirstOrDefaultAsync(c => c.PhoneNumber == model.PhoneNumber);

                if (existingCandidate != null)
                {
                    result.Result = Result.Failed;
                    result.Message = "Số điện thoại này đã được đăng ký bởi ứng viên khác";
                    return result;
                }

                // Tạo entity từ model
                var candidate = model.ToEntity();
                candidate = candidate.UpdateCommonInt(model.UpdatedBy, model.UpdatedByUserName);

                // Xử lý upload CV nếu có
                if (model.CvFile != null)
                {
                    var cvUploadResult = await _cvUploadService.UploadCvAsync(model.CvFile);
                    if (cvUploadResult.Result == Result.Success)
                    {
                        candidate.CvFileName = cvUploadResult.FileName;
                        candidate.CvFilePath = cvUploadResult.FilePath;
                        candidate.CvFileSize = cvUploadResult.FileSize;
                        candidate.CvFileType = cvUploadResult.FileType;
                        candidate.CvFileUrl = cvUploadResult.FileUrl;
                        candidate.CvUploadedTime = cvUploadResult.UploadedTime;
                    }
                    else
                    {
                        result.Result = Result.Failed;
                        result.Message = $"Lỗi upload CV: {cvUploadResult.Message}";
                        return result;
                    }
                }

                // Lưu vào database
                var insertResult = await _candidateRepository.InsertAsync(candidate);
                if (insertResult <= 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 = "Tạo ứng viên thành công";
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = "Lỗi hệ thống: " + ex.Message;
            }

            return result;
        }

        /// <summary>
        /// Lấy thông tin ứng viên theo ID.
        /// </summary>
        /// <param name="id">ID của ứng viên.</param>
        /// <returns>Thông tin ứng viên.</returns>
        public async Task<CandidateModel> GetById(int id)
        {
            var result = new CandidateModel();

            if (id <= 0)
            {
                return result;
            }

            var candidate = await _candidateRepository.Query().FirstOrDefaultAsync(c => c.Id == id);
            if (candidate == null || candidate.Id <= 0)
            {
                return result;
            }

            result = candidate.ToModel();

            // Cập nhật URL CV nếu có
            if (!string.IsNullOrEmpty(candidate.CvFilePath))
            {
                result.CvFileUrl = _cvUploadService.GetUrlFromPath(candidate.CvFilePath);
            }

            return result;
        }

        /// <summary>
        /// Cập nhật thông tin ứng viên.
        /// </summary>
        /// <param name="model">Thông tin ứng viên.</param>
        /// <returns>Kết quả của thao tác.</returns>
        public async Task<BaseResult> Update(CandidateModel model)
        {
            var result = new BaseResult();

            if (model.Id <= 0)
            {
                result.Result = Result.Failed;
                result.Message = "ID ứng viên không hợp lệ";
                return result;
            }

            try
            {
                // Tìm ứng viên cần cập nhật
                var candidate = await _candidateRepository.Query().FirstOrDefaultAsync(c => c.Id == model.Id);
                if (candidate == null || candidate.Id <= 0)
                {
                    result.Result = Result.Failed;
                    result.Message = "Không tìm thấy ứng viên yêu cầu";
                    return result;
                }

                // Kiểm tra trùng lặp số điện thoại (trừ chính ứng viên này)
                var existingCandidate = await _candidateRepository.Query()
                    .FirstOrDefaultAsync(c => c.PhoneNumber == model.PhoneNumber && c.Id != model.Id);

                if (existingCandidate != null)
                {
                    result.Result = Result.Failed;
                    result.Message = "Số điện thoại này đã được đăng ký bởi ứng viên khác";
                    return result;
                }

                // Cập nhật thông tin
                candidate.FullName = model.FullName;
                candidate.PhoneNumber = model.PhoneNumber;
                candidate.YearOfBirth = model.YearOfBirth;
                candidate.Address = model.Address;
                candidate.Introduction = model.Introduction;
                candidate.Status = model.Status;
                candidate.StatusContent = model.StatusContent;
                candidate.AppointmentTime = model.AppointmentTime;
                candidate.Note = model.Note;
                candidate.JobId = model.JobId;
                candidate.Source = model.Source;

                // Xử lý upload CV mới nếu có
                if (model.CvFile != null)
                {
                    // Xóa CV cũ nếu có
                    if (!string.IsNullOrEmpty(candidate.CvFilePath))
                    {
                        await _cvUploadService.DeleteCvAsync(candidate.CvFilePath);
                    }

                    // Upload CV mới
                    var cvUploadResult = await _cvUploadService.UploadCvAsync(model.CvFile, model.Id);
                    if (cvUploadResult.Result == Result.Success)
                    {
                        candidate.CvFileName = cvUploadResult.FileName;
                        candidate.CvFilePath = cvUploadResult.FilePath;
                        candidate.CvFileSize = cvUploadResult.FileSize;
                        candidate.CvFileType = cvUploadResult.FileType;
                        candidate.CvFileUrl = cvUploadResult.FileUrl;
                        candidate.CvUploadedTime = cvUploadResult.UploadedTime;
                    }
                    else
                    {
                        result.Result = Result.Failed;
                        result.Message = $"Lỗi upload CV: {cvUploadResult.Message}";
                        return result;
                    }
                }

                // Cập nhật thông tin chung
                candidate = candidate.UpdateCommonInt();

                // Lưu vào database
                var updateResult = await _candidateRepository.UpdateAsync(candidate);
                if (updateResult <= 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 = "Cập nhật ứng viên thành công";
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = "Lỗi hệ thống: " + ex.Message;
            }

            return result;
        }
    }
}
