using AutoMapper;
using Lada.Framework.Data.Domains.Categories;
using Lada.Framework.Data.Domains.Cms;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Categories;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Cms;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Categories;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Cms;

namespace Ladaer.BackEnd.Infrastructures.DTO.Profiles
{
    public class CmsMappingProfile : Profile
    {
        public CmsMappingProfile()
        {
            #region Category
            CreateMap<Category, CategoryItem>()
                .ForMember(dest => dest.Slug, opt => opt.MapFrom(src => src.UrlRecord != null ? src.UrlRecord.Slug : ""));
            CreateMap<Category, CategoryTreeItem>();
            CreateMap<CategoryModel, Category>();
            CreateMap<Category, CategoryModel>();
            CreateMap<Category, PostCategoryModel>();
            #endregion

            #region Tag
            CreateMap<Tag, TagItem>()
                .ForMember(dest => dest.CreatedTime, opt => opt.MapFrom(src => src.CreatedTime.HasValue ? src.CreatedTime.Value.ToString("dd/MM/yyyy HH:mm") : ""));
            CreateMap<PostTagModel, Tag>();
            CreateMap<Tag, PostTagModel>();
            CreateMap<Tag, ProductTagModel>();
            CreateMap<ProductTagModel, Tag>();
            #endregion

            #region UrlRecord
            CreateMap<UrlRecord, UrlRecordItem>()
                .ForMember(dest => dest.EntityIdInt, opt => opt.MapFrom(src =>
                    src.EntityName == "Post" ? (src.PostId ?? 0) :
                    src.EntityName == "Category" ? (src.CategoryId ?? 0) :
                    src.EntityName == "Tag" ? (src.TagId ?? 0) :
                    src.EntityName == "Product" ? (src.ProductId ?? 0) :
                    src.EntityName == "JobPost" ? (src.JobPostId ?? 0) :
                    src.EntityName == "Topic" ? (src.TopicId ?? 0) : 0))
                .ForMember(dest => dest.EntityIdLong, opt => opt.MapFrom(src =>
                    src.EntityName == "Post" ? (long)(src.PostId ?? 0) :
                    src.EntityName == "Category" ? (long)(src.CategoryId ?? 0) :
                    src.EntityName == "Tag" ? (long)(src.TagId ?? 0) :
                    src.EntityName == "Product" ? (long)(src.ProductId ?? 0) :
                    src.EntityName == "JobPost" ? (long)(src.JobPostId ?? 0) :
                    src.EntityName == "Topic" ? (long)(src.TopicId ?? 0) : 0L));
            CreateMap<UrlRecord, UrlRecordModel>();
            CreateMap<UrlRecordModel, UrlRecord>();
            #endregion

            #region Post
            CreateMap<Post, PostItem>()
                .ForMember(dest => dest.Slug, opt => opt.MapFrom(src => src.UrlRecord != null && src.UrlRecord.Id > 0 ? src.UrlRecord.Slug : ""))
                .ForMember(dest => dest.CreatedBy, opt => opt.MapFrom(src => src.CreatedByUserName))
                .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<Post, PostModel>()
                .ForMember(dest => dest.PostCategoryModels, opt => opt.MapFrom(src => src.PostCategories!.Select(pt => new PostCategoryModel() { Id = pt.CategoryId, Name = pt.Category.Name }).ToList()))
                .ForMember(dest => dest.Tags, opt => opt.MapFrom(src => src.PostTags!.Select(pt => new PostTagModel() { Id = pt.TagId, Name = pt.Tag.Name }).ToList()))
                .ForMember(dest => dest.UrlRecordId, opt => opt.MapFrom(src => src.UrlRecord!.Id));
            CreateMap<PostModel, Post>();
            #endregion

            #region Product
            CreateMap<Product, ProductItem>()
                .ForMember(dest => dest.Slug, opt => opt.MapFrom(src => src.UrlRecord != null && src.UrlRecord.Id > 0 ? src.UrlRecord.Slug : ""))
                .ForMember(dest => dest.CreatedBy, opt => opt.MapFrom(src => src.CreatedByUserName))
                .ForMember(dest => dest.CreatedTime, opt => opt.MapFrom(src => src.CreatedTime.HasValue ? src.CreatedTime.Value.ToString("dd/MM/yyyy HH:mm") : ""));
            CreateMap<Product, ProductModel>()
                .ForMember(dest => dest.ProductCategoryModels, opt => opt.MapFrom(src => src.ProductCategories!.Select(pt => new ProductCategoryModel() { Id = pt.CategoryId, Name = pt.Category.Name }).ToList()))
                .ForMember(dest => dest.Tags, opt => opt.MapFrom(src => src.ProductTags!.Select(pt => new ProductTagModel() { Id = pt.TagId, Name = pt.Tag.Name }).ToList()));
            CreateMap<ProductModel, Product>();
            #endregion

            #region Topic
            CreateMap<Topic, TopicItem>()
                .ForMember(dest => dest.Slug, opt => opt.MapFrom(src => src.UrlRecord != null && src.UrlRecord.Id > 0 ? src.UrlRecord.Slug : ""))
                .ForMember(dest => dest.CreatedBy, opt => opt.MapFrom(src => src.CreatedByUserName))
                .ForMember(dest => dest.CreatedTime, opt => opt.MapFrom(src => src.CreatedTime.HasValue ? src.CreatedTime.Value.ToString("dd/MM/yyyy HH:mm") : ""));
            CreateMap<Topic, TopicModel>();
            CreateMap<TopicModel, Topic>();
            #endregion
        }
    }

    public static class CmsMappingExtensions
    {
        // Category extensions
        public static CategoryItem ToItem(this Category entity)
            => entity.MapTo<Category, CategoryItem>();

        public static CategoryModel ToModel(this Category entity)
            => entity.MapTo<Category, CategoryModel>();

        public static CategoryTreeItem ToTreeItem(this Category entity)
            => entity.MapTo<Category, CategoryTreeItem>();

        public static PostCategoryModel ToPostCategoryModel(this Category entity)
            => entity.MapTo<Category, PostCategoryModel>();

        public static Category ToEntity(this CategoryModel model)
            => model.MapTo<CategoryModel, Category>();

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

        public static PostTagModel ToPostTagModel(this Tag entity)
            => entity.MapTo<Tag, PostTagModel>();

        public static ProductTagModel ToProductTagModel(this Tag entity)
            => entity.MapTo<Tag, ProductTagModel>();

        public static Tag ToEntity(this PostTagModel model)
            => model.MapTo<PostTagModel, Tag>();

        public static Tag ToEntity(this ProductTagModel model)
            => model.MapTo<ProductTagModel, Tag>();

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

        public static UrlRecordModel ToModel(this UrlRecord entity)
            => entity.MapTo<UrlRecord, UrlRecordModel>();

        public static UrlRecord ToEntity(this UrlRecordModel model)
            => model.MapTo<UrlRecordModel, UrlRecord>();

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

        public static PostModel ToModel(this Post entity)
            => entity.MapTo<Post, PostModel>();

        public static Post ToEntity(this PostModel model)
            => model.MapTo<PostModel, Post>();

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

        public static ProductModel ToModel(this Product entity)
            => entity.MapTo<Product, ProductModel>();

        public static Product ToEntity(this ProductModel model)
            => model.MapTo<ProductModel, Product>();

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

        public static TopicModel ToModel(this Topic entity)
            => entity.MapTo<Topic, TopicModel>();

        public static Topic ToEntity(this TopicModel model)
            => model.MapTo<TopicModel, Topic>();
    }
}