using System.Security.Claims;
using BMA.EHR.Recurit.Exam.Service.Extensions;
using BMA.EHR.Recurit.Exam.Service.Core;
using BMA.EHR.Recurit.Exam.Service.Data;
using BMA.EHR.Recurit.Exam.Service.Models;
using BMA.EHR.Recurit.Exam.Service.Request;
using BMA.EHR.Recurit.Exam.Service.Response;
using BMA.EHR.Recurit.Exam.Service.Responses.Document;
using Microsoft.EntityFrameworkCore;

namespace BMA.EHR.Recurit.Exam.Service.Services
{
    public class CandidateService
    {
        #region " Fields "

        private readonly ApplicationDbContext _context;
        private readonly OrgDbContext _contextOrg;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly MinIOService _minioService;
        private readonly MailService _mailService;

        #endregion

        #region " Constructor and Destructor "

        public CandidateService(ApplicationDbContext context,
                                     OrgDbContext contextOrg,
                                     IHttpContextAccessor httpContextAccessor,
                                     MinIOService minioService,
                                     MailService mailService)
        {
            _context = context;
            _contextOrg = contextOrg;
            _httpContextAccessor = httpContextAccessor;
            _minioService = minioService;
            _mailService = mailService;
        }

        #endregion

        #region " Properties "

        private string? UserId => _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;

        private string? FullName => _httpContextAccessor?.HttpContext?.User?.FindFirst("name")?.Value;

        #endregion

        #region " Methods "

        public async Task<Candidate> GetsAsync(string candidateId)
        {
            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            return candidate;
        }

