using System.Linq;
using BO.AppServer.Data.Entity;
using BO.AppServer.Metadata.Dto;
using BO.AppServer.Metadata.Enums;
using Quadarax.Foundation.Core.Data.Interface.Entity;

namespace BO.AppServer.Business.Mapper
{
    public class MapperLong : Quadarax.Foundation.Core.Data.Mapper.Mapper<MapperLong>
    {
        public MapperLong()
        {
            //TODO: make automatic

            DefineBiDirection<User,UserRDto>();
            DefineBiDirection<User,UserCDto>();
            DefineBiDirection<User,UserUDto>();

            DefineBiDirection<BillingPlan,BillingPlanRDto>();
            DefineBiDirection<BillingPlan,BillingPlanCDto>();
            DefineBiDirection<BillingPlan,BillingPlanUDto>();


            DefineBiDirection<MimeType,MimeTypeRDto>();
            DefineBiDirection<MimeType,MimeTypeCDto>();
            DefineBiDirection<MimeType,MimeTypeUDto>();

            DefineBiDirection<Statistic,StatisticsDto>();

            Define<Workspace, WorkspaceRDto>(builder =>
                {
                    builder.Custom(dest => dest.Structures, src => src.Structures.MapList<Structure, StructureRDto>());
                    builder.Custom(dest => dest.Audit, src => new BoAuditDto()
                    {
                        Created = src.Created,
                        Changed = src.Modified,
                        CreatedBy = src.CreatedByUser.Name,
                        ChangedBy = src.ModifiedByUser != null ? src.ModifiedByUser.Name : string.Empty
                    });
                    //calculate on demand  builder.Custom(dest => dest.BillingPlanCode, src => src.WorkspaceBillings.OrderByDescending(x=>x.Created).FirstOrDefault().BillingPlan.Code);
                });

            Define<WorkspaceCDto, Workspace>();
            Define<WorkspaceUDto, Workspace>();

            DefineReverse<DocumentCDto, Metadocument>();

            Define<Metadocument, DocumentRDto>();
            Define<Metadocument, DocumentRDto>(builder =>
            {
                builder.Custom(dest => dest.Audit, src => new BoAuditDto()
                {
                    Created = src.Created,
                    Changed = src.Modified,
                    CreatedBy = src.CreatedByUser.Name,
                    ChangedBy = src.ModifiedByUser != null ? src.ModifiedByUser.Name : string.Empty
                });
                builder.Custom(dest => dest.Artifacts, src => src.Artifacts.MapList<Artifact, ArtifactRDto>());
                //calculate on demand  builder.Custom(dest => dest.BillingPlanCode, src => src.WorkspaceBillings.OrderByDescending(x=>x.Created).FirstOrDefault().BillingPlan.Code);
            });
            
            //Define<ArtifactCDto, Artifact>();
            Define<Artifact, ArtifactRDto>(builder =>
            {
                builder.Custom(dest => dest.Audit, src => new BoAuditDto()
                {
                    Created = src.Created,
                    Changed = null,
                    CreatedBy = src.CreatedByUser.Name,
                    ChangedBy = string.Empty
                });
                //calculate on demand  builder.Custom(dest => dest.BillingPlanCode, src => src.WorkspaceBillings.OrderByDescending(x=>x.Created).FirstOrDefault().BillingPlan.Code);
            });







            Define<Structure, StructureRDto>(builder =>
            {
                builder.Custom(dest => dest.DocumentAllCount, src => src.Metadocuments.Count);
                builder.Custom(dest => dest.DocumentPendingCount, src => src.Metadocuments.Count(x => x.Status == (int)DocumentStatusEnum.Pending));
                builder.Custom(dest => dest.DocumentWorkingCount, src => src.Metadocuments.Count(x => x.Status == (int)DocumentStatusEnum.Processing));
                builder.Custom(dest => dest.DocumentDoneCount, src => src.Metadocuments.Count(x => x.Status == (int)DocumentStatusEnum.DoneOk));
                builder.Custom(dest => dest.DocumentFailCount, src => src.Metadocuments.Count(x => x.Status == (int)DocumentStatusEnum.DoneFail));
                builder.Custom(dest => dest.Audit, src => new BoAuditDto()
                {
                    Created = src.Created,
                    Changed = src.Modified,
                    CreatedBy = src.CreatedByUser.Name,
                    ChangedBy = src.ModifiedByUser != null ? src.ModifiedByUser.Name : string.Empty
                });

            });


            Define<RegistrationCDto, Registration>();
            Define<RegistrationUDto, Registration>();
            Define<Registration, RegistrationRDto>(builder =>
            {
                builder.Custom(dest => dest.Audit, src => new BoAuditTimestampDto()
                {
                    Created = src.Created,
                    Changed = null,
                });
            });


        }
        public void DefineBiDirection<TDao, TDto>() 
            where TDao : class, IDao<long>, new()
            where TDto : class, IDto, new()
        {
            DefineBiDirection<TDao, TDto, long>();
        }



    }
}
