using Hotline.Ai.Visit;
using Hotline.Early;
using Hotline.FlowEngine.Workflows;
using Hotline.Orders;
using Hotline.Share.Dtos.Ai;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Dtos.Order.Detail;
using Hotline.Share.Dtos.Order.OrderDelay;
using Hotline.Share.Dtos.Settings;
using Hotline.Share.Enums.FlowEngine;
using Hotline.Share.Enums.Order;
using Hotline.Share.Tools;
using Mapster;

namespace Hotline.Application.Mappers;

public class OrderMapperConfigs : IRegister
{
    public void Register(TypeAdapterConfig config)
    {
        config.ForType<Order, OrderDto>()
            .IgnoreIf((s, d) => s.OrderExtension == null, d => d.OrderExtension)
            .IgnoreIf((s, d) => s.Hotspot == null, d => d.Hotspot)
               .IgnoreIf((s, d) => s.FwCallRecord == null, d => d.FwCallRecord)
            //.Map(d => d.IsRed, s => string.IsNullOrEmpty(s.SignerId) || !s.ActualHandleStepAcceptTime.HasValue)
            .Map(d => d.IsRed, s => s.WorkflowSteps != null
                                    && s.WorkflowSteps.Any()
                                    && s.WorkflowSteps.First().Status == EWorkflowStepStatus.WaitForAccept)
            ;

        config.ForType<Order, OrderListOutDto>()
            .Map(d => d.IsRed, s => s.WorkflowSteps != null
                                    && s.WorkflowSteps.Any()
                                    && s.WorkflowSteps.First().Status == EWorkflowStepStatus.WaitForAccept)
            ;

        config.ForType<OrderCopy, OrderDto>()
            .Map(d => d.Id, s => s.OrderId)
            .Map(d => d.CopyId, s => s.Id)
            ;

        config.ForType<AiOrderVisitDetail, AiOrderVisitDetailDto>()
            .IgnoreIf((s, d) => s.Order == null, d => d.No)
            .IgnoreIf((s, d) => s.Order == null, d => d.Title)
            .IgnoreIf((s, d) => s.Order == null, d => d.FromName)
            .IgnoreIf((s, d) => s.Order == null, d => d.FromGender)
            .IgnoreIf((s, d) => s.Order == null, d => d.StartTime)
            .IgnoreIf((s, d) => s.Order == null, d => d.FiledTime)
            .Map(d => d.No, s => s.Order.No)
            .Map(d => d.Title, s => s.Order.Title)
            .Map(d => d.FromName, s => s.Order.FromName)
            .Map(d => d.FromGender, s => s.Order.FromGender)
            .Map(d => d.StartTime, s => s.Order.StartTime)
            .Map(d => d.FiledTime, s => s.Order.FiledTime)
            .Map(d => d.RecordUrl, s => s.OrderVisit.RecordUrl)
            .Map(d => d.SeatEvaluate, s => s.AiSeatEvaluate)
            .AfterMapping((s, d) =>
            {
                //d.SeatEvaluate = s.OrderVisit.OrderVisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Seat)?.SeatEvaluate;
                //d.OrgProcessingResults = s.OrderVisit.OrderVisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Org)?.OrgProcessingResults?.Value;
                //d.IsContact = s.OrderVisit.OrderVisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Org)?.IsContact == true ? "是" : s.OrderVisit.OrderVisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Org)?.IsContact == false ? "否" : "";
                //d.Volved = s.OrderVisit.OrderVisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Org)?.Volved == true ? "是" : s.OrderVisit.OrderVisitDetails.FirstOrDefault(x => x.VisitTarget == EVisitTarget.Org)?.Volved == false ? "否" :"";
                //d.IsSuccessText = s.IsSuccess == true ? "是" : s.IsSuccess == false ? "否" : "";
                d.OrgProcessingResults = s.AiOrgProcessingResults?.Value;
                d.IsContact = s.AiIsContact == true ? "是" : s.AiIsContact == false ? "否" : "";
                d.Volved = s.AiVolved == true ? "是" : s.AiVolved == false ? "否" : "";
                d.IsSuccessText = s.IsSuccess == true ? "是" : s.IsSuccess == false ? "否" : "";
            });

        config.ForType<OrderVisitDetail, OrgVisitDetailListResp>()
            //.IgnoreIf((s, d) => s.OrderVisit == null, d => d.VisitId)
            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.Id)
            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.No)
            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.ReTransactNum)
            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.HotspotSpliceName)
            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.OrgLevelOneName)
            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.CurrentHandleOrgName)
            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.Title)
            .IgnoreIf((s, d) => s.OrderVisit.Employee == null, d => d.VisitUser)
            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.Content)
            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.FileOpinion)
            .IgnoreIf((s, d) => s.OrderVisit.Order == null, d => d.FiledTime)
            .Map(d => d.VisitId, s => s.OrderVisit.Id)
            .Map(d => d.Id, s => s.OrderVisit.Order.Id)
            .Map(d => d.No, s => s.OrderVisit.Order.No)
            .Map(d => d.ReTransactNum, s => s.OrderVisit.Order.ReTransactNum)
            .Map(d => d.HotspotSpliceName, s => s.OrderVisit.Order.HotspotSpliceName)
            .Map(d => d.OrgLevelOneName, s => s.OrderVisit.Order.OrgLevelOneName)
            .Map(d => d.CurrentHandleOrgName, s => s.OrderVisit.Order.CurrentHandleOrgName)
            .Map(d => d.Title, s => s.OrderVisit.Order.Title)
            .Map(d => d.VisitUser, s => s.OrderVisit.Employee.Name)
            .Map(d => d.VisitType, s => s.OrderVisit.VisitType)
            .Map(d => d.VisitTime, s => s.OrderVisit.VisitTime)
            .Map(d => d.Content, s => s.OrderVisit.Order.Content)
            .Map(d => d.FileOpinion, s => s.OrderVisit.Order.FileOpinion)
            .Map(d => d.FiledTime, s => s.OrderVisit.Order.FiledTime)
            .AfterMapping((s, d) =>
            {
                d.OrderScreenStatus = s.OrderVisit.Order.OrderScreens.OrderByDescending(q => q.CreationTime).FirstOrDefault()?.Status;
                d.OrgProcessingResults = s.OrgProcessingResults.Value;
            });

        config.ForType<AddOrderDto, Order>()
            .IgnoreIf((s, d) => s.OrderExtension == null, d => d.OrderExtension)
            .Map(d => d.Additions, s => s.Files)
            .IgnoreIf((s, d) => !s.ExpiredTime.HasValue, d => d.ExpiredTime)
            .IgnoreIf((s, d) => !s.NearlyExpiredTime.HasValue, d => d.NearlyExpiredTime)
            .IgnoreIf((s, d) => !s.NearlyExpiredTimeOne.HasValue, d => d.NearlyExpiredTimeOne)
            .IgnoreIf((s, d) => string.IsNullOrEmpty(s.TimeLimit), d => d.TimeLimit)
            .IgnoreIf((s, d) => !s.TimeLimitCount.HasValue, d => d.TimeLimitCount)
            .IgnoreIf((s, d) => !s.TimeLimitUnit.HasValue, d => d.TimeLimitUnit)
            ;

        config.ForType<UpdateOrderDto, Order>()
            .Inherits<AddOrderDto, Order>()
            .Map(d => d.OrderExtension.Id, x => x.Id)
            //.IgnoreIf((s, d) => !string.IsNullOrEmpty(s.FileOpinion), d => d.FileOpinion)
            //.IgnoreIf((s, d) => !string.IsNullOrEmpty(s.CenterOpinion), d => d.CenterToOrgOpinion)
            .Ignore(d => d.ProvinceNo)
            .Ignore(d => d.SmsSended);

        config.ForType<Workflow, Order>()
            .Map(d => d.WorkflowId, s => s.Id)
            .Map(d => d.StartTime, s => s.CreationTime)
            .Ignore(d => d.Status)
            .Ignore(d => d.Title)
            .Ignore(d => d.AcceptorId)
            .Ignore(d => d.AcceptorName)
            .Ignore(d => d.AcceptorStaffNo)
            .Ignore(d => d.ExternalId)
            .Ignore(d => d.CreationTime)
            //.AfterMapping((s, d) =>
            //{
            //    //d.UpdateHandlingStatus(s.IsInCountersign);
            //    d.CurrentStepAcceptTime = s.CurrentStepAcceptTime;
            //})
            ;

        config.ForType<Order, PublishDto>()
            .Inherits<Order, OrderDto>()
            .IgnoreIf((s, d) => s.OrderPublish == null, d => d.PublishState)
            .IgnoreIf((s, d) => s.OrderPublish == null, d => d.ArrangeContent)
            .IgnoreIf((s, d) => s.OrderPublish == null, d => d.PublishTime)
            .IgnoreIf((s, d) => s.OrderPublish == null, d => d.PublishMan)
            .Map(d => d.PublishState, s => s.OrderPublish.PublishState)
            .Map(d => d.ArrangeContent, s => s.OrderPublish.ArrangeContent)
            .Map(d => d.PublishTime, s => s.OrderPublish.CreationTime)
            .Map(d => d.PublishMan, s => s.OrderPublish.CreatorName);


        config.ForType<OrderPublish, PublishedDto>()
            .Map(d => d.PublishState, s => s.PublishState)
            .Map(d => d.ArrangeContent, s => s.ArrangeContent)
            .Map(d => d.PublishTime, s => s.CreationTime)
            .Map(d => d.PublishMan, s => s.CreatorName);

        config.ForType<Order, OrderWaitedDto>()
            .Inherits<Order, OrderDto>();

        config.ForType<OrderVisit, OrderVisitDto>()
            .IgnoreIf((s, d) => s.Employee == null, d => d.EmployeeName)
            .Map(d => d.EmployeeName, s => s.Employee.Name);

        config.ForType<VisitDetailDto, OrderVisitDetail>()
            .Map(d => d.VoiceEvaluate, s => s.VoiceEvaluate)
            .Map(d => d.SeatEvaluate, s => s.SeatEvaluate);

        config.ForType<OrderDelay, Hotline.Share.Dtos.Order.OrderDelay.OrderDelayDto>()
            //.Inherits<Order, OrderDto>()
            .Map(d => d.CurrentStepName, s => s.Workflow.ActualHandleStepName)
            .Map(d => d.ActualHandlerName, s => s.Workflow.ActualHandlerName)
            .IgnoreIf((s, d) => s.Workflow == null, d => d.CurrentStepName)
            .IgnoreIf((s, d) => s.Workflow == null, d => d.ActualHandlerName);

        config.ForType<OrderDelay, OrderDelayStepIdDto>()
            .Map(d => d.StepId, s => s.WorkflowSteps.First().Id)
            .Map(d => d.CurrentStepName, s => s.WorkflowSteps.First().Name)
            .Map(d => d.ActualHandlerName, s => s.WorkflowSteps.First().HandlerName)
            .Map(d => d.DelayCurrentStepName, s => s.WorkflowSteps.First().Name)
            .IgnoreIf((s, d) => s.WorkflowSteps == null || !s.WorkflowSteps.Any(),
                d => d.StepId,
                d => d.CurrentStepName,
                d => d.ActualHandlerName,
                d => d.DelayCurrentStepName)
            ;

        config.ForType<ExpiredTimeWithConfig, UpdateOrderDto>()
            .Map(d => d.TimeLimit, s => s.TimeText)
            .Map(d => d.TimeLimitCount, s => s.Count)
            .Map(d => d.TimeLimitUnit, s => s.TimeType);

        config.ForType<ExpiredTimeWithConfig, Order>()
            .Map(d => d.TimeLimit, s => s.TimeText)
            .Map(d => d.TimeLimitCount, s => s.Count)
            .Map(d => d.TimeLimitUnit, s => s.TimeType);

        config.ForType<OrderScreen, OrderScreenListDto>()
            .IgnoreIf((s, d) => s.VisitDetail == null, d => d.VisitDetail)
            ;

        //config.ForType<OrderHandleFlowDto, Workflow>()
        //    .Map(d => d.RealHandlerPhone, s => s.RealHandlerPhone)
        //    .Map(d => d.RealHandlerName, s => s.RealHandlerName)
        //    .Map(d => d.RealCommunicationMode, s => s.RealCommunicationMode)
        //    .Map(d => d.RealCommunicationTime, s => s.RealCommunicationTime)
        //    .Map(d => d.RealCommunicationAddress, s => s.RealCommunicationAddress)
        //    .Map(d => d.RealIsContacted, s => s.RealIsContacted)
        //    .Map(d => d.RealContactLocale, s => s.RealContactLocale)
        //    .IgnoreNonMapped(true);

        config.ForType<OrderHandleFlowDto, Order>()
            .Map(src => src.RealCommunicationAddress, dest => dest.RealCommunicationAddress)
            .IgnoreIf((src, dest) => string.IsNullOrEmpty(src.RealCommunicationAddress), dest => dest.RealCommunicationAddress)
            .Map(src => src.RealHandlerPhone, dest => dest.RealHandlerPhone)
            .IgnoreIf((src, dest) => string.IsNullOrEmpty(src.RealHandlerPhone), dest => dest.RealHandlerPhone)
            .Map(src => src.RealHandlerName, dest => dest.RealHandlerName)
            .IgnoreIf((src, dest) => string.IsNullOrEmpty(src.RealHandlerName), dest => dest.RealHandlerName)
            .Map(src => src.RealCommunicationMode, dest => dest.RealCommunicationMode)
            .IgnoreIf((src, dest) => src.RealCommunicationMode == null, dest => dest.RealCommunicationMode)
            .Map(src => src.RealCommunicationTime, dest => dest.RealCommunicationTime)
            .IgnoreIf((src, dest) => src.RealCommunicationTime == null, dest => dest.RealCommunicationTime)
            .Map(src => src.RealIsContacted, dest => dest.RealIsContacted)
            .IgnoreIf((src, dest) => src.RealIsContacted == null, dest => dest.RealIsContacted)
            .Map(src => src.RealContactLocale, dest => dest.RealContactLocale)
            .IgnoreIf((src, dest) => src.RealContactLocale == null, dest => dest.RealContactLocale)
            .Map(src => src.IsOther, dest => dest.IsOther)
            .IgnoreIf((src, dest) => src.IsOther == null, dest => dest.IsOther)
            .Map(src => src.OtherRemark, dest => dest.OtherRemark)
            .IgnoreIf((src, dest) => string.IsNullOrEmpty(src.OtherRemark), dest => dest.OtherRemark)
            .Map(src => src.Transpond, dest => dest.Transpond)
            .IgnoreIf((src, dest) => src.Transpond.HasValue == false, dest => dest.Transpond)
            .Map(src => src.TranspondCityId, dest => dest.TranspondCityId)
            .IgnoreIf((src, dest) => string.IsNullOrEmpty(src.TranspondCityId), dest => dest.TranspondCityId)
            .Map(src => src.TranspondCityName, dest => dest.TranspondCityName)
            .IgnoreIf((src, dest) => string.IsNullOrEmpty(src.TranspondCityName), dest => dest.TranspondCityName)
            .Map(src => src.TranspondCityValue, dest => dest.TranspondCityValue)
            .IgnoreIf((src, dest) => string.IsNullOrEmpty(src.TranspondCityValue), dest => dest.TranspondCityValue)
            .Map(src => src.IsStepUrgent, dest => dest.IsStepUrgent)
            .IgnoreIf((src, dest) => src.IsStepUrgent == null, dest => dest.IsStepUrgent)
            .Map(src => src.IsEvasive, dest => dest.IsEvasive)
            .IgnoreIf((src, dest) => src.IsEvasive == null, dest => dest.IsEvasive)
            .Map(src => src.IsInactively, dest => dest.IsInactively)
            .IgnoreIf((src, dest) => src.IsInactively == null, dest => dest.IsInactively)
            .IgnoreNonMapped(true);

        config.ForType<AddOrderComplementDto, OrderComplement>()
            .Map(d => d.No, s => s.CaseSerial);

        config.ForType<WorkflowTrace, OrderFlowTraceDto>()
            //.IgnoreIf((s, d) => s.Status < EWorkflowStepStatus.Handled, d => d.HandlerName)
            //.IgnoreIf((s, d) => s.Status < EWorkflowStepStatus.Handled, d => d.HandlerOrgName)
            //.IgnoreIf((s, d) => s.Status < EWorkflowStepStatus.Handled, d => d.HandleTime)

            .IgnoreIf((s, d) => s.TraceStyle != ETraceStyle.Publish || s.OrderPublish == null, d => d.PublishState)
            .Map(d => d.PublishState, s => s.OrderPublish.PublishState)
            .IgnoreIf((s, d) => s.TraceStyle != ETraceStyle.Publish || s.OrderPublish == null, d => d.ArrangeOpinion)
            .Map(d => d.ArrangeOpinion, s => s.OrderPublish.ArrangeOpinion)
            .AfterMapping((s, d) =>
            {
                if (s.TraceStyle == ETraceStyle.Visit
                   && s.OrderVisit != null
                   && s.OrderVisit.OrderVisitDetails.Any(x => x.VisitTarget == EVisitTarget.Seat))
                {
                    d.VoiceEvaluate = s.OrderVisit.OrderVisitDetails.First(x => x.VisitTarget == EVisitTarget.Seat).VoiceEvaluate;
                    d.SeatEvaluate = s.OrderVisit.OrderVisitDetails.First(x => x.VisitTarget == EVisitTarget.Seat).SeatEvaluate;
                    d.VisitContent = s.OrderVisit.OrderVisitDetails.First(x => x.VisitTarget == EVisitTarget.Seat).VisitContent;
                }
                if (s.TraceStyle == ETraceStyle.Visit
                   && s.OrderVisit != null
                   && s.OrderVisit.OrderVisitDetails.Any(x => x.VisitTarget == EVisitTarget.Org))
                {
                    d.OrderFlowVisitDetails = s.OrderVisit.OrderVisitDetails
                        .Where(x => x.VisitTarget == EVisitTarget.Org)
                        .ToList()
                        .Adapt<IReadOnlyList<OrderFlowVisitDetail>>();
                }
            })
            ;

        config.ForType<OrderVisitDetail, OrderFlowVisitDetail>()
            .IgnoreIf((s, d) => s.OrgProcessingResults == null, d => d.OrgProcessingResults)
            .Map(d => d.OrgProcessingResults, s => s.OrgProcessingResults.Value)
            .IgnoreIf((s, d) => s.OrgNoSatisfiedReason == null, d => d.OrgNoSatisfiedReason)
            .Map(d => d.OrgNoSatisfiedReason, s => s.OrgNoSatisfiedReason.Select(d => d.Value))
            .IgnoreIf((s, d) => s.OrgHandledAttitude == null, d => d.OrgHandledAttitude)
            .Map(d => d.OrgHandledAttitude, s => s.OrgHandledAttitude.Value)
            ;

        config.ForType<OrderVisitDetail, OrderVisitDetailCopy>()
        .Ignore(d => d.CreationTime)
         .Ignore(d => d.CreatorId)
          .Ignore(d => d.CreatorName)
           .Ignore(d => d.CreatorOrgId)
            .Ignore(d => d.CreatorOrgLevel)
            .Ignore(d => d.CreatorOrgName)
            .Ignore(d => d.AreaId)
        ;

        config.ForType<EarlyWarningSettingDto, EarlyWarningSetting>()
            .IgnoreIf((s, d) => false, d => d.Id);
    }
}