using Hotline.FlowEngine.Workflows;
using Hotline.IndustryClassification;
using Hotline.Orders;
using Hotline.Settings;
using Hotline.Share.Dtos.IndustryClassification;
using Hotline.Share.Enums.FlowEngine;
using Hotline.Share.Enums.Order;
using Hotline.Share.Requests;
using MapsterMapper;
using SqlSugar;
using XF.Domain.Authentications;
using XF.Domain.Dependency;

namespace Hotline.Application.IndustryClassification
{
    public class IndustryClassificationApplication : IIndustryClassificationApplication, IScopeDependency
    {
        private readonly IMapper _mapper;
        private readonly ISystemOrganizeRepository _organizeRepository;
        private readonly IIndustryClassificationRepositpry _industrialManagementRepository;
        private readonly ISessionContext _sessionContext;
        private readonly IOrderRepository _orderRepository;

        public IndustryClassificationApplication(IMapper mapper,
            ISystemOrganizeRepository organizeRepository,
            IIndustryClassificationRepositpry industrialManagementRepository,
            ISessionContext sessionContext,
            IOrderRepository orderRepository)
        {
            _mapper = mapper;
            _organizeRepository = organizeRepository;
            _industrialManagementRepository = industrialManagementRepository;
            _sessionContext = sessionContext;
            _orderRepository = orderRepository;
        }

        /// <summary>
        /// 查询行业列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public ISugarQueryable<IndustrialManagementDto> GetIndustrialManagementList(PagedKeywordRequest dto)
        {
            var query = _industrialManagementRepository.Queryable()
                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.IndustrialName.Contains(dto.Keyword))
                .Select(p => new IndustrialManagementDto
                {
                    Id = p.Id,
                    IndustrialName = p.IndustrialName,
                    UpdateTime = SqlFunc.IIF(p.LastModificationTime != null, p.LastModificationTime, p.CreationTime),
                    OrgCount = SqlFunc.Subqueryable<IndustryAssociations>().Where(s => s.IndustrialManagementId == p.Id).Count()
                })
                .MergeTable()
                .OrderByDescending(p => p.UpdateTime);
            return query;
        }

        /// <summary>
        /// 行业诉求工单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public  ISugarQueryable<IndustrialManagementOrderDto> GetIndustrialManagementOrderList(IndustrialManagementRequestDto dto)
        {
            string industrialId = "";
            if (!_sessionContext.OrgIsCenter)
            {
                var industrial = _industrialManagementRepository.Queryable()
                      .Includes(d => d.Orgs)
                      .FirstAsync(d => d.Orgs.Any(p => p.Id == _sessionContext.RequiredOrgId)).GetAwaiter().GetResult();
                if (industrial is not null)
                    industrialId = industrial.Id;
                else
                    industrialId = "-1";
            }

            var queryorder = _industrialManagementRepository.Queryable()
             .InnerJoin<IndustryAssociations>((i, io) => i.Id == io.IndustrialManagementId)
             .InnerJoin<Order>((i, io, o) => io.OrganizeId == o.ActualHandleOrgCode)
             // .InnerJoin<Order>((i, io, s, o) => s.ExternalId == o.Id)
             .Where((i, io, o) => o.Status >= EOrderStatus.Filed)
             .WhereIF(!string.IsNullOrEmpty(industrialId), (i, io, o) => io.IndustrialManagementId == industrialId)
             .OrderBy((i, io, o) => i.Id)
             .GroupBy((i, io, o) => new
             {
                 o.Id,
                 o.Status,
                 IndustrialId = i.Id,
                 i.IndustrialName,
                 o.Title,
                 o.No,
                 o.AcceptType,
                 o.AcceptTypeCode,
                 o.HotspotId,
                 o.HotspotName,
                 o.HotspotSpliceName,
                 o.HotspotExternal,
                 o.CreationTime,
                 o.StartTime,
                 o.OrgLevelOneCode,
                 o.OrgLevelOneName,
                 o.ActualHandleOrgName,
                 o.ActualHandleOrgCode,
                 o.CounterSignType,
                 o.FiledTime,
                 o.ExpiredTime,
                 o.NearlyExpiredTime,
                 o.NearlyExpiredTimeOne
             })
             .Select((i, io, o) => new IndustrialManagementOrderDto
             {

                 Id = o.Id,
                 Status = o.Status,
                 IndustrialId = i.Id,
                 IndustrialName = i.IndustrialName,
                 Title = o.Title,
                 No = o.No,
                 AcceptType = o.AcceptType,
                 AcceptTypeCode = o.AcceptTypeCode,
                 HotspotId = o.HotspotId,
                 HotspotName = o.HotspotName,
                 HotspotSpliceName = o.HotspotSpliceName,
                 HotspotExternal = o.HotspotExternal,
                 CreationTime = o.CreationTime,
                 StartTime = o.StartTime,
                 OrgLevelOneCode = o.OrgLevelOneCode,
                 OrgLevelOneName = o.OrgLevelOneName,
                 ActualHandleOrgName = o.ActualHandleOrgName,
                 ActualHandleOrgCode = o.ActualHandleOrgCode,
                 CounterSignType = o.CounterSignType,
                 FiledTime = o.FiledTime,
                 ExpiredTime = o.ExpiredTime,
                 NearlyExpiredTime = o.NearlyExpiredTime,
                 NearlyExpiredTimeOne = o.NearlyExpiredTimeOne
             }).MergeTable()
               ;
            var queryhuiqian = _industrialManagementRepository.Queryable()
                .InnerJoin<IndustryAssociations>((i, io) => i.Id == io.IndustrialManagementId)
                .InnerJoin<WorkflowTrace>((i, io, s) => io.OrganizeId == s.HandlerOrgId)
                .InnerJoin<Order>((i, io, s, o) => s.ExternalId == o.Id)
                .Where((i, io, s, o) => o.Status >= EOrderStatus.Filed && s.CountersignPosition == ECountersignPosition.Direct)
                .WhereIF(!string.IsNullOrEmpty(industrialId), (i, io, s, o) => io.IndustrialManagementId == industrialId)
                .OrderBy((i, io, s, o) => i.Id)
                .GroupBy((i, io, s, o) => new
                {
                    o.Id,
                    o.Status,
                    IndustrialId = i.Id,
                    i.IndustrialName,
                    o.Title,
                    o.No,
                    o.AcceptType,
                    o.AcceptTypeCode,
                    o.HotspotId,
                    o.HotspotName,
                    o.HotspotSpliceName,
                    o.HotspotExternal,
                    o.CreationTime,
                    o.StartTime,
                    o.OrgLevelOneCode,
                    o.OrgLevelOneName,
                    o.ActualHandleOrgName,
                    o.ActualHandleOrgCode,
                    o.CounterSignType,
                    o.FiledTime,
                    o.ExpiredTime,
                    o.NearlyExpiredTime,
                    o.NearlyExpiredTimeOne
                })
                .Select((i, io, s, o) => new IndustrialManagementOrderDto
                {

                    Id = o.Id,
                    Status = o.Status,
                    IndustrialId = i.Id,
                    IndustrialName = i.IndustrialName,
                    Title = o.Title,
                    No = o.No,
                    AcceptType = o.AcceptType,
                    AcceptTypeCode = o.AcceptTypeCode,
                    HotspotId = o.HotspotId,
                    HotspotName = o.HotspotName,
                    HotspotSpliceName = o.HotspotSpliceName,
                    HotspotExternal = o.HotspotExternal,
                    CreationTime = o.CreationTime,
                    StartTime = o.StartTime,
                    OrgLevelOneCode = o.OrgLevelOneCode,
                    OrgLevelOneName = o.OrgLevelOneName,
                    ActualHandleOrgName = o.ActualHandleOrgName,
                    ActualHandleOrgCode = o.ActualHandleOrgCode,
                    CounterSignType = o.CounterSignType,
                    FiledTime = o.FiledTime,
                    ExpiredTime = o.ExpiredTime,
                    NearlyExpiredTime = o.NearlyExpiredTime,
                    NearlyExpiredTimeOne = o.NearlyExpiredTimeOne
                }).MergeTable()
                ;

            var query = _orderRepository.UnionAll(queryorder, queryhuiqian)
                       .OrderBy(d => d.Id)
                       .GroupBy(d => new
                       {
                           d.Id,
                           d.Status,
                           d.IndustrialId,
                           d.IndustrialName,
                           d.Title,
                           d.No,
                           d.AcceptType,
                           d.AcceptTypeCode,
                           d.HotspotId,
                           d.HotspotName,
                           d.HotspotSpliceName,
                           d.HotspotExternal,
                           d.CreationTime,
                           d.StartTime,
                           d.OrgLevelOneCode,
                           d.OrgLevelOneName,
                           d.ActualHandleOrgName,
                           d.ActualHandleOrgCode,
                           d.CounterSignType,
                           d.FiledTime,
                           d.ExpiredTime,
                           d.NearlyExpiredTime,
                           d.NearlyExpiredTimeOne
                       })
                       .Select(d => new IndustrialManagementOrderDto
                       {

                           Id = d.Id,
                           Status = d.Status,
                           IndustrialId = d.IndustrialId,
                           IndustrialName = d.IndustrialName,
                           Title = d.Title,
                           No = d.No,
                           AcceptType = d.AcceptType,
                           AcceptTypeCode = d.AcceptTypeCode,
                           HotspotId = d.HotspotId,
                           HotspotName = d.HotspotName,
                           HotspotSpliceName = d.HotspotSpliceName,
                           HotspotExternal = d.HotspotExternal,
                           CreationTime = d.CreationTime,
                           StartTime = d.StartTime,
                           OrgLevelOneCode = d.OrgLevelOneCode,
                           OrgLevelOneName = d.OrgLevelOneName,
                           ActualHandleOrgName = d.ActualHandleOrgName,
                           ActualHandleOrgCode = d.ActualHandleOrgCode,
                           CounterSignType = d.CounterSignType,
                           FiledTime = d.FiledTime,
                           ExpiredTime = d.ExpiredTime,
                           NearlyExpiredTime = d.NearlyExpiredTime,
                           NearlyExpiredTimeOne = d.NearlyExpiredTimeOne
                       }).MergeTable()
                       .WhereIF(!string.IsNullOrEmpty(dto.IndustrialName), d => d.IndustrialName.Contains(dto.IndustrialName))
                       .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title.Contains(dto.Title))
                       .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No.Contains(dto.No))
                       .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), d => d.AcceptTypeCode == dto.AcceptTypeCode)
                         .WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime) //受理时间开始
                       .WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime) //受理时间结束
                       .WhereIF(!string.IsNullOrEmpty(dto.HotspotSpliceName), d => d.HotspotSpliceName.Contains(dto.HotspotSpliceName))
                       .WhereIF(!string.IsNullOrEmpty(dto.OrgLevelOneName), d => d.OrgLevelOneName.Contains(dto.OrgLevelOneName))
                       .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), d => d.ActualHandleOrgName.Contains(dto.ActualHandleOrgName))
                       .OrderByIF(string.IsNullOrEmpty(dto.SortField), d => d.CreationTime, OrderByType.Desc) //默认排序时间为创建时间
                       .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, d => d.CreationTime, OrderByType.Asc) //工单创建时间
                       .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, d => d.CreationTime, OrderByType.Desc) //工单创建时间降序
                       ;

            return query;

            //var query = _industrialManagementRepository.Queryable()
            //    .InnerJoin<IndustryAssociations>((i, io) => i.Id == io.IndustrialManagementId)
            //    .InnerJoin<WorkflowStep>((i, io, s) => io.OrganizeId == s.HandlerOrgId)
            //    .InnerJoin<Order>((i, io, s, o) => s.ExternalId == o.Id)
            //    .Where((i, io, s, o) => o.Status >= EOrderStatus.Filed)
            //    .WhereIF(!string.IsNullOrEmpty(industrialId), (i, io, s, o) => io.IndustrialManagementId == industrialId)
            //    .OrderBy((i, io, s, o) => i.Id)
            //    .GroupBy((i, io, s, o) => new
            //    {
            //        o.Id,
            //        o.Status,
            //        IndustrialId = i.Id,
            //        i.IndustrialName,
            //        o.Title,
            //        o.No,
            //        o.AcceptType,
            //        o.AcceptTypeCode,
            //        o.HotspotId,
            //        o.HotspotName,
            //        o.HotspotSpliceName,
            //        o.HotspotExternal,
            //        o.CreationTime,
            //        o.StartTime,
            //        o.OrgLevelOneCode,
            //        o.OrgLevelOneName,
            //        o.ActualHandleOrgName,
            //        o.ActualHandleOrgCode,
            //        o.CounterSignType,
            //        o.FiledTime,
            //        o.ExpiredTime,
            //        o.NearlyExpiredTime,
            //        o.NearlyExpiredTimeOne
            //    })
            //    .Select((i, io, s, o) => new IndustrialManagementOrderDto
            //    {

            //        Id = o.Id,
            //        Status = o.Status,
            //        IndustrialId = i.Id,
            //        IndustrialName = i.IndustrialName,
            //        Title = o.Title,
            //        No = o.No,
            //        AcceptType = o.AcceptType,
            //        AcceptTypeCode = o.AcceptTypeCode,
            //        HotspotId = o.HotspotId,
            //        HotspotName = o.HotspotName,
            //        HotspotSpliceName = o.HotspotSpliceName,
            //        HotspotExternal = o.HotspotExternal,
            //        CreationTime = o.CreationTime,
            //        StartTime = o.StartTime,
            //        OrgLevelOneCode = o.OrgLevelOneCode,
            //        OrgLevelOneName = o.OrgLevelOneName,
            //        ActualHandleOrgName = o.ActualHandleOrgName,
            //        ActualHandleOrgCode = o.ActualHandleOrgCode,
            //        CounterSignType = o.CounterSignType,
            //        FiledTime = o.FiledTime,
            //        ExpiredTime = o.ExpiredTime,
            //        NearlyExpiredTime = o.NearlyExpiredTime,
            //        NearlyExpiredTimeOne = o.NearlyExpiredTimeOne
            //    }).MergeTable()
            //    .WhereIF(!string.IsNullOrEmpty(dto.IndustrialName), d => d.IndustrialName.Contains(dto.IndustrialName))
            //    .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Title.Contains(dto.Title))
            //    .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.No.Contains(dto.No))
            //    .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), d => d.AcceptTypeCode == dto.AcceptTypeCode)
            //      .WhereIF(dto.StartTime.HasValue, d => d.CreationTime >= dto.StartTime) //受理时间开始
            //    .WhereIF(dto.EndTime.HasValue, d => d.CreationTime <= dto.EndTime) //受理时间结束
            //    .WhereIF(!string.IsNullOrEmpty(dto.HotspotSpliceName), d => d.HotspotSpliceName.Contains(dto.HotspotSpliceName))
            //    .WhereIF(!string.IsNullOrEmpty(dto.OrgLevelOneName), d => d.OrgLevelOneName.Contains(dto.OrgLevelOneName))
            //    .WhereIF(!string.IsNullOrEmpty(dto.ActualHandleOrgName), d => d.ActualHandleOrgName.Contains(dto.ActualHandleOrgName))
            //    .OrderByIF(string.IsNullOrEmpty(dto.SortField), d => d.CreationTime, OrderByType.Desc) //默认排序时间为创建时间
            //    .OrderByIF(dto is { SortField: "creationTime", SortRule: 0 }, d => d.CreationTime, OrderByType.Asc) //工单创建时间
            //    .OrderByIF(dto is { SortField: "creationTime", SortRule: 1 }, d => d.CreationTime, OrderByType.Desc) //工单创建时间降序
            //    ;

        }
    }
}