        public async Task<CandidateInformationResponseItem?> GetsAsyncInformation(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                return await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position)
                                .Select(x => new CandidateInformationResponseItem
                                {
                                    Prefix = x.PrefixName,
                                    PrefixId = x.PrefixId != null ? x.PrefixId.ToString() : null,
                                    FirstName = x.FirstName,
                                    LastName = x.LastName,
                                    Nationality = x.Nationality,
                                    DateOfBirth = x.DateOfBirth,
                                    Religion = x.ReligionName,
                                    ReligionId = x.ReligionId != null ? x.ReligionId.ToString() : null,
                                    CitizenProvince = x.CitizenProvinceName,
                                    CitizenProvinceId = x.CitizenProvinceId != null ? x.CitizenProvinceId.ToString() : null,
                                    CitizenDistrict = x.CitizenDistrictName,
                                    CitizenDistrictId = x.CitizenDistrictId != null ? x.CitizenDistrictId.ToString() : null,
                                    CitizenDate = x.CitizenDate,
                                    Email = x.Email,
                                    CitizenId = x.CitizenId,
                                    Telephone = x.Telephone,
                                    MobilePhone = x.MobilePhone,
                                    Knowledge = x.Knowledge,
                                })
                                .FirstOrDefaultAsync();
            }
            else
            {
                return await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == exam && x.UserId == UserId)
                                .Select(x => new CandidateInformationResponseItem
                                {
                                    Prefix = x.PrefixName,
                                    PrefixId = x.PrefixId != null ? x.PrefixId.ToString() : null,
                                    FirstName = x.FirstName,
                                    LastName = x.LastName,
                                    Nationality = x.Nationality,
                                    DateOfBirth = x.DateOfBirth,
                                    Religion = x.ReligionName,
                                    ReligionId = x.ReligionId != null ? x.ReligionId.ToString() : null,
                                    CitizenProvince = x.CitizenProvinceName,
                                    CitizenProvinceId = x.CitizenProvinceId != null ? x.CitizenProvinceId.ToString() : null,
                                    CitizenDistrict = x.CitizenDistrictName,
                                    CitizenDistrictId = x.CitizenDistrictId != null ? x.CitizenDistrictId.ToString() : null,
                                    CitizenDate = x.CitizenDate,
                                    Email = x.Email,
                                    CitizenId = x.CitizenId,
                                    Telephone = x.Telephone,
                                    MobilePhone = x.MobilePhone,
                                    Knowledge = x.Knowledge,
                                })
                                .FirstOrDefaultAsync();
            }
        }

        public async Task<CandidateAddressResponseItem?> GetsAsyncAddress(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                return await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position)
                                .Select(x => new CandidateAddressResponseItem
                                {
                                    RegistAddress = x.RegistAddress,
                                    RegistProvince = x.RegistProvinceName,
                                    RegistProvinceId = x.RegistProvinceId != null ? x.RegistProvinceId.ToString() : null,
                                    RegistDistrict = x.RegistDistrictName,
                                    RegistDistrictId = x.RegistDistrictId != null ? x.RegistDistrictId.ToString() : null,
                                    RegistSubDistrict = x.RegistSubDistrictName,
                                    RegistSubDistrictId = x.RegistSubDistrictId != null ? x.RegistSubDistrictId.ToString() : null,
                                    RegistZipCode = x.RegistZipCode,
                                    RegistSame = x.RegistSame,
                                    CurrentAddress = x.CurrentAddress,
                                    CurrentProvince = x.CurrentProvinceName,
                                    CurrentProvinceId = x.CurrentProvinceId != null ? x.CurrentProvinceId.ToString() : null,
                                    CurrentDistrict = x.CurrentDistrictName,
                                    CurrentDistrictId = x.CurrentDistrictId != null ? x.CurrentDistrictId.ToString() : null,
                                    CurrentSubDistrict = x.CurrentSubDistrictName,
                                    CurrentSubDistrictId = x.CurrentSubDistrictId != null ? x.CurrentSubDistrictId.ToString() : null,
                                    CurrentZipCode = x.CurrentZipCode,
                                })
                                .FirstOrDefaultAsync();
            }
            else
            {
                return await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == exam && x.UserId == UserId)
                                .Select(x => new CandidateAddressResponseItem
                                {
                                    RegistAddress = x.RegistAddress,
                                    RegistProvince = x.RegistProvinceName,
                                    RegistProvinceId = x.RegistProvinceId != null ? x.RegistProvinceId.ToString() : null,
                                    RegistDistrict = x.RegistDistrictName,
                                    RegistDistrictId = x.RegistDistrictId != null ? x.RegistDistrictId.ToString() : null,
                                    RegistSubDistrict = x.RegistSubDistrictName,
                                    RegistSubDistrictId = x.RegistSubDistrictId != null ? x.RegistSubDistrictId.ToString() : null,
                                    RegistZipCode = x.RegistZipCode,
                                    RegistSame = x.RegistSame,
                                    CurrentAddress = x.CurrentAddress,
                                    CurrentProvince = x.CurrentProvinceName,
                                    CurrentProvinceId = x.CurrentProvinceId != null ? x.CurrentProvinceId.ToString() : null,
                                    CurrentDistrict = x.CurrentDistrictName,
                                    CurrentDistrictId = x.CurrentDistrictId != null ? x.CurrentDistrictId.ToString() : null,
                                    CurrentSubDistrict = x.CurrentSubDistrictName,
                                    CurrentSubDistrictId = x.CurrentSubDistrictId != null ? x.CurrentSubDistrictId.ToString() : null,
                                    CurrentZipCode = x.CurrentZipCode,
                                })
                                .FirstOrDefaultAsync();
            }
        }

        public async Task<CandidateFamilyResponseItem?> GetsAsyncFamily(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                return await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position)
                                .Select(x => new CandidateFamilyResponseItem
                                {
                                    Marry = x.Marry,
                                    MarryPrefix = x.MarryPrefixName,
                                    MarryPrefixId = x.MarryPrefixId != null ? x.MarryPrefixId.ToString() : null,
                                    MarryFirstName = x.MarryFirstName,
                                    MarryLastName = x.MarryLastName,
                                    MarryOccupation = x.MarryOccupation,
                                    MarryNationality = x.MarryNationality,
                                    FatherPrefix = x.FatherPrefixName,
                                    FatherPrefixId = x.FatherPrefixId != null ? x.FatherPrefixId.ToString() : null,
                                    FatherFirstName = x.FatherFirstName,
                                    FatherLastName = x.FatherLastName,
                                    FatherOccupation = x.FatherOccupation,
                                    FatherNationality = x.FatherNationality,
                                    MotherPrefix = x.MotherPrefixName,
                                    MotherPrefixId = x.MotherPrefixId != null ? x.MotherPrefixId.ToString() : null,
                                    MotherFirstName = x.MotherFirstName,
                                    MotherLastName = x.MotherLastName,
                                    MotherOccupation = x.MotherOccupation,
                                    MotherNationality = x.MotherNationality,
                                })
                                .FirstOrDefaultAsync();
            }
            else
            {
                return await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == exam && x.UserId == UserId)
                                .Select(x => new CandidateFamilyResponseItem
                                {
                                    Marry = x.Marry,
                                    MarryPrefix = x.MarryPrefixName,
                                    MarryPrefixId = x.MarryPrefixId != null ? x.MarryPrefixId.ToString() : null,
                                    MarryFirstName = x.MarryFirstName,
                                    MarryLastName = x.MarryLastName,
                                    MarryOccupation = x.MarryOccupation,
                                    MarryNationality = x.MarryNationality,
                                    FatherPrefix = x.FatherPrefixName,
                                    FatherPrefixId = x.FatherPrefixId != null ? x.FatherPrefixId.ToString() : null,
                                    FatherFirstName = x.FatherFirstName,
                                    FatherLastName = x.FatherLastName,
                                    FatherOccupation = x.FatherOccupation,
                                    FatherNationality = x.FatherNationality,
                                    MotherPrefix = x.MotherPrefixName,
                                    MotherPrefixId = x.MotherPrefixId != null ? x.MotherPrefixId.ToString() : null,
                                    MotherFirstName = x.MotherFirstName,
                                    MotherLastName = x.MotherLastName,
                                    MotherOccupation = x.MotherOccupation,
                                    MotherNationality = x.MotherNationality,
                                })
                                .FirstOrDefaultAsync();
            }
        }

        public async Task<CandidateOccupationResponseItem?> GetsAsyncOccupation(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                return await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position)
                                .Select(x => new CandidateOccupationResponseItem
                                {
                                    OccupationOrg = x.OccupationOrg,
                                    OccupationPile = x.OccupationPile,
                                    OccupationGroup = x.OccupationGroup,
                                    OccupationSalary = x.OccupationSalary,
                                    OccupationPosition = x.OccupationPosition,
                                    OccupationPositionType = x.OccupationPositionType,
                                    OccupationTelephone = x.OccupationTelephone,
                                })
                                .FirstOrDefaultAsync();
            }
            else
            {
                return await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == exam && x.UserId == UserId)
                                .Select(x => new CandidateOccupationResponseItem
                                {
                                    OccupationOrg = x.OccupationOrg,
                                    OccupationPile = x.OccupationPile,
                                    OccupationGroup = x.OccupationGroup,
                                    OccupationSalary = x.OccupationSalary,
                                    OccupationPosition = x.OccupationPosition,
                                    OccupationPositionType = x.OccupationPositionType,
                                    OccupationTelephone = x.OccupationTelephone,
                                })
                                .FirstOrDefaultAsync();
            }
        }

        public async Task<CandidateContactResponseItem?> GetsAsyncContact(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                return await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position)
                                .Select(x => new CandidateContactResponseItem
                                {
                                    ContactPrefixId = x.ContactPrefixId,
                                    ContactFirstname = x.ContactFirstname,
                                    ContactLastname = x.ContactLastname,
                                    ContactRelations = x.ContactRelations,
                                    ContactTel = x.ContactTel,
                                })
                                .FirstOrDefaultAsync();
            }
            else
            {
                return await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == exam && x.UserId == UserId)
                                .Select(x => new CandidateContactResponseItem
                                {
                                    ContactPrefixId = x.ContactPrefixId,
                                    ContactFirstname = x.ContactFirstname,
                                    ContactLastname = x.ContactLastname,
                                    ContactRelations = x.ContactRelations,
                                    ContactTel = x.ContactTel,
                                })
                                .FirstOrDefaultAsync();
            }
        }

        public async Task<IEnumerable<Career?>> GetsAsyncCareer(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                candidate = await _context.Candidates.AsQueryable()
                                .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position);
            }

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            return await _context.Careers.AsQueryable()
                            .Where(x => x.Candidate == candidate)
                            .OrderBy(d => d.DurationStart)
                            .ToListAsync();
        }

        public async Task<Education?> GetsAsyncEducation(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                candidate = await _context.Candidates.AsQueryable()
                                .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position);
            }

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            return await _context.Educations.AsQueryable()
                            .Where(x => x.Candidate == candidate)
                            .FirstOrDefaultAsync();
        }

        public async Task<IEnumerable<FileListResponse?>> GetsAsyncFileUpload(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                candidate = await _context.Candidates.AsQueryable()
                                .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position);
            }

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            var document = await _context.CandidateDocuments.AsQueryable()
                                        .Where(x => x.Candidate == candidate)
                                        .OrderBy(x => x.CreatedAt)
                                        .Select(x => new FileListResponse
                                        {
                                            Id = x.Document == null ? "" : x.Document.Id.ToString(),
                                            FileName = x.Document == null ? "" : x.Document.FileName,
                                            FileType = x.Document == null ? "" : x.Document.FileType,
                                            FileSize = x.Document == null ? 0 : x.Document.FileSize,
                                            Detail = x.Document == null ? "" : x.Document.Id.ToString(),
                                        })
                                        .ToListAsync();

            var i = 0;
            foreach (var item in document)
            {
                if (document[i].Detail != null && document[i].Detail != "")
                    document[i].Detail = _minioService.ImagesPath(Guid.Parse(document[i].Detail)).Result;
                i++;
            }

            return document;
        }

        public async Task<IEnumerable<FileListResponse?>> GetsAsyncAdminFileUpload(string candidateId)
        {
            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            var document = await _context.CandidateDocuments.AsQueryable()
                                        .Where(x => x.Candidate == candidate)
                                        .OrderBy(x => x.CreatedAt)
                                        .Select(x => new FileListResponse
                                        {
                                            Id = x.Document == null ? "" : x.Document.Id.ToString(),
                                            FileName = x.Document == null ? "" : x.Document.FileName,
                                            FileType = x.Document == null ? "" : x.Document.FileType,
                                            FileSize = x.Document == null ? 0 : x.Document.FileSize,
                                            Detail = x.Document == null ? "" : x.Document.Id.ToString(),
                                        })
                                        .ToListAsync();

            var i = 0;
            foreach (var item in document)
            {
                if (document[i].Detail != null && document[i].Detail != "")
                    document[i].Detail = _minioService.ImagesPath(Guid.Parse(document[i].Detail)).Result;
                i++;
            }

            return document;
        }

        public async Task<string> GetsAsyncProfileImage(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var candidate = await _context.Candidates.AsQueryable()
                                        .Include(x => x.ProfileImg)
                                        .Where(x => x.PeriodExam == exam && x.UserId == UserId)
                                        .FirstOrDefaultAsync();

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                candidate = await _context.Candidates.AsQueryable()
                                            .Include(x => x.ProfileImg)
                                            .Where(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position)
                                            .FirstOrDefaultAsync();
            }

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            if (candidate.ProfileImg != null)
                candidate.ProfileImg.Detail = _minioService.ImagesPath(candidate.ProfileImg.Id).Result;

            return candidate.ProfileImg == null ? "" : candidate.ProfileImg.Detail;
        }

        public async Task<string> GetsAsyncAdminProfileImage(string candidateId)
        {
            var candidate = await _context.Candidates.AsQueryable()
                                        .Include(x => x.ProfileImg)
                                        .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            if (candidate.ProfileImg != null)
                candidate.ProfileImg.Detail = _minioService.ImagesPath(candidate.ProfileImg.Id).Result;

            return candidate.ProfileImg == null ? "" : candidate.ProfileImg.Detail;
        }

        public async Task<PaymentImgResponse> GetsAsyncPaymentImg(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var candidate = await _context.Candidates.AsQueryable()
                                        .Include(x => x.PaymentImg)
                                        .Where(x => x.PeriodExam == exam && x.UserId == UserId)
                                        .FirstOrDefaultAsync();

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                candidate = await _context.Candidates.AsQueryable()
                                            .Include(x => x.PaymentImg)
                                            .Where(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position)
                                            .FirstOrDefaultAsync();
            }

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            if (candidate.PaymentImg != null)
                candidate.PaymentImg.Detail = _minioService.ImagesPath(candidate.PaymentImg.Id).Result;

            return new PaymentImgResponse { PaymentImg = candidate.PaymentImg == null ? "" : candidate.PaymentImg.Detail, RejectDetail = candidate.RejectDetail };
        }

        public async Task<string> GetsAsyncPaymentImgCandidate(string candidateId)
        {
            var candidate = await _context.Candidates.AsQueryable()
                                        .Include(x => x.PaymentImg)
                                        .Where(x => x.Id == Guid.Parse(candidateId))
                                        .FirstOrDefaultAsync();

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            if (candidate.PaymentImg != null)
                candidate.PaymentImg.Detail = _minioService.ImagesPath(candidate.PaymentImg.Id).Result;

            return candidate.PaymentImg == null ? "" : candidate.PaymentImg.Detail.ToString();
        }

        public async Task<RequestStatusRegistry> GetsAsyncRegisterExam(Guid examId, Guid positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .Include(x => x.BankExam)
                            .FirstOrDefaultAsync(x => x.Id == examId);

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId);

            var position = await _context.PositionExams.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == positionId);

            if (positionId != Guid.Parse("00000000-0000-0000-0000-000000000000"))
            {
                // var position = await _context.PositionExams.AsQueryable()
                //                 .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                candidate = await _context.Candidates.AsQueryable()
                                .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position);
            }

            var candidatePosition = await _context.Candidates.AsQueryable()
                            .Include(x => x.PositionExam)
                            .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId && x.RegisterDate != null && x.Status != "register" && x.Status != "rejectRegister");

            return new RequestStatusRegistry
            {
                Consend = candidate != null,
                Status = candidate == null ? null : candidate.Status,
                PositionExam = candidatePosition?.PositionExam,
                Bank = exam.BankExam.Count() > 0,
                Payment = exam.Fee > 0,
                EditorCondition = exam.EditorCondition,
                EditorConfirm = exam.EditorConfirm,
                Position = candidatePosition == null ? false : true,
                CanRegister = exam.RegisterStartDate == null || exam.RegisterEndDate == null ? true : DateOnly.FromDateTime(exam.RegisterStartDate.Value) <= DateOnly.FromDateTime(DateTime.Now) && DateOnly.FromDateTime(exam.RegisterEndDate.Value) >= DateOnly.FromDateTime(DateTime.Now),
                RegisterEndDate = exam.RegisterEndDate,
                RegisterStartDate = exam.RegisterStartDate,
            };
        }

        public async Task<string> CreateAsyncCandidate(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (exam.RegisterStartDate != null && exam.RegisterStartDate.Value.Date > DateTime.Now.Date)
                throw new Exception("ยังไม่ถึงช่วงเวลาสมัครสอบ");

            if (exam.RegisterEndDate != null && exam.RegisterEndDate.Value.Date < DateTime.Now.Date)
                throw new Exception("หมดเวลาช่วงสมัครสอบ");

            var _candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId);

            var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                _candidate = await _context.Candidates.AsQueryable()
                                .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position);
            }

            if (_candidate == null)
            {
                var candidate = new Candidate
                {
                    PeriodExam = exam,
                    PositionExam = position,
                    CreatedAt = DateTime.Now,
                    CreatedUserId = UserId ?? "",
                    CreatedFullName = FullName ?? "",
                    LastUpdatedAt = DateTime.Now,
                    LastUpdateUserId = UserId ?? "",
                    LastUpdateFullName = FullName ?? "",
                    UserId = UserId ?? "",
                };
                await _context.Candidates.AddAsync(candidate);
                await _context.SaveChangesAsync();
                return candidate.Id.ToString();
            }
            else
            {
                _candidate.LastUpdatedAt = DateTime.Now;
                _candidate.LastUpdateUserId = UserId ?? "";
                _candidate.LastUpdateFullName = FullName ?? "";
                return _candidate.Id.ToString();
            }
        }

        public async Task UpdateAsync(string examId, string positionId, CandidateResponseItem updated)
        {
            var candidateId = await CreateAsyncCandidate(examId, positionId);

            var candidate = await _context.Candidates
                            .AsQueryable()
                            .Include(x => x.Educations)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (updated.PrefixId != null)
            {
                var prefix = await _contextOrg.prefixe.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.PrefixId));

                if (prefix == null)
                    throw new Exception(GlobalMessages.PrefixNotFound);

                candidate.PrefixId = prefix.Id;
                candidate.PrefixName = prefix.name;
            }

            if (updated.ContactPrefixId != null)
            {
                var prefix = await _contextOrg.prefixe.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == updated.ContactPrefixId);

                if (prefix == null)
                    throw new Exception(GlobalMessages.PrefixNotFound);

                candidate.ContactPrefixId = prefix.Id;
                candidate.ContactPrefixName = prefix.name;
            }

            if (updated.ReligionId != null)
            {
                var religion = await _contextOrg.religion.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.ReligionId));

                if (religion == null)
                    throw new Exception(GlobalMessages.ReligionNotFound);

                candidate.ReligionId = religion.Id;
                candidate.ReligionName = religion.name;
            }

            if (updated.RegistProvinceId != null)
            {
                var registProvince = await _contextOrg.province.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistProvinceId));

                if (registProvince == null)
                    throw new Exception(GlobalMessages.ProvinceNotFound);

                candidate.RegistProvinceId = registProvince.Id;
                candidate.RegistProvinceName = registProvince.name;
            }

            if (updated.RegistDistrictId != null)
            {
                var registDistrict = await _contextOrg.district.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistDistrictId));

                if (registDistrict == null)
                    throw new Exception(GlobalMessages.DistrictNotFound);

                candidate.RegistDistrictId = registDistrict.Id;
                candidate.RegistDistrictName = registDistrict.name;
            }

            if (updated.RegistSubDistrictId != null)
            {
                var registSubDistrict = await _contextOrg.subDistrict.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistSubDistrictId));

                if (registSubDistrict == null)
                    throw new Exception(GlobalMessages.SubDistrictNotFound);

                candidate.RegistSubDistrictId = registSubDistrict.Id;
                candidate.RegistSubDistrictName = registSubDistrict.name;
                candidate.RegistZipCode = registSubDistrict.zipCode;
            }

            if (updated.CurrentProvinceId != null)
            {
                var currentProvince = await _contextOrg.province.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentProvinceId));

                if (currentProvince == null)
                    throw new Exception(GlobalMessages.ProvinceNotFound);

                candidate.CurrentProvinceId = currentProvince.Id;
                candidate.CurrentProvinceName = currentProvince.name;
            }

            if (updated.CurrentDistrictId != null)
            {
                var currentDistrict = await _contextOrg.district.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentDistrictId));

                if (currentDistrict == null)
                    throw new Exception(GlobalMessages.DistrictNotFound);

                candidate.CurrentDistrictId = currentDistrict.Id;
                candidate.CurrentDistrictName = currentDistrict.name;
            }

            if (updated.CurrentSubDistrictId != null)
            {
                var currentSubDistrict = await _contextOrg.subDistrict.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentSubDistrictId));

                if (currentSubDistrict == null)
                    throw new Exception(GlobalMessages.SubDistrictNotFound);

                candidate.CurrentSubDistrictId = currentSubDistrict.Id;
                candidate.CurrentSubDistrictName = currentSubDistrict.name;
                candidate.CurrentZipCode = currentSubDistrict.zipCode;
            }

            candidate.FirstName = updated.FirstName;
            candidate.LastName = updated.LastName;
            candidate.Nationality = updated.Nationality;
            candidate.DateOfBirth = updated.DateOfBirth;
            candidate.Email = updated.Email;
            candidate.CitizenId = updated.CitizenId;
            candidate.Telephone = updated.Telephone;
            candidate.MobilePhone = updated.MobilePhone;
            candidate.Knowledge = updated.Knowledge;

            candidate.RegistAddress = updated.RegistAddress;
            candidate.RegistSame = updated.RegistSame == null ? null : updated.RegistSame;
            candidate.CurrentAddress = updated.CurrentAddress;

            candidate.OccupationOrg = updated.OccupationOrg;
            candidate.OccupationPile = updated.OccupationPile;
            candidate.OccupationGroup = updated.OccupationGroup;
            candidate.OccupationSalary = updated.OccupationSalary;
            candidate.OccupationPosition = updated.OccupationPosition;
            candidate.OccupationPositionType = updated.OccupationPositionType;
            candidate.OccupationTelephone = updated.OccupationTelephone;

            candidate.ContactFirstname = updated.ContactFirstname;
            candidate.ContactLastname = updated.ContactLastname;
            candidate.ContactRelations = updated.ContactRelations;
            candidate.ContactTel = updated.ContactTel;
            if (candidate.Educations.FirstOrDefault() == null)
            {
                var education = new Education
                {
                    Candidate = candidate,
                    EducationName = updated.EducationName,
                    EducationMajor = updated.EducationMajor,
                    EducationLocation = updated.EducationLocation,
                    EducationType = updated.EducationType,
                    EducationEndDate = updated.EducationEndDate,
                    EducationScores = updated.EducationScores,
                    CreatedAt = DateTime.Now,
                    CreatedUserId = UserId ?? "",
                    CreatedFullName = FullName ?? "",
                    LastUpdatedAt = DateTime.Now,
                    LastUpdateUserId = UserId ?? "",
                    LastUpdateFullName = FullName ?? "",
                };
                if (updated.EducationLevelExamId != null)
                {
                    var educationLevelExam = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelExamId);

                    if (educationLevelExam == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    education.EducationLevelExamId = educationLevelExam.Id;
                    education.EducationLevelExamName = educationLevelExam.name;
                }

                if (updated.EducationLevelHighId != null)
                {
                    var educationLevelHigh = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelHighId);

                    if (educationLevelHigh == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    education.EducationLevelHighId = educationLevelHigh.Id;
                    education.EducationLevelHighName = educationLevelHigh.name;
                }
                await _context.Educations.AddAsync(education);
            }
            else
            {
                candidate.Educations.FirstOrDefault().EducationName = updated.EducationName;
                candidate.Educations.FirstOrDefault().EducationMajor = updated.EducationMajor;
                candidate.Educations.FirstOrDefault().EducationLocation = updated.EducationLocation;
                candidate.Educations.FirstOrDefault().EducationType = updated.EducationType;
                candidate.Educations.FirstOrDefault().EducationEndDate = updated.EducationEndDate;
                candidate.Educations.FirstOrDefault().EducationScores = updated.EducationScores;
                candidate.Educations.FirstOrDefault().LastUpdatedAt = DateTime.Now;
                candidate.Educations.FirstOrDefault().LastUpdateUserId = UserId ?? "";
                candidate.Educations.FirstOrDefault().LastUpdateFullName = FullName ?? "";
                if (updated.EducationLevelExamId != null)
                {
                    var educationLevelExam = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelExamId);

                    if (educationLevelExam == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    candidate.Educations.FirstOrDefault().EducationLevelExamId = educationLevelExam.Id;
                    candidate.Educations.FirstOrDefault().EducationLevelExamName = educationLevelExam.name;
                }

                if (updated.EducationLevelHighId != null)
                {
                    var educationLevelHigh = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelHighId);

                    if (educationLevelHigh == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    candidate.Educations.FirstOrDefault().EducationLevelHighId = educationLevelHigh.Id;
                    candidate.Educations.FirstOrDefault().EducationLevelHighName = educationLevelHigh.name;
                }
            }

            await _context.SaveChangesAsync();
        }

        public async Task UpdateAdminAsync(string candidateId, CandidateResponseItem updated)
        {
            var candidate = await _context.Candidates
                            .AsQueryable()
                            .Include(x => x.Educations)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (updated.PrefixId != null)
            {
                var prefix = await _contextOrg.prefixe.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.PrefixId));

                if (prefix == null)
                    throw new Exception(GlobalMessages.PrefixNotFound);

                candidate.PrefixId = prefix.Id;
                candidate.PrefixName = prefix.name;
            }

            if (updated.ContactPrefixId != null)
            {
                var prefix = await _contextOrg.prefixe.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == updated.ContactPrefixId);

                if (prefix == null)
                    throw new Exception(GlobalMessages.PrefixNotFound);

                candidate.ContactPrefixId = prefix.Id;
                candidate.ContactPrefixName = prefix.name;
            }

            if (updated.ReligionId != null)
            {
                var religion = await _contextOrg.religion.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.ReligionId));

                if (religion == null)
                    throw new Exception(GlobalMessages.ReligionNotFound);

                candidate.ReligionId = religion.Id;
                candidate.ReligionName = religion.name;
            }

            if (updated.RegistProvinceId != null)
            {
                var registProvince = await _contextOrg.province.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistProvinceId));

                if (registProvince == null)
                    throw new Exception(GlobalMessages.ProvinceNotFound);

                candidate.RegistProvinceId = registProvince.Id;
                candidate.RegistProvinceName = registProvince.name;
            }

            if (updated.RegistDistrictId != null)
            {
                var registDistrict = await _contextOrg.district.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistDistrictId));

                if (registDistrict == null)
                    throw new Exception(GlobalMessages.DistrictNotFound);

                candidate.RegistDistrictId = registDistrict.Id;
                candidate.RegistDistrictName = registDistrict.name;
            }

            if (updated.RegistSubDistrictId != null)
            {
                var registSubDistrict = await _contextOrg.subDistrict.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistSubDistrictId));

                if (registSubDistrict == null)
                    throw new Exception(GlobalMessages.SubDistrictNotFound);

                candidate.RegistSubDistrictId = registSubDistrict.Id;
                candidate.RegistSubDistrictName = registSubDistrict.name;
                candidate.RegistZipCode = registSubDistrict.zipCode;
            }

            if (updated.CurrentProvinceId != null)
            {
                var currentProvince = await _contextOrg.province.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentProvinceId));

                if (currentProvince == null)
                    throw new Exception(GlobalMessages.ProvinceNotFound);

                candidate.CurrentProvinceId = currentProvince.Id;
                candidate.CurrentProvinceName = currentProvince.name;
            }

            if (updated.CurrentDistrictId != null)
            {
                var currentDistrict = await _contextOrg.district.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentDistrictId));

                if (currentDistrict == null)
                    throw new Exception(GlobalMessages.DistrictNotFound);

                candidate.CurrentDistrictId = currentDistrict.Id;
                candidate.CurrentDistrictName = currentDistrict.name;
            }

            if (updated.CurrentSubDistrictId != null)
            {
                var currentSubDistrict = await _contextOrg.subDistrict.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentSubDistrictId));

                if (currentSubDistrict == null)
                    throw new Exception(GlobalMessages.SubDistrictNotFound);

                candidate.CurrentSubDistrictId = currentSubDistrict.Id;
                candidate.CurrentSubDistrictName = currentSubDistrict.name;
                candidate.CurrentZipCode = currentSubDistrict.zipCode;
            }

            candidate.FirstName = updated.FirstName;
            candidate.LastName = updated.LastName;
            candidate.Nationality = updated.Nationality;
            candidate.DateOfBirth = updated.DateOfBirth;
            candidate.Email = updated.Email;
            candidate.CitizenId = updated.CitizenId;
            candidate.Telephone = updated.Telephone;
            candidate.MobilePhone = updated.MobilePhone;
            candidate.Knowledge = updated.Knowledge;

            candidate.RegistAddress = updated.RegistAddress;
            candidate.RegistSame = updated.RegistSame == null ? null : updated.RegistSame;
            candidate.CurrentAddress = updated.CurrentAddress;

            candidate.OccupationOrg = updated.OccupationOrg;
            candidate.OccupationPile = updated.OccupationPile;
            candidate.OccupationGroup = updated.OccupationGroup;
            candidate.OccupationSalary = updated.OccupationSalary;
            candidate.OccupationPosition = updated.OccupationPosition;
            candidate.OccupationPositionType = updated.OccupationPositionType;
            candidate.OccupationTelephone = updated.OccupationTelephone;

            candidate.ContactFirstname = updated.ContactFirstname;
            candidate.ContactLastname = updated.ContactLastname;
            candidate.ContactRelations = updated.ContactRelations;
            candidate.ContactTel = updated.ContactTel;

            if (candidate.Educations.FirstOrDefault() == null)
            {
                var education = new Education
                {
                    Candidate = candidate,
                    EducationName = updated.EducationName,
                    EducationMajor = updated.EducationMajor,
                    EducationLocation = updated.EducationLocation,
                    EducationType = updated.EducationType,
                    EducationEndDate = updated.EducationEndDate,
                    EducationScores = updated.EducationScores,
                    CreatedAt = DateTime.Now,
                    CreatedUserId = UserId ?? "",
                    CreatedFullName = FullName ?? "",
                    LastUpdatedAt = DateTime.Now,
                    LastUpdateUserId = UserId ?? "",
                    LastUpdateFullName = FullName ?? "",
                };
                if (updated.EducationLevelExamId != null)
                {
                    var educationLevelExam = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelExamId);

                    if (educationLevelExam == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    education.EducationLevelExamId = educationLevelExam.Id;
                    education.EducationLevelExamName = educationLevelExam.name;
                }

                if (updated.EducationLevelHighId != null)
                {
                    var educationLevelHigh = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelHighId);

                    if (educationLevelHigh == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    education.EducationLevelHighId = educationLevelHigh.Id;
                    education.EducationLevelHighName = educationLevelHigh.name;
                }
                await _context.Educations.AddAsync(education);
            }
            else
            {
                candidate.Educations.FirstOrDefault().EducationName = updated.EducationName;
                candidate.Educations.FirstOrDefault().EducationMajor = updated.EducationMajor;
                candidate.Educations.FirstOrDefault().EducationLocation = updated.EducationLocation;
                candidate.Educations.FirstOrDefault().EducationType = updated.EducationType;
                candidate.Educations.FirstOrDefault().EducationEndDate = updated.EducationEndDate;
                candidate.Educations.FirstOrDefault().EducationScores = updated.EducationScores;
                candidate.Educations.FirstOrDefault().LastUpdatedAt = DateTime.Now;
                candidate.Educations.FirstOrDefault().LastUpdateUserId = UserId ?? "";
                candidate.Educations.FirstOrDefault().LastUpdateFullName = FullName ?? "";
                if (updated.EducationLevelExamId != null)
                {
                    var educationLevelExam = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelExamId);

                    if (educationLevelExam == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    candidate.Educations.FirstOrDefault().EducationLevelExamId = educationLevelExam.Id;
                    candidate.Educations.FirstOrDefault().EducationLevelExamName = educationLevelExam.name;
                }

                if (updated.EducationLevelHighId != null)
                {
                    var educationLevelHigh = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelHighId);

                    if (educationLevelHigh == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    candidate.Educations.FirstOrDefault().EducationLevelHighId = educationLevelHigh.Id;
                    candidate.Educations.FirstOrDefault().EducationLevelHighName = educationLevelHigh.name;
                }
            }
            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsyncInformation(string examId, string positionId, CandidateInformationResponseItem updated)
        {
            var candidateId = await CreateAsyncCandidate(examId, positionId);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (updated.PrefixId != null)
            {
                var prefix = await _contextOrg.prefixe.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.PrefixId));

                if (prefix == null)
                    throw new Exception(GlobalMessages.PrefixNotFound);

                candidate.PrefixId = prefix.Id;
                candidate.PrefixName = prefix.name;
            }

            if (updated.RelationshipId != null)
            {
                var relationship = await _contextOrg.relationship.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RelationshipId));

                if (relationship == null)
                    throw new Exception(GlobalMessages.RelationshipNotFound);

                candidate.RelationshipId = relationship.Id;
                candidate.RelationshipName = relationship.name;
            }

            if (updated.CitizenProvinceId != null)
            {
                var citizenProvince = await _contextOrg.province.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CitizenProvinceId));

                if (citizenProvince == null)
                    throw new Exception(GlobalMessages.ProvinceNotFound);

                candidate.CitizenProvinceId = citizenProvince.Id;
                candidate.CitizenProvinceName = citizenProvince.name;
            }

            if (updated.CitizenDistrictId != null)
            {
                var citizenDistrict = await _contextOrg.district.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CitizenDistrictId));

                if (citizenDistrict == null)
                    throw new Exception(GlobalMessages.DistrictNotFound);

                candidate.CitizenDistrictId = citizenDistrict.Id;
                candidate.CitizenDistrictName = citizenDistrict.name;
            }

            candidate.FirstName = updated.FirstName;
            candidate.LastName = updated.LastName;
            candidate.Nationality = updated.Nationality;
            candidate.DateOfBirth = updated.DateOfBirth;
            candidate.Email = updated.Email;
            candidate.CitizenId = updated.CitizenId;
            candidate.CitizenDate = updated.CitizenDate;
            candidate.Telephone = updated.Telephone;
            candidate.MobilePhone = updated.MobilePhone;
            candidate.Knowledge = updated.Knowledge;

            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsyncProfileImage(string examId, string positionId, IFormFile file)
        {
            var candidateId = await CreateAsyncCandidate(examId, positionId);

            var candidate = await _context.Candidates.AsQueryable()
                            .Include(x => x.ProfileImg)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (candidate.ProfileImg != null)
            {
                await DeleteDocument(candidate.ProfileImg.Id.ToString());
            }

            var doc = await _minioService.UploadFileAsync(file);

            var document = await _context.Documents.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == doc.Id);

            candidate.ProfileImg = document;
            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsyncAdminProfileImage(string candidateId, IFormFile file)
        {
            var candidate = await _context.Candidates.AsQueryable()
                            .Include(x => x.ProfileImg)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (candidate.ProfileImg != null)
            {
                await DeleteDocument(candidate.ProfileImg.Id.ToString());
            }

            var doc = await _minioService.UploadFileAsync(file);

            var document = await _context.Documents.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == doc.Id);

            candidate.ProfileImg = document;
            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsyncAddress(string examId, string positionId, CandidateAddressResponseItem updated)
        {
            var candidateId = await CreateAsyncCandidate(examId, positionId);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (updated.RegistProvinceId != null)
            {
                var registProvince = await _contextOrg.province.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistProvinceId));

                if (registProvince == null)
                    throw new Exception(GlobalMessages.ProvinceNotFound);

                candidate.RegistProvinceId = registProvince.Id;
                candidate.RegistProvinceName = registProvince.name;
            }

            if (updated.RegistDistrictId != null)
            {
                var registDistrict = await _contextOrg.district.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistDistrictId));

                if (registDistrict == null)
                    throw new Exception(GlobalMessages.DistrictNotFound);

                candidate.RegistDistrictId = registDistrict.Id;
                candidate.RegistDistrictName = registDistrict.name;
            }

            if (updated.RegistSubDistrictId != null)
            {
                var registSubDistrict = await _contextOrg.subDistrict.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistSubDistrictId));

                if (registSubDistrict == null)
                    throw new Exception(GlobalMessages.SubDistrictNotFound);

                candidate.RegistSubDistrictId = registSubDistrict.Id;
                candidate.RegistSubDistrictName = registSubDistrict.name;
                candidate.RegistZipCode = registSubDistrict.zipCode;
            }

            if (updated.CurrentProvinceId != null)
            {
                var currentProvince = await _contextOrg.province.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentProvinceId));

                if (currentProvince == null)
                    throw new Exception(GlobalMessages.ProvinceNotFound);

                candidate.CurrentProvinceId = currentProvince.Id;
                candidate.CurrentProvinceName = currentProvince.name;
            }

            if (updated.CurrentDistrictId != null)
            {
                var currentDistrict = await _contextOrg.district.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentDistrictId));

                if (currentDistrict == null)
                    throw new Exception(GlobalMessages.DistrictNotFound);

                candidate.CurrentDistrictId = currentDistrict.Id;
                candidate.CurrentDistrictName = currentDistrict.name;
            }

            if (updated.CurrentSubDistrictId != null)
            {
                var currentSubDistrict = await _contextOrg.subDistrict.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentSubDistrictId));

                if (currentSubDistrict == null)
                    throw new Exception(GlobalMessages.SubDistrictNotFound);

                candidate.CurrentSubDistrictId = currentSubDistrict.Id;
                candidate.CurrentSubDistrictName = currentSubDistrict.name;
                candidate.CurrentZipCode = currentSubDistrict.zipCode;
            }

            candidate.RegistAddress = updated.RegistAddress;
            candidate.RegistSame = updated.RegistSame == null ? null : updated.RegistSame;
            candidate.CurrentAddress = updated.CurrentAddress;

            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsyncFamily(string examId, string positionId, CandidateFamilyResponseItem updated)
        {
            var candidateId = await CreateAsyncCandidate(examId, positionId);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (updated.MarryPrefixId != null)
            {
                var prefix = await _contextOrg.prefixe.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.MarryPrefixId));

                if (prefix == null)
                    throw new Exception(GlobalMessages.PrefixNotFound);

                candidate.MarryPrefixId = prefix.Id;
                candidate.MarryPrefixName = prefix.name;
            }

            if (updated.FatherPrefixId != null)
            {
                var prefix = await _contextOrg.prefixe.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.FatherPrefixId));

                if (prefix == null)
                    throw new Exception(GlobalMessages.PrefixNotFound);

                candidate.FatherPrefixId = prefix.Id;
                candidate.FatherPrefixName = prefix.name;
            }

            if (updated.MotherPrefixId != null)
            {
                var prefix = await _contextOrg.prefixe.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.MotherPrefixId));

                if (prefix == null)
                    throw new Exception(GlobalMessages.PrefixNotFound);

                candidate.MotherPrefixId = prefix.Id;
                candidate.MotherPrefixName = prefix.name;
            }

            candidate.Marry = updated.Marry == null ? null : updated.Marry;
            candidate.MarryFirstName = updated.MarryFirstName;
            candidate.MarryLastName = updated.MarryLastName;
            candidate.MarryOccupation = updated.MarryOccupation;
            candidate.MarryNationality = updated.MarryNationality;
            candidate.FatherFirstName = updated.FatherFirstName;
            candidate.FatherLastName = updated.FatherLastName;
            candidate.FatherOccupation = updated.FatherOccupation;
            candidate.FatherNationality = updated.FatherNationality;
            candidate.MotherFirstName = updated.MotherFirstName;
            candidate.MotherLastName = updated.MotherLastName;
            candidate.MotherOccupation = updated.MotherOccupation;
            candidate.MotherNationality = updated.MotherNationality;

            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsyncOccupation(string examId, string positionId, CandidateOccupationResponseItem updated)
        {
            var candidateId = await CreateAsyncCandidate(examId, positionId);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            candidate.OccupationOrg = updated.OccupationOrg;
            candidate.OccupationPile = updated.OccupationPile;
            candidate.OccupationGroup = updated.OccupationGroup;
            candidate.OccupationSalary = updated.OccupationSalary;
            candidate.OccupationPosition = updated.OccupationPosition;
            candidate.OccupationPositionType = updated.OccupationPositionType;
            candidate.OccupationTelephone = updated.OccupationTelephone;

            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsyncContact(string examId, string positionId, CandidateContactResponseItem updated)
        {
            var candidateId = await CreateAsyncCandidate(examId, positionId);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (updated.ContactPrefixId != null)
            {
                var prefix = await _contextOrg.prefixe.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == updated.ContactPrefixId);

                if (prefix == null)
                    throw new Exception(GlobalMessages.PrefixNotFound);

                candidate.ContactPrefixId = prefix.Id;
                candidate.ContactPrefixName = prefix.name;
            }
            candidate.ContactFirstname = updated.ContactFirstname;
            candidate.ContactLastname = updated.ContactLastname;
            candidate.ContactRelations = updated.ContactRelations;
            candidate.ContactTel = updated.ContactTel;

            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsyncDocument(string examId, string positionId, IFormFile file)
        {
            var candidateId = await CreateAsyncCandidate(examId, positionId);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var doc = await _minioService.UploadFileAsync(file);

            var document = await _context.Documents.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == doc.Id);

            if (document == null)
                throw new Exception(GlobalMessages.NoFileToUpload);

            var candidateDocument = new CandidateDocument
            {
                Candidate = candidate,
                Document = document,
            };

            await _context.CandidateDocuments.AddAsync(candidateDocument);
            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsyncAdminDocument(string candidateId, IFormFile file)
        {
            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var doc = await _minioService.UploadFileAsync(file);

            var document = await _context.Documents.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == doc.Id);

            if (document == null)
                throw new Exception(GlobalMessages.NoFileToUpload);

            var candidateDocument = new CandidateDocument
            {
                Candidate = candidate,
                Document = document,
            };

            await _context.CandidateDocuments.AddAsync(candidateDocument);
            await _context.SaveChangesAsync();
        }

        public async Task DeleteDocument(string documentId)
        {
            await _minioService.DeleteFileAsync(Guid.Parse(documentId));
        }

        public async Task DeleteAsyncDocument(string examId, string positionId, string documentId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .Include(x => x.PositionExam)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            // if (exam.PositionExam != null)
            // {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
            //     var position = exam.PositionExam.Where(x => x.Id == Guid.Parse(positionId)).FirstOrDefault();

            //     if (position == null)
            //         throw new Exception(GlobalMessages.PositionExamNotFound);
            // }
            await _minioService.DeleteFileAsync(Guid.Parse(documentId));
        }

        public async Task DeleteAsyncAdminDocument(string candidateId, string documentId)
        {
            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            await _minioService.DeleteFileAsync(Guid.Parse(documentId));
        }

        public async Task CreateAsyncCareer(string examId, string positionId, CandidateCareerResponseItem updated)
        {
            var candidateId = await CreateAsyncCandidate(examId, positionId);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            var career = new Career
            {
                Candidate = candidate,
                Position = updated.Position,
                Group = updated.Group,
                Pile = updated.Pile,
                Org = updated.Org,
                DurationStart = updated.DurationStart,
                DurationEnd = updated.DurationEnd,
                RangeDate = updated.RangeDate,
                Type = updated.Type,
                CreatedAt = DateTime.Now,
                CreatedUserId = UserId ?? "",
                LastUpdatedAt = DateTime.Now,
                LastUpdateUserId = UserId ?? "",
                CreatedFullName = FullName ?? "",
                LastUpdateFullName = FullName ?? "",
            };

            await _context.Careers.AddAsync(career);
            await _context.SaveChangesAsync();
        }

        public async Task CreateAsyncAdminCareer(string candidateId, CandidateCareerResponseItem updated)
        {
            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            var career = new Career
            {
                Candidate = candidate,
                Position = updated.Position,
                Group = updated.Group,
                Pile = updated.Pile,
                Org = updated.Org,
                DurationStart = updated.DurationStart,
                DurationEnd = updated.DurationEnd,
                RangeDate = updated.RangeDate,
                Type = updated.Type,
                CreatedAt = DateTime.Now,
                CreatedUserId = UserId ?? "",
                LastUpdatedAt = DateTime.Now,
                LastUpdateUserId = UserId ?? "",
                CreatedFullName = FullName ?? "",
                LastUpdateFullName = FullName ?? "",
            };

            await _context.Careers.AddAsync(career);
            await _context.SaveChangesAsync();
        }

        public async Task CreateAsyncEducation(string examId, string positionId, CandidateEducationResponseItem updated)
        {
            var candidateId = await CreateAsyncCandidate(examId, positionId);

            var candidate = await _context.Candidates.AsQueryable()
                            .Include(x => x.Educations)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            if (candidate.Educations.FirstOrDefault() == null)
            {
                var education = new Education
                {
                    Candidate = candidate,
                    EducationName = updated.EducationName,
                    EducationMajor = updated.EducationMajor,
                    EducationLocation = updated.EducationLocation,
                    EducationType = updated.EducationType,
                    EducationEndDate = updated.EducationEndDate,
                    EducationScores = updated.EducationScores,
                    CreatedAt = DateTime.Now,
                    CreatedUserId = UserId ?? "",
                    CreatedFullName = FullName ?? "",
                    LastUpdatedAt = DateTime.Now,
                    LastUpdateUserId = UserId ?? "",
                    LastUpdateFullName = FullName ?? "",
                };
                if (updated.EducationLevelExamId != null)
                {
                    var educationLevelExam = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelExamId);

                    if (educationLevelExam == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    education.EducationLevelExamId = educationLevelExam.Id;
                    education.EducationLevelExamName = educationLevelExam.name;
                }

                if (updated.EducationLevelHighId != null)
                {
                    var educationLevelHigh = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelHighId);

                    if (educationLevelHigh == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    education.EducationLevelHighId = educationLevelHigh.Id;
                    education.EducationLevelHighName = educationLevelHigh.name;
                }
                await _context.Educations.AddAsync(education);
            }
            else
            {
                candidate.Educations.FirstOrDefault().EducationName = updated.EducationName;
                candidate.Educations.FirstOrDefault().EducationMajor = updated.EducationMajor;
                candidate.Educations.FirstOrDefault().EducationLocation = updated.EducationLocation;
                candidate.Educations.FirstOrDefault().EducationType = updated.EducationType;
                candidate.Educations.FirstOrDefault().EducationEndDate = updated.EducationEndDate;
                candidate.Educations.FirstOrDefault().EducationScores = updated.EducationScores;
                candidate.Educations.FirstOrDefault().LastUpdatedAt = DateTime.Now;
                candidate.Educations.FirstOrDefault().LastUpdateUserId = UserId ?? "";
                candidate.Educations.FirstOrDefault().LastUpdateFullName = FullName ?? "";
                if (updated.EducationLevelExamId != null)
                {
                    var educationLevelExam = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelExamId);

                    if (educationLevelExam == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    candidate.Educations.FirstOrDefault().EducationLevelExamId = educationLevelExam.Id;
                    candidate.Educations.FirstOrDefault().EducationLevelExamName = educationLevelExam.name;
                }

                if (updated.EducationLevelHighId != null)
                {
                    var educationLevelHigh = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelHighId);

                    if (educationLevelHigh == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    candidate.Educations.FirstOrDefault().EducationLevelHighId = educationLevelHigh.Id;
                    candidate.Educations.FirstOrDefault().EducationLevelHighName = educationLevelHigh.name;
                }
            }

            await _context.SaveChangesAsync();
        }

        public async Task CreateAsyncAdminEducation(string candidateId, CandidateEducationResponseItem updated)
        {
            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            if (candidate.Educations.FirstOrDefault() == null)
            {
                var education = new Education
                {
                    Candidate = candidate,
                    EducationName = updated.EducationName,
                    EducationMajor = updated.EducationMajor,
                    EducationLocation = updated.EducationLocation,
                    EducationType = updated.EducationType,
                    EducationEndDate = updated.EducationEndDate,
                    EducationScores = updated.EducationScores,
                    CreatedAt = DateTime.Now,
                    CreatedUserId = UserId ?? "",
                    CreatedFullName = FullName ?? "",
                    LastUpdatedAt = DateTime.Now,
                    LastUpdateUserId = UserId ?? "",
                    LastUpdateFullName = FullName ?? "",
                };
                if (updated.EducationLevelExamId != null)
                {
                    var educationLevelExam = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelExamId);

                    if (educationLevelExam == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    education.EducationLevelExamId = educationLevelExam.Id;
                    education.EducationLevelExamName = educationLevelExam.name;
                }

                if (updated.EducationLevelHighId != null)
                {
                    var educationLevelHigh = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelHighId);

                    if (educationLevelHigh == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    education.EducationLevelHighId = educationLevelHigh.Id;
                    education.EducationLevelHighName = educationLevelHigh.name;
                }
                await _context.Educations.AddAsync(education);
            }
            else
            {
                candidate.Educations.FirstOrDefault().EducationName = updated.EducationName;
                candidate.Educations.FirstOrDefault().EducationMajor = updated.EducationMajor;
                candidate.Educations.FirstOrDefault().EducationLocation = updated.EducationLocation;
                candidate.Educations.FirstOrDefault().EducationType = updated.EducationType;
                candidate.Educations.FirstOrDefault().EducationEndDate = updated.EducationEndDate;
                candidate.Educations.FirstOrDefault().EducationScores = updated.EducationScores;
                candidate.Educations.FirstOrDefault().LastUpdatedAt = DateTime.Now;
                candidate.Educations.FirstOrDefault().LastUpdateUserId = UserId ?? "";
                candidate.Educations.FirstOrDefault().LastUpdateFullName = FullName ?? "";
                if (updated.EducationLevelExamId != null)
                {
                    var educationLevelExam = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelExamId);

                    if (educationLevelExam == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    candidate.Educations.FirstOrDefault().EducationLevelExamId = educationLevelExam.Id;
                    candidate.Educations.FirstOrDefault().EducationLevelExamName = educationLevelExam.name;
                }

                if (updated.EducationLevelHighId != null)
                {
                    var educationLevelHigh = await _contextOrg.educationLevel.AsQueryable()
                                    .FirstOrDefaultAsync(x => x.Id == updated.EducationLevelHighId);

                    if (educationLevelHigh == null)
                        throw new Exception(GlobalMessages.EducationLevelNotFound);
                    candidate.Educations.FirstOrDefault().EducationLevelHighId = educationLevelHigh.Id;
                    candidate.Educations.FirstOrDefault().EducationLevelHighName = educationLevelHigh.name;
                }
            }
            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsyncCareer(string careerId, CandidateCareerResponseItem updated)
        {
            var career = await _context.Careers.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(careerId));

            if (career == null)
                throw new Exception(GlobalMessages.CareerNotFound);

            career.Position = updated.Position;
            career.Group = updated.Group;
            career.Pile = updated.Pile;
            career.Org = updated.Org;
            career.DurationStart = updated.DurationStart;
            career.DurationEnd = updated.DurationEnd;
            career.RangeDate = updated.RangeDate;
            career.Type = updated.Type;
            career.LastUpdatedAt = DateTime.Now;
            career.LastUpdateUserId = UserId ?? "";
            career.LastUpdateFullName = FullName ?? "";

            await _context.SaveChangesAsync();
        }

        public async Task DeleteAsyncCareer(string careerId)
        {
            var career = await _context.Careers.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(careerId));

            if (career == null)
                throw new Exception(GlobalMessages.CareerNotFound);

            _context.Careers.Remove(career);

            await _context.SaveChangesAsync();
        }

        // public async Task UpdateAsyncEducation(string educationId, CandidateEducationResponseItem updated)
        // {
        //     var education = await _context.Educations.AsQueryable()
        //                     .FirstOrDefaultAsync(x => x.Id == Guid.Parse(educationId));

        //     if (education == null)
        //         throw new Exception(GlobalMessages.EducationNotFound);

        //     var educationLevel = await _contextOrg.educationLevel.AsQueryable()
        //                     .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.EducationLevelId));

        //     if (educationLevel == null)
        //         throw new Exception(GlobalMessages.EducationLevelNotFound);

        //     education.EducationLevelId = educationLevel.Id;
        //     education.EducationLevelName = educationLevel.Name;
        //     education.Major = updated.Major;
        //     education.Scores = updated.Scores;
        //     education.Name = updated.Name;
        //     education.DurationStart = updated.DurationStart;
        //     education.DurationEnd = updated.DurationEnd;
        //     education.LastUpdatedAt = DateTime.Now;
        //     education.LastUpdateUserId = UserId ?? "";
        //     education.LastUpdateFullName = FullName ?? "";

        //     await _context.SaveChangesAsync();
        // }

        public async Task DeleteAsyncEducation(string educationId)
        {
            var education = await _context.Educations.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(educationId));

            if (education == null)
                throw new Exception(GlobalMessages.EducationNotFound);

            _context.Educations.Remove(education);

            await _context.SaveChangesAsync();
        }

        public async Task<CandidateStatusResponse> GetStatusCandidateService(string examId, string positionId)
        {
            Console.WriteLine(UserId);
            Console.WriteLine("cccccccccccccccccccccccccccccccc");
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var candidate = await _context.Candidates.AsQueryable()
                            .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                candidate = await _context.Candidates.AsQueryable()
                                .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position);
            }

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            return new CandidateStatusResponse { Status = candidate.Status, RejectDetail = candidate.RejectDetail };
        }

        public async Task UserCheckCandidateService(string examId, string positionId, string status)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .Include(x => x.PositionExam)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (exam.RegisterStartDate != null && exam.RegisterStartDate.Value.Date > DateTime.Now.Date)
                throw new Exception("ยังไม่ถึงช่วงเวลาสมัครสอบ");

            if (exam.RegisterEndDate != null && exam.RegisterEndDate.Value.Date < DateTime.Now.Date)
                throw new Exception("หมดเวลาช่วงสมัครสอบ");

            var candidate = await _context.Candidates.AsQueryable()
                            .Include(x => x.PositionExam)
                            .Include(x => x.PeriodExam)
                            .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                var candidateDelete = await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam != position)
                                .ToListAsync();

                _context.Candidates.RemoveRange(candidateDelete);

                candidate = await _context.Candidates.AsQueryable()
                                .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position);
            }

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            if (status == "checkRegister")
            {
                var subject = "แจ้งผลการสมัครสอบคัดเลือก " + exam.Name;
                var body = candidate.FirstName + " " + candidate.LastName + " สถานะการสมัครสอบ: รอยืนยันสถานะการสมัคร";
                if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
                if (candidate.RegisterDate == null)
                    candidate.RegisterDate = DateTime.Now;

                var periodExam = await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == candidate.PeriodExam)
                                .Where(x => x.PositionExam == candidate.PositionExam)
                                .Where(x => x.ExamIdenNumber != null)
                                .Where(x => x.Status != "register")
                                .OrderByDescending(d => d.CreatedAt)
                                .ToListAsync();

                if (periodExam == null)
                    throw new Exception(GlobalMessages.ExamNotFound);
                if (candidate.ExamIdenNumber == null)
                {
                    var num = periodExam.Count() + 1;
                    candidate.ExamIdenNumber = candidate.PositionExam == null ? num.ToString() : candidate.PositionExam.Code + num.ToString("D5");
                }
            }
            if (status == "checkPayment")
            {
                var subject = "แจ้งผลการสมัครสอบคัดเลือก " + exam.Name;
                var body = candidate.FirstName + " " + candidate.LastName + " สถานะการสมัครสอบ: รอเจ้าหน้าที่ตรวจสอบหลักฐานชำระเงิน";
                if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
            }
            candidate.Status = status;
            candidate.RejectDetail = null;

            await _context.SaveChangesAsync();
        }

        public async Task AdminCheckCandidateService(string candidateId, string status, RequestApprove item)
        {
            var candidate = await _context.Candidates.AsQueryable()
                            .Include(x => x.PeriodExam)
                            .Include(x => x.PositionExam)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            if (candidate.PeriodExam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var periodExam = await _context.Candidates.AsQueryable()
                            .Where(x => x.PeriodExam == candidate.PeriodExam && x.ExamIdenNumber != null)
                            .OrderByDescending(d => d.CreatedAt)
                            .ToListAsync();

            if (periodExam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (status != "rejectDelete")
            {
                candidate.Status = status;
                if (status == "rejectRegister")
                {
                    var subject = "แจ้งผลการสมัครสอบคัดเลือก " + candidate.PeriodExam.Name;
                    var body = candidate.FirstName + " " + candidate.LastName + " มีคุณสมบัติสมัครสอบไม่ผ่านกรุณาตรวจสอบข้อมูล  เนื่องจาก: " + item.Reason;
                    if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
                    candidate.RejectDetail = item.Reason;
                }
                else if (status == "rejectPayment")
                {
                    var subject = "แจ้งผลการสมัครสอบคัดเลือก " + candidate.PeriodExam.Name;
                    var body = candidate.FirstName + " " + candidate.LastName + " มีหลักฐานชำระเงินไม่ถูกต้องกรุณาตรวจสอบข้อมูล  เนื่องจาก: " + item.Reason;
                    if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
                    candidate.RejectDetail = item.Reason;
                }
                else if (status == "payment" && candidate.PeriodExam.Fee == 0)
                {
                    var subject = "แจ้งผลการสมัครสอบคัดเลือก " + candidate.PeriodExam.Name;
                    var body = candidate.FirstName + " " + candidate.LastName + " สถานะการสมัครสอบ: ได้รับใบสมัครแล้ว";
                    if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
                    candidate.Status = "checkSeat";
                    candidate.RejectDetail = null;
                    // var num = periodExam.Count() + 1;
                    // candidate.ExamIdenNumber = candidate.PositionExam == null ? num.ToString() : candidate.PositionExam.Code + num;
                }
                else if (status == "payment" && candidate.PeriodExam.Fee != 0)
                {
                    var subject = "แจ้งผลการสมัครสอบคัดเลือก " + candidate.PeriodExam.Name;
                    var body = candidate.FirstName + " " + candidate.LastName + " สถานะการสมัครสอบ: รอชำระค่าสมัครสอบ";
                    if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
                    candidate.RejectDetail = null;
                }
                else if (status == "checkSeat")
                {
                    var subject = "แจ้งผลการสมัครสอบคัดเลือก " + candidate.PeriodExam.Name;
                    var body = candidate.FirstName + " " + candidate.LastName + " สถานะการสมัครสอบ: ได้ชำระค่าสมัครสอบแล้ว";
                    if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
                    // var num = periodExam.Count() + 1;
                    // candidate.ExamIdenNumber = candidate.PositionExam == null ? num.ToString() : candidate.PositionExam.Code + num;
                    candidate.PaymentDate = DateTime.Now;
                    candidate.RejectDetail = null;
                }
            }
            else
            {
                var subject = "แจ้งผลการสมัครสอบคัดเลือก " + candidate.PeriodExam.Name;
                var body = candidate.FirstName + " " + candidate.LastName + " มีคุณสมบัติไม่ผ่านตามเงื่อนไข";
                if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
                _context.Candidates.Remove(candidate);
            }

            await _context.SaveChangesAsync();
        }
        public async Task AdminCheckCandidatesService(string[] candidateId)
        {
            var _num = 0;
            foreach (var _candidateId in candidateId)
            {
                var candidate = await _context.Candidates.AsQueryable()
                                .Include(x => x.PeriodExam)
                                .Include(x => x.PositionExam)
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(_candidateId));
                if (candidate == null)
                    throw new Exception(GlobalMessages.CandidateNotFound);

                if (candidate.Status.Trim().ToUpper() != "CHECKREGISTER")
                    continue;

                if (candidate.PeriodExam == null)
                    throw new Exception(GlobalMessages.ExamNotFound);

                var periodExam = await _context.Candidates.AsQueryable()
                                .Where(x => x.PeriodExam == candidate.PeriodExam)
                                .Where(x => x.PositionExam == candidate.PositionExam)
                                .Where(x => x.ExamIdenNumber != null)
                                .Where(x => x.Status != "register")
                                .OrderByDescending(d => d.CreatedAt)
                                .ToListAsync();

                if (periodExam == null)
                    throw new Exception(GlobalMessages.ExamNotFound);

                candidate.Status = "payment";
                candidate.RejectDetail = null;
                if (candidate.PeriodExam.Fee == 0)
                {
                    var subject = "แจ้งผลการสมัครสอบคัดเลือก " + candidate.PeriodExam.Name;
                    var body = candidate.FirstName + " " + candidate.LastName + " สถานะการสมัครสอบ: ได้รับใบสมัครแล้ว";
                    if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
                    candidate.Status = "checkSeat";
                    if (candidate.ExamIdenNumber == null)
                    {
                        var num = periodExam.Count() + 1;
                        candidate.ExamIdenNumber = candidate.PositionExam == null ? num.ToString() : candidate.PositionExam.Code + num.ToString("D5");
                    }
                }
                else if (candidate.PeriodExam.Fee != 0)
                {
                    var subject = "แจ้งผลการสมัครสอบคัดเลือก " + candidate.PeriodExam.Name;
                    var body = candidate.FirstName + " " + candidate.LastName + " สถานะการสมัครสอบ: รอชำระค่าสมัครสอบ";
                    if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
                }
                ++_num;
            }

            await _context.SaveChangesAsync();
        }
        public async Task AdminRejectToCheckCandidateService(Guid candidateId, string? reason)
        {
            var candidate = await _context.Candidates.AsQueryable()
                            .Include(x => x.PeriodExam)
                            .Include(x => x.PositionExam)
                            .FirstOrDefaultAsync(x => x.Id == candidateId);

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            if (candidate.Status.Trim().ToUpper() != "PAYMENT" && candidate.Status.Trim().ToUpper() != "CHECKSEAT")
                return;

            candidate.RejectDetail = reason;
            candidate.Status = "checkRegister";

            await _context.SaveChangesAsync();
        }

        public async Task AdminPassCandidateService(string candidateId, string status)
        {
            var candidate = await _context.Candidates.AsQueryable()
                            .Include(x => x.PeriodExam)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            if (candidate.PeriodExam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (status == "done")
            {
                var subject = "แจ้งผลการสมัครสอบคัดเลือก " + candidate.PeriodExam.Name;
                var body = candidate.FirstName + " " + candidate.LastName + " สถานะการสมัครสอบ: สอบคัดเลือกสำเร็จ";
                if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
            }
            if (status == "checkPoint")
            {
                var subject = "แจ้งผลการสมัครสอบคัดเลือก " + candidate.PeriodExam.Name;
                var body = candidate.FirstName + " " + candidate.LastName + " สถานะการสมัครสอบ: ติดตามประกาศทาง Website";
                if (candidate.Email != null && candidate.Email != "") _mailService.SendMailToUser(subject, body, candidate.Email);
            }
            candidate.Status = status;
            candidate.RejectDetail = null;

            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsyncPaymentImage(string examId, string positionId, IFormFile file)
        {
            var candidateId = await CreateAsyncCandidate(examId, positionId);

            var candidate = await _context.Candidates.AsQueryable()
                            .Include(x => x.PaymentImg)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (candidate.PaymentImg != null)
            {
                await DeleteDocument(candidate.PaymentImg.Id.ToString());
            }

            var doc = await _minioService.UploadFileAsync(file);

            var document = await _context.Documents.AsQueryable()
                            .FirstOrDefaultAsync(x => x.Id == doc.Id);

            candidate.PaymentImg = document;
            await _context.SaveChangesAsync();
        }

        public async Task<RequestCardCandidate> GetsAsyncCardCandidate(string examId, string positionId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var candidate = await _context.Candidates.AsQueryable()
                                        .Include(x => x.ProfileImg)
                                        .Where(x => x.PeriodExam == exam && x.UserId == UserId)
                                        .FirstOrDefaultAsync();

            var positionName = "";
            var positionLevelName = "";
            var highDegree = "";
            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                candidate = await _context.Candidates.AsQueryable()
                                            .Where(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position)
                                            .FirstOrDefaultAsync();
                positionName = position.PositionName;
                positionLevelName = position.PositionLevelName;
                highDegree = position.HighDegree == true ? "ปริญญาบัตรขึ้นไป" : "ต่ำกว่าปริญญาบัตร";
            }

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            return new RequestCardCandidate
            {
                Avatar = candidate.ProfileImg == null ? "" : _minioService.ImagesPath(candidate.ProfileImg.Id).Result,
                FirstName = candidate.FirstName,
                LastName = candidate.LastName,
                Prefix = candidate.PrefixName,
                CitizenId = candidate.CitizenId,
                ExamIdenNumber = candidate.ExamIdenNumber,
                SeatNumber = candidate.SeatNumber,
                PointTotalA = candidate.PointTotalA,
                PointPath1A = candidate.PointPath1A,
                PointPath2A = candidate.PointPath2A,
                PointPath3A = candidate.PointPath3A,
                PointA = candidate.PointA,
                PointPerA = candidate.PointPerA,
                ResultA = candidate.ResultA,
                PointTotalB = candidate.PointTotalB,
                PointB = candidate.PointB,
                PointPerB = candidate.PointPerB,
                ResultB = candidate.ResultB,
                PointTotalC = candidate.PointTotalC,
                PointPath1C = candidate.PointPath1C,
                PointPath2C = candidate.PointPath2C,
                PointC = candidate.PointC,
                PointPerC = candidate.PointPerC,
                ResultC = candidate.ResultC,
                Pass = candidate.Pass,
                ExamReason = candidate.ExamReason,
                Number = candidate.Number,
                ReviewPoint = candidate.ReviewPoint,
                Review = candidate.Review,
                AnnouncementDate = exam.AnnouncementDate?.AddYears(2),
                Id = candidate.Id,
                Position = positionName,
                PositionLevel = positionLevelName,
                HighDegree = highDegree,
            };
        }

        public async Task<RequestCardCandidate> GetsAsyncAdminCardCandidate(string candidateId)
        {
            var candidate = await _context.Candidates.AsQueryable()
                                        .Include(x => x.ProfileImg)
                                        .Include(x => x.PeriodExam)
                                        .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId));

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            var positionName = "";
            var positionLevelName = "";
            var highDegree = "";
            if (candidate.PositionExam != null)
            {
                positionName = candidate.PositionExam.PositionName;
                positionLevelName = candidate.PositionExam.PositionLevelName;
                highDegree = candidate.PositionExam.HighDegree == true ? "ปริญญาบัตรขึ้นไป" : "ต่ำกว่าปริญญาบัตร";
            }

            return new RequestCardCandidate
            {
                Avatar = candidate.ProfileImg == null ? "" : _minioService.ImagesPath(candidate.ProfileImg.Id).Result,
                FirstName = candidate.FirstName,
                LastName = candidate.LastName,
                Prefix = candidate.PrefixName,
                CitizenId = candidate.CitizenId,
                ExamIdenNumber = candidate.ExamIdenNumber,
                SeatNumber = candidate.SeatNumber,
                PointTotalA = candidate.PointTotalA,
                PointPath1A = candidate.PointPath1A,
                PointPath2A = candidate.PointPath2A,
                PointPath3A = candidate.PointPath3A,
                PointA = candidate.PointA,
                PointPerA = candidate.PointPerA,
                ResultA = candidate.ResultA,
                PointTotalB = candidate.PointTotalB,
                PointB = candidate.PointB,
                PointPerB = candidate.PointPerB,
                ResultB = candidate.ResultB,
                PointTotalC = candidate.PointTotalC,
                PointPath1C = candidate.PointPath1C,
                PointPath2C = candidate.PointPath2C,
                PointC = candidate.PointC,
                PointPerC = candidate.PointPerC,
                ResultC = candidate.ResultC,
                Pass = candidate.Pass,
                ExamReason = candidate.ExamReason,
                Number = candidate.Number,
                ReviewPoint = candidate.ReviewPoint,
                Review = candidate.Review,
                AnnouncementDate = candidate.PeriodExam?.AnnouncementDate?.AddYears(2),
                Id = candidate.Id,
                Position = positionName,
                PositionLevel = positionLevelName,
                HighDegree = highDegree,
            };
        }

        public async Task<string> GetsAsyncBillCandidate(string examId, string positionId)
        {
            // var exam = await _context.PeriodExams.AsQueryable()
            //                 .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            // if (exam == null)
            //     throw new Exception(GlobalMessages.ExamNotFound);

            // var candidate = await _context.Candidates.AsQueryable()
            //                 .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId);

            // if (positionId != "00000000-0000-0000-0000-000000000000")
            // {
            //     var position = await _context.PositionExams.AsQueryable()
            //                     .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

            //     if (position == null)
            //         throw new Exception(GlobalMessages.PositionExamNotFound);

            //     candidate = await _context.Candidates.AsQueryable()
            //                     .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position);
            // }

            // if (candidate == null)
            //     throw new Exception(GlobalMessages.CandidateNotFound);

            // var document = await _context.CandidateDocuments.AsQueryable()
            //                             .Where(x => x.Candidate == candidate)
            //                             .OrderBy(x => x.CreatedAt)
            //                             .Select(x => new FileListResponse
            //                             {
            //                                 Id = x.Document == null ? "" : x.Document.Id.ToString(),
            //                                 FileName = x.Document == null ? "" : x.Document.FileName,
            //                                 FileType = x.Document == null ? "" : x.Document.FileType,
            //                                 FileSize = x.Document == null ? 0 : x.Document.FileSize,
            //                                 Detail = x.Document == null ? "" : x.Document.Id.ToString(),
            //                             })
            //                             .ToListAsync();

            return _minioService.ImagesPathString("ใบจ่ายเงิน.pdf").Result;
        }

        public async Task UpdateReviewAsyncCandidate(string examId, string positionId, RequestReview item)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            var candidate = await _context.Candidates.AsQueryable()
                                        .Include(x => x.ProfileImg)
                                        .Where(x => x.PeriodExam == exam && x.UserId == UserId)
                                        .FirstOrDefaultAsync();

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                candidate = await _context.Candidates.AsQueryable()
                                            .Where(x => x.PeriodExam == exam && x.UserId == UserId && x.PositionExam == position)
                                            .FirstOrDefaultAsync();
            }

            if (candidate == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

            candidate.ReviewPoint = item.ReviewPoint;
            candidate.Review = item.Review;
            await _context.SaveChangesAsync();
        }

        public async Task CheckCitizen(string examId, string positionId, string citizenId)
        {
            var exam = await _context.PeriodExams.AsQueryable()
                            .Where(p => p.CheckDisability == false)
                            .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId));

            if (exam == null)
                throw new Exception(GlobalMessages.ExamNotFound);

            if (positionId != "00000000-0000-0000-0000-000000000000")
            {
                var position = await _context.PositionExams.AsQueryable()
                                .FirstOrDefaultAsync(x => x.Id == Guid.Parse(positionId) && x.PeriodExam == exam);

                if (position == null)
                    throw new Exception(GlobalMessages.PositionExamNotFound);

                var candidate1 = await _context.Candidates.AsQueryable()
                                            .Where(x => x.PeriodExam == exam && x.UserId != UserId && x.PositionExam == position && x.CitizenId == citizenId)
                                            .FirstOrDefaultAsync();
                if (candidate1 != null)
                    throw new Exception(GlobalMessages.CitizanDupicate);
                return;
            }

            var candidate2 = await _context.Candidates.AsQueryable()
                                        .Where(x => x.PeriodExam == exam && x.UserId != UserId && x.CitizenId == citizenId)
                                        .FirstOrDefaultAsync();
            if (candidate2 != null)
                throw new Exception(GlobalMessages.CitizanDupicate);
        }

        public async Task GetExamCandidateAsync(Guid id)
        {
            var exam = await _context.Candidates.AsQueryable()
                        .Where(x => x.Id == id)
                        .Select(p => new
                        {
                            p.Id,
                            ExamIdenNumber = p.ExamIdenNumber,
                            PositionName = p.PositionExam == null ? "" : p.PositionExam.PositionName,
                            PeriodExamName = p.PeriodExam == null ? "" : p.PeriodExam.Name,

                            FullName = $"{p.PrefixName}{p.FirstName} {p.LastName}",
                            Religion = p.ReligionName,
                            Nationality = p.Nationality,
                            DateOfBirth = p.DateOfBirth == null ? "" : p.DateOfBirth.Value.ToThaiFullDate(),
                            Age = p.DateOfBirth == null ? "" : p.DateOfBirth.Value.CalculateAgeStrV2(0, 0),
                            CitizenId = p.CitizenId,

                            EducationLevelExamName = p.Educations.FirstOrDefault() == null ? "" : p.Educations.FirstOrDefault().EducationLevelExamName,
                            EducationName = p.Educations.FirstOrDefault() == null ? "" : p.Educations.FirstOrDefault().EducationName,
                            EducationMajor = p.Educations.FirstOrDefault() == null ? "" : p.Educations.FirstOrDefault().EducationMajor,
                            EducationLocation = p.Educations.FirstOrDefault() == null ? "" : p.Educations.FirstOrDefault().EducationLocation,
                            EducationEndDate = p.Educations.FirstOrDefault() == null || p.Educations.FirstOrDefault().EducationEndDate == null ? "" : p.Educations.FirstOrDefault().EducationEndDate.Value.ToThaiFullDate(),
                            EducationScores = p.Educations.FirstOrDefault() == null ? "" : p.Educations.FirstOrDefault().EducationScores,
                            EducationType = p.Educations.FirstOrDefault() == null ? "" : p.Educations.FirstOrDefault().EducationType,
                            EducationLevelHighName = p.Educations.FirstOrDefault() == null ? "" : p.Educations.FirstOrDefault().EducationLevelHighName,

                            OccupationPositionType = p.OccupationPositionType,
                            OccupationPosition = p.OccupationPosition,
                            OccupationSalary = p.OccupationSalary,
                            OccupationGroup = p.OccupationGroup,
                            OccupationPile = p.OccupationPile,
                            OccupationOrg = p.OccupationOrg,
                            OccupationTelephone = p.OccupationTelephone,

                            Careers = p.Careers.Select(y => new
                            {
                                Position = y.Position,
                                Type = y.Type,
                                DurationStart = y.DurationStart.ToThaiFullDate(),
                                DurationEnd = y.DurationEnd.ToThaiFullDate(),
                                RangeDate = y.RangeDate,
                            }),

                            RegistAddress = p.RegistAddress,
                            RegistProvinceName = p.RegistProvinceName,
                            RegistDistrictName = p.RegistDistrictName,
                            RegistSubDistrictName = p.RegistSubDistrictName,
                            RegistZipCode = p.RegistZipCode,
                            CurrentAddress = p.CurrentAddress,
                            CurrentProvinceName = p.CurrentProvinceName,
                            CurrentSubDistrictName = p.CurrentSubDistrictName,
                            CurrentDistrictName = p.CurrentDistrictName,
                            CurrentZipCode = p.CurrentZipCode,
                            Telephone = p.Telephone,
                            Email = p.Email,

                            ContactFullName = $"{p.ContactPrefixName}{p.ContactFirstname} {p.ContactLastname}",
                            ContactRelations = p.ContactRelations,
                            ContactTel = p.ContactTel,

                            RegisterDate = p.RegisterDate == null ? "" : p.RegisterDate.Value.ToThaiFullDate(),
                        })
                       .FirstOrDefaultAsync();

            if (exam == null)
                throw new Exception(GlobalMessages.CandidateNotFound);

        }

        #endregion
    }
}
