using AutoMapper;
using Lada.Framework.Data.Domains.Hr;
using Lada.Framework.Data.Domains.Medias;
using Lada.Framework.Data.Domains.Cms;
using Lada.Framework.Data.Enums;
using Lada.Framework.Infrastructures.Helpers;
using Lada.Framework.Infrastructures.Services;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Hr;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Hr;

namespace Ladaer.BackEnd.Infrastructures.DTO.Profiles
{
    public class HrMappingProfile : Profile
    {
        public HrMappingProfile()
        {
            #region JobPost
            CreateMap<JobPost, JobPostItem>()
                .ForMember(dest => dest.JobStatusStr, opt => opt.MapFrom(src => src.JobStatus.GetDescription()))
                .ForMember(dest => dest.Slug, opt => opt.MapFrom(src => src.UrlRecord != null && src.UrlRecord.Id > 0 ? src.UrlRecord.Slug : ""))
                .ForMember(dest => dest.CandidateCount, opt => opt.MapFrom(src => src.Candidates.Any() ? src.Candidates.Count() : 0))
                .ForMember(dest => dest.CreatedBy, opt => opt.MapFrom(src => src.CreatedByUserName))
                .ForMember(dest => dest.StartDate, opt => opt.MapFrom(src => src.StartDate.HasValue ? src.StartDate.Value.ToString("dd/MM/yyyy") : ""))
                .ForMember(dest => dest.EndDate, opt => opt.MapFrom(src => src.EndDate.HasValue ? src.EndDate.Value.ToString("dd/MM/yyyy") : ""))
                .ForMember(dest => dest.CreatedTime, opt => opt.MapFrom(src => src.CreatedTime.HasValue ? src.CreatedTime.Value.ToString("dd/MM/yyyy HH:mm") : ""))
                .ForMember(dest => dest.JobType, opt => opt.MapFrom(src => src.JobType.GetDescription()));
            CreateMap<JobPost, JobPostModel>()
                .ForMember(dest => dest.Tags, opt => opt.MapFrom(src => src.JobPostTags!.Select(pt => new JobPostTagModel() { Id = pt.TagId, Name = pt.Tag.Name }).ToList()));
            CreateMap<JobPostModel, JobPost>();

            // JobPost Tag mappings  
            CreateMap<JobPostTagModel, Tag>();
            CreateMap<Tag, JobPostTagModel>();
            #endregion

            #region Candidate
            CreateMap<Candidate, CandidateItem>()
                .ForMember(dest => dest.StatusStr, opt => opt.MapFrom(src => src.Status.GetDescription()))
                .ForMember(dest => dest.CreatedTime, opt => opt.MapFrom(src => src.CreatedTime.HasValue ? src.CreatedTime.Value.ToString("dd/MM/yyyy HH:mm") : ""));
            CreateMap<Candidate, CandidateModel>();
            CreateMap<Candidate, CandidateReviewModel>();
            CreateMap<CandidateModel, Candidate>();
            #endregion

            #region Attendance
            CreateMap<Attendance, AttendanceItem>()
                .ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.User.UserName))
                .ForMember(dest => dest.UserFullName, opt => opt.MapFrom(src => src.User.FullName))
                .ForMember(dest => dest.CheckInTime, opt => opt.MapFrom(src => src.CheckInTime.ToString("dd/MM/yyyy HH:mm")))
                .ForMember(dest => dest.CheckOutTime, opt => opt.MapFrom(src => src.CheckOutTime.HasValue ? src.CheckOutTime.Value.ToString("dd/MM/yyyy HH:mm") : ""));
            #endregion
        }
    }

    public static class HrMappingExtensions
    {
        // JobPost extensions
        public static JobPostModel ToModel(this JobPost entity)
            => entity.MapTo<JobPost, JobPostModel>();

        public static JobPostItem ToItem(this JobPost entity)
            => entity.MapTo<JobPost, JobPostItem>();

        public static JobPost ToEntity(this JobPostModel model)
            => model.MapTo<JobPostModel, JobPost>();

        // Candidate extensions
        public static CandidateModel ToModel(this Candidate entity)
            => entity.MapTo<Candidate, CandidateModel>();

        public static CandidateReviewModel ToReviewModel(this Candidate entity)
            => entity.MapTo<Candidate, CandidateReviewModel>();

        public static CandidateItem ToItem(this Candidate entity)
            => entity.MapTo<Candidate, CandidateItem>();

        public static Candidate ToEntity(this CandidateModel model)
            => model.MapTo<CandidateModel, Candidate>();

        // Attendance extensions
        public static AttendanceItem ToItem(this Attendance entity)
            => entity.MapTo<Attendance, AttendanceItem>();

        public static async Task<AttendanceItem> ToItemWithMedia(this Attendance entity, IUnifiedMediaService unifiedMediaService)
        {
            var item = entity.MapTo<Attendance, AttendanceItem>();

            if (entity.AttendanceMedias != null && entity.AttendanceMedias.Any())
            {
                foreach (var attendanceMedia in entity.AttendanceMedias)
                {
                    if (attendanceMedia.Media != null)
                    {
                        var mediaItem = new AttendanceMediaItem
                        {
                            Id = attendanceMedia.Media.Id,
                            AltText = attendanceMedia.Media.AltText ?? string.Empty,
                            Caption = attendanceMedia.Media.Caption ?? string.Empty,
                            DisplayOrder = attendanceMedia.Media.DisplayOrder,
                            Url = await unifiedMediaService.GetUrlBySystemPathAsync(attendanceMedia.Media.SystemPath)
                        };

                        if (attendanceMedia.Type == AttendanceMediaType.CheckIn)
                        {
                            item.CheckInMedias.Add(mediaItem);
                        }
                        else if (attendanceMedia.Type == AttendanceMediaType.CheckOut)
                        {
                            item.CheckOutMedias.Add(mediaItem);
                        }
                    }
                }
            }

            return item;
        }
    }
}