using Hotline.Application.FlowEngine;
using Hotline.Caching.Interfaces;
using Hotline.FlowEngine.WorkflowModules;
using Hotline.JudicialManagement;
using Hotline.Orders;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Settings;
using Hotline.Settings.TimeLimits;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.JudicialManagement;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Enums.Order;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using StackExchange.Redis;
using XF.Domain.Authentications;
using XF.Domain.Exceptions;
using XF.Domain.Repository;
using XF.Utility.EnumExtensions;
using Order = Hotline.Orders.Order;

namespace Hotline.Api.Controllers
{
    public class EnforcementOrderController : BaseController
    {
        private readonly IRepository<EnforcementOrders> _enforcementOrdersRepository;
        private readonly IRepository<JudicialComplaintsEventType> _judicialComplaintsEventTypeRepository;
        private readonly IRepository<EnforcementHotspot> _enforcementHotspotRepository;
        private readonly IMapper _mapper;
        private readonly IWorkflowApplication _workflowApplication;
        private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
        private readonly IRepository<SystemOrganize> _systemOrganizeRepository;
        private readonly ISessionContext _sessionContext;
        private readonly IRepository<SystemArea> _systemAreaRepository;
        private readonly IOrderRepository _orderRepository;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="enforcementOrdersRepository"></param>
        /// <param name="judicialComplaintsEventTypeRepository"></param>
        /// <param name="enforcementHotspotRepository"></param>
        /// <param name="mapper"></param>
        /// <param name="workflowApplication"></param>
        /// <param name="sysDicDataCacheManager"></param>
        /// <param name="systemOrganizeRepository"></param>
        /// <param name="sessionContext"></param>
        /// <param name="systemAreaRepository"></param>
        /// <param name="orderRepository"></param>
        public EnforcementOrderController(IRepository<EnforcementOrders> enforcementOrdersRepository,
         IRepository<JudicialComplaintsEventType> judicialComplaintsEventTypeRepository,
         IRepository<EnforcementHotspot> enforcementHotspotRepository,
         IMapper mapper,
         IWorkflowApplication workflowApplication,
         ISystemDicDataCacheManager sysDicDataCacheManager,
         IRepository<SystemOrganize> systemOrganizeRepository,
         ISessionContext sessionContext,
         IOrderRepository orderRepository,
		 IRepository<SystemArea> systemAreaRepository
         )
        {
            _enforcementOrdersRepository = enforcementOrdersRepository;
            _judicialComplaintsEventTypeRepository = judicialComplaintsEventTypeRepository;
            _enforcementHotspotRepository = enforcementHotspotRepository;
            _mapper = mapper;
            _workflowApplication = workflowApplication;
            _sysDicDataCacheManager = sysDicDataCacheManager;
            _systemOrganizeRepository = systemOrganizeRepository;
            _sessionContext = sessionContext;
            _systemAreaRepository = systemAreaRepository;
            _orderRepository = orderRepository;
        }

        /// <summary>
        /// 司法行政监督管理工单查询
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("getorderlist")]
        public async Task<PagedDto<EnforcementOrderListDto>> GetOrderList([FromQuery] QueryEnforcementOrderDto dto)
        {
            var areaCode = _sessionContext.OrgAreaCode ?? "511500";

            var (total, items) = await _enforcementOrdersRepository.Queryable()
           .Includes(x => x.Order)
           .Where(d => d.Order.Id != null)
           .WhereIF(areaCode != "511500", d => d.Order.AreaCode.StartsWith(areaCode))
           .WhereIF(dto.IsEnforcementOrder.HasValue, d => d.IsEnforcementOrder == dto.IsEnforcementOrder)//是否行政执法类
           .WhereIF(dto.IsPassTheBuckOrder.HasValue, d => d.IsPassTheBuckOrder == dto.IsPassTheBuckOrder)//是否推诿
           .WhereIF(dto.IsTheClueTrue.HasValue, d => d.IsTheClueTrue == dto.IsTheClueTrue)//线索是否属实
           .WhereIF(!string.IsNullOrEmpty(dto.EventTypeId), d => dto.EventTypeId == d.EventTypeId)//事项分类
           .WhereIF(!string.IsNullOrEmpty(dto.Title), d => d.Order.Title.Contains(dto.Title!)) //标题
           .WhereIF(!string.IsNullOrEmpty(dto.ProvinceNo), d => d.Order.ProvinceNo.Contains(dto.ProvinceNo)) //省本地编号
           .WhereIF(!string.IsNullOrEmpty(dto.No), d => d.Order.No.Contains(dto.No)) //工单编码
           .WhereIF(dto.AcceptTypes.Any(), d => dto.AcceptTypes.Contains(d.Order.AcceptTypeCode)) //受理类型
           .WhereIF(dto.Channels.Any(), d => dto.Channels.Contains(d.Order.SourceChannelCode)) //来源渠道
           .WhereIF(dto.HotspotIds.Any(), d => dto.HotspotIds.Contains(d.Order.HotspotId)) //热点类型
           .WhereIF(!string.IsNullOrEmpty(dto.TransferPhone), d => d.Order.TransferPhone.Contains(dto.TransferPhone!)) //转接号码
           .WhereIF(dto.OrgCodes.Any(), d => dto.OrgCodes.Contains(d.Order.ActualHandleOrgCode)) //接办部门
           .WhereIF(!string.IsNullOrEmpty(dto.NameOrNo), d => d.Order.AcceptorName.Contains(dto.NameOrNo!) || d.Order.AcceptorStaffNo.Contains(dto.NameOrNo!)) //受理人/坐席
           .WhereIF(dto.CreationTimeStart.HasValue, d => d.Order.CreationTime >= dto.CreationTimeStart) //受理时间开始
           .WhereIF(dto.CreationTimeEnd.HasValue, d => d.Order.CreationTime <= dto.CreationTimeEnd) //受理时间结束
           //.WhereIF(dto.EmergencyLevels.Any(), d => dto.EmergencyLevels.Contains(d.Order.EmergencyLevel))  //紧急程度
           .WhereIF(!string.IsNullOrEmpty(dto.FromPhone), d => d.Order.FromPhone.Contains(dto.FromPhone)) //来电号码
           .WhereIF(!string.IsNullOrEmpty(dto.PhoneNo), d => d.Order.Contact.Contains(dto.PhoneNo!)) //联系电话
           //.WhereIF(!string.IsNullOrEmpty(dto.PushTypeCode), d => d.Order.PushTypeCode == dto.PushTypeCode) //推送分类
           .WhereIF(!string.IsNullOrEmpty(dto.PushTypeCode), d => d.Order.OrderPushTypes.Any(opt=> opt.PushTypeCode == dto.PushTypeCode)) //推送分类
		   .WhereIF(dto.ExpiredTimeStart.HasValue, d => d.Order.ExpiredTime >= dto.ExpiredTimeStart) //超期时间开始
           .WhereIF(dto.ExpiredTimeEnd.HasValue, d => d.Order.ExpiredTime <= dto.ExpiredTimeEnd) //超期时间结束
           .WhereIF(dto.Statuses.Any(), d => dto.Statuses.Contains(d.Order.Status))  //工单状态
           .WhereIF(dto.Statuses.Any(d => d == EOrderStatus.SpecialToUnAccept), d => d.Order.Status <= EOrderStatus.SpecialToUnAccept)
           .WhereIF(!string.IsNullOrEmpty(dto.ActualHandlerName), d => d.Order.ActualHandlerName.Contains(dto.ActualHandlerName)) //接办人
           .WhereIF(!string.IsNullOrEmpty(dto.CurrentStepCode), d => d.Order.ActualHandleStepCode == dto.CurrentStepCode) //当前办理节点
           .WhereIF(dto.ActualHandleTimeStart.HasValue, d => d.Order.ActualHandleTime >= dto.ActualHandleTimeStart) //办结时间开始
           .WhereIF(dto.ActualHandleTimeEnd.HasValue, d => d.Order.ActualHandleTime <= dto.ActualHandleTimeEnd) //办结时间结束
           .WhereIF(dto.IsOverTime == true, d => (d.Order.ExpiredTime < DateTime.Now && d.Order.Status < EOrderStatus.Filed) || (d.Order.ExpiredTime < d.Order.ActualHandleTime && d.Order.Status >= EOrderStatus.Filed)) //是 超期
           .WhereIF(dto.IsOverTime == false, d => (d.Order.ExpiredTime > DateTime.Now && d.Order.Status < EOrderStatus.Filed) || (d.Order.ExpiredTime > d.Order.ActualHandleTime && d.Order.Status >= EOrderStatus.Filed)) //否 超期
           .WhereIF(dto.IdentityType != null, d => d.Order.IdentityType == dto.IdentityType) //来电主体
           .WhereIF(!string.IsNullOrEmpty(dto.FromName), d => d.Order.FromName.Contains(dto.FromName)) //来电人姓名
           .WhereIF(dto.AreaCodes.Any(), d => dto.AreaCodes.Contains(d.Order.AreaCode)) //区域
           .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == true, x => x.Order.IsProvince == true)
           .WhereIF(dto.IsProvinceOrder.HasValue && dto.IsProvinceOrder == false, x => x.Order.IsProvince == false)
           .OrderByDescending(d => d.CreationTime)
           .ToPagedListAsync(dto, HttpContext.RequestAborted);

            var data = _mapper.Map<List<EnforcementOrderListDto>>(items);

            if (_sessionContext.RequiredOrgId == "001188")
            {
                foreach (var item in data)
                {
                    if (item.IsTheClueTrue.HasValue)
                        item.IsShowUpdateButton = true;
                }
            }
            return new PagedDto<EnforcementOrderListDto>(total, data);
        }

        /// <summary>
        /// 列表页面基础数据
        /// </summary>
        /// <returns></returns>
        [HttpGet("base-data")]
        public async Task<object> BaseData()
        {
            var wfModule = await _workflowApplication.GetWorkflowModuleAsync(WorkflowModuleConsts.OrderHandle, HttpContext.RequestAborted);
            var definition = wfModule.Definition;
            var orgList = await _systemOrganizeRepository.Queryable().OrderBy(d => d.Id).ToTreeAsync(x => x.Children, it => it.ParentId, null);
            var judicialManagementOrg = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.JudicialManagementOrg);

            List<SystemOrganize> OrgsOptions = new();
            foreach (var item in judicialManagementOrg)
            {
                var tempOrg = orgList.Find(p => p.Id == item.DicDataValue);
                if (tempOrg != null)
                    OrgsOptions.Add(tempOrg);
            }
            var rsp = new
            {
                AcceptTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType),
                ChannelOptions = _sysDicDataCacheManager.GetSysDicDataCache(TimeLimitBaseDataConsts.SourceChannel),
                OrgsOptions,
                EmergencyLevelOptions = EnumExts.GetDescriptions<EEmergencyLevel>(),
                PushTypeOptions = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.PushType),
                OrderStatusOptions = EnumExts.GetDescriptions<EOrderStatus>(),
                CurrentStepOptions = definition?.Steps.Select(x => new Kv(x.Code, x.Name)),
                IdentityTypeOptions = EnumExts.GetDescriptions<EIdentityType>(),
                EnforcementHotspot = await _enforcementHotspotRepository.Queryable().ToTreeAsync(it => it.Children, it => it.ParentId, null, it => it.Id)
            };
            return rsp;
        }

        /// <summary>
        /// 获取省市区树形
        /// </summary>
        /// <returns></returns>
        [HttpGet("area/tree")]
        public async Task<List<SystemArea>> GetAreaTree()
        {
            var areaCode = _sessionContext.OrgAreaCode;
            if (string.IsNullOrEmpty(areaCode))
                areaCode = "511500";
            if (areaCode == "511500")
            {
                return await _systemAreaRepository.Queryable().OrderBy(x => x.Id).ToTreeAsync(x => x.Children, q => q.ParentId, "510000");
            }
            else
            {
                string parentId = "510000";
                var data = await _systemAreaRepository.GetAsync(p => p.Id == areaCode);
                if (data != null)
                    parentId = data.ParentId;
                return await _systemAreaRepository.Queryable().Where(p => p.Id.StartsWith(areaCode)).OrderBy(x => x.Id).ToTreeAsync(x => x.Children, q => q.ParentId, parentId);
            }
        }

        /// <summary>
        /// 线索核实  
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("clue_verification")]
        public async Task ClueVerificationAsync([FromBody] ClueVerificationDto dto)
        {
            if (dto.OrderIds == null || dto.OrderIds.Count == 0)
                throw UserFriendlyException.SameMessage("工单不能为空");

            if (dto.IsTheClueTrue.HasValue && dto.IsTheClueTrue.Value == true)
            {
                if (string.IsNullOrEmpty(dto.EventTypeId) || string.IsNullOrEmpty(dto.EventTypeName))
                    throw UserFriendlyException.SameMessage("事项不能为空");
            }

            foreach (var item in dto.OrderIds)
            {
                var order = await _enforcementOrdersRepository.GetAsync(p => p.Id == item, HttpContext.RequestAborted);
                if (order == null)
                    throw UserFriendlyException.SameMessage("工单查询失败");

                order.IsTheClueTrue = dto.IsTheClueTrue;

                if (!string.IsNullOrEmpty(dto.EventTypeName))
                    order.EventTypeName = dto.EventTypeName;
                else
                    order.EventTypeName = "";

                if (!string.IsNullOrEmpty(dto.EventTypeSpliceName))
                    order.EventTypeSpliceName = dto.EventTypeSpliceName;
                else
                    order.EventTypeSpliceName = "";

                if (!string.IsNullOrEmpty(dto.EventTypeId))
                {
                    order.EventTypeOneLevelId = dto.EventTypeId.Substring(0, 2);
                    order.EventTypeId = dto.EventTypeId;
                }
                else
                {
                    order.EventTypeOneLevelId = "";
                    order.EventTypeId = "";
                }
                if (!order.IsTheClueTrue.HasValue || order.IsTheClueTrue.Value == false)
                {
                    order.EventTypeName = "";
                    order.EventTypeSpliceName = "";
                    order.EventTypeOneLevelId = "";
                    order.EventTypeId = "";
                }
                await _enforcementOrdersRepository.UpdateAsync(order, HttpContext.RequestAborted);
            }
        }

        /// <summary>
        /// 行政执法活动投诉事项类型- 获取层级分类
        /// </summary>
        /// <returns></returns>
        [HttpGet("treelist")]
        public async Task<List<JudicialComplaintsEventType>> GetTreeList()
        {
            return await _judicialComplaintsEventTypeRepository.Queryable().ToTreeAsync(it => it.Children, it => it.ParentId, null, it => it.Id);
        }

        /// <summary>
        /// 事项分类统计
        /// </summary>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="Id"></param>
        /// <param name="AreaCode"></param>
        /// <returns></returns>
        [HttpGet("event_classification_statistics")]
        public async Task<object> GetEventClassificationStatisticsAsync(DateTime StartTime, DateTime EndTime, string Id, string AreaCode)
        {
            var items = await _judicialComplaintsEventTypeRepository.Queryable()
             .LeftJoin<EnforcementOrders>((x, o) => o.EventTypeSpliceName != null && (x.EventTypeName == o.EventTypeSpliceName || o.EventTypeSpliceName.Contains(x.EventTypeName)))
            .LeftJoin<Order>((x, o, p) => p.Id == o.Id)
            .Where((x, o, p) => p.StartTime >= StartTime && p.StartTime <= EndTime)
            .WhereIF(!string.IsNullOrEmpty(AreaCode), (x, o, p) => p.AreaCode.StartsWith(AreaCode))
             .Where((x, o, p) => x.ParentId == Id)
             .GroupBy((x, o, p) => new { x.Id, x.EventTypeName })
             .Select((x, o, p) => new
             {
                 Id = x.Id,
                 Name = x.EventTypeName,
                 Num = SqlFunc.AggregateSum(SqlFunc.IIF(p.Id != null, 1, 0)),
                 Sublevel = SqlFunc.AggregateSum(SqlFunc.IIF(x.EventTypeName != o.EventTypeName, 1, 0)) > 0,
             })
             .MergeTable()
             .ToListAsync();

            var data = await _enforcementOrdersRepository.Queryable()
                .Includes(x => x.Order)
                .Where(d => d.Order.Id != null)
                .Where(d => d.Order.StartTime >= StartTime && d.Order.StartTime <= EndTime)
                .GroupBy(d => d.Id)
                 .Select(d => new EventClassificationOrderCountDto
                 {
                     TheClueIsTrue = SqlFunc.AggregateSum(SqlFunc.IIF(d.IsTheClueTrue.HasValue && d.IsTheClueTrue.Value == true, 1, 0)),
                     TheClueIsNotTrue = SqlFunc.AggregateSum(SqlFunc.IIF(d.IsTheClueTrue.HasValue && d.IsTheClueTrue.Value == false, 1, 0)),
                     EnforcementOrder = SqlFunc.AggregateSum(SqlFunc.IIF(d.IsEnforcementOrder, 1, 0)),
                     PassTheBuckOrder = SqlFunc.AggregateSum(SqlFunc.IIF(d.IsPassTheBuckOrder, 1, 0))
                 })
                   .ToListAsync();

            var orderCount = new
            {
                TheClueIsTrue = data.Sum(x => x.TheClueIsTrue),
                TheClueIsNotTrue = data.Sum(x => x.TheClueIsNotTrue),
                EnforcementOrder = data.Sum(x => x.EnforcementOrder),
                PassTheBuckOrder = data.Sum(x => x.PassTheBuckOrder),
            };

            return new { List = items, OrderCount = orderCount };
        }

        /// <summary>
        /// 事项分类统计--明细
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("event_classification_statistics_order_list")]
        public async Task<PagedDto<EnforcementOrderListDto>> GetEventClassificationStatisticsOrderListAsync([FromQuery] QueryEventClassificationStatisticsDto dto)
        {
            var (total, items) = await _enforcementOrdersRepository.Queryable()
            .Includes(x => x.Order)
            .Where(d => d.Order.Id != null)
            .Where(d => d.Order.StartTime >= dto.StartTime && d.Order.StartTime <= dto.EndTime && d.EventTypeId != null)
            .WhereIF(!string.IsNullOrEmpty(dto.EventTypeId), d => d.EventTypeId.StartsWith(dto.EventTypeId))
            .WhereIF(!string.IsNullOrEmpty(dto.AreaCode), d => d.Order.AreaCode.StartsWith(dto.AreaCode))
              .OrderByDescending(d => d.CreationTime)
           .ToPagedListAsync(dto, HttpContext.RequestAborted);

            return new PagedDto<EnforcementOrderListDto>(total, _mapper.Map<List<EnforcementOrderListDto>>(items));
        }

        /// <summary>
        /// 执法部门办件统计
        /// </summary>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <returns></returns>
        [HttpGet("enforcement_departmental_processing_statistics")]
        public async Task<object> GetDepartmentalProcessingStatisticsAsync(DateTime StartTime, DateTime EndTime)
        {
            var data = await _enforcementOrdersRepository.Queryable()
                   .Includes(x => x.Order)
                   .Where(d => d.Order.Id != null)
                   .Where(d => d.Order.StartTime >= StartTime && d.Order.StartTime <= EndTime)
                    .GroupBy(d => new
                    {
                        OrgCode = d.Order.OrgLevelOneCode,
                        OrgName = d.Order.OrgLevelOneName
                    })
                    .Select(d => new
                    {
                        OrgCode = d.Order.OrgLevelOneCode,
                        OrgName = d.Order.OrgLevelOneName,
                        CountNum = SqlFunc.AggregateCount(d.Order.OrgLevelOneCode),
                        TheClueIsTrue = SqlFunc.AggregateSum(SqlFunc.IIF(d.IsTheClueTrue.HasValue && d.IsTheClueTrue.Value == true, 1, 0)),
                        TheClueIsNotTrue = SqlFunc.AggregateSum(SqlFunc.IIF(d.IsTheClueTrue.HasValue && d.IsTheClueTrue.Value == false, 1, 0)),
                        EnforcementOrder = SqlFunc.AggregateSum(SqlFunc.IIF(d.IsEnforcementOrder, 1, 0))
                    })
                   .ToListAsync();

            return data;
        }

        /// <summary>
        /// 执法部门办件统计---子级
        /// </summary>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="OrgCode"></param>
        /// <returns></returns>
        [HttpGet("enforcement_departmental_processing_statistics_child")]
        public async Task<object> GetDepartmentalProcessingStatisticsChildAsync(DateTime StartTime, DateTime EndTime, string OrgCode)
        {
            if (string.IsNullOrEmpty(OrgCode))
                throw UserFriendlyException.SameMessage("部门code不能为空!");

            var data = await _enforcementOrdersRepository.Queryable()
                   .Includes(x => x.Order)
                   .Where(d => d.Order.Id != null)
                   .Where(d => d.Order.StartTime >= StartTime && d.Order.StartTime <= EndTime)
                   .WhereIF(OrgCode == "001", d => d.Order.ActualHandleOrgCode == OrgCode)
                   .WhereIF(OrgCode != "001", d => d.Order.ActualHandleOrgCode.StartsWith(OrgCode))
                    .GroupBy(d => new
                    {
                        OrgCode = d.Order.ActualHandleOrgCode,
                        OrgName = d.Order.ActualHandleOrgName
                    })
                    .Select(d => new
                    {
                        OrgCode = d.Order.ActualHandleOrgCode,
                        OrgName = d.Order.ActualHandleOrgName,
                        CountNum = SqlFunc.AggregateCount(d.Order.ActualHandleOrgCode),
                        TheClueIsTrue = SqlFunc.AggregateSum(SqlFunc.IIF(d.IsTheClueTrue.HasValue && d.IsTheClueTrue.Value == true, 1, 0)),
                        TheClueIsNotTrue = SqlFunc.AggregateSum(SqlFunc.IIF(d.IsTheClueTrue.HasValue && d.IsTheClueTrue.Value == false, 1, 0)),
                        EnforcementOrder = SqlFunc.AggregateSum(SqlFunc.IIF(d.IsEnforcementOrder, 1, 0)),

                    })
                   .ToListAsync();

            return data;
        }

        /// <summary>
        /// 执法部门办件统计---明细
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("enforcement_departmental_processing_statistics_order_list")]
        public async Task<PagedDto<EnforcementOrderListDto>> GetDepartmentalProcessingStatisticsOrderListAsync([FromQuery] QueryDepartmentalProcessingStatisticsDto dto)
        {
            var (total, items) = await _enforcementOrdersRepository.Queryable()
            .Includes(x => x.Order)
            .Where(d => d.Order.Id != null)
            .Where(d => d.Order.StartTime >= dto.StartTime && d.Order.StartTime <= dto.EndTime)
            .WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.OrgCode == "001", d => d.Order.ActualHandleOrgCode == dto.OrgCode)
            .WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.OrgCode != "001", d => d.Order.ActualHandleOrgCode.StartsWith(dto.OrgCode))
            .WhereIF(dto.TheClueIsTrue == true, d => d.IsTheClueTrue == true)
            .WhereIF(dto.TheClueIsNotTrue == true, d => d.IsTheClueTrue == false)
            .WhereIF(dto.EnforcementOrder == true, d => d.IsEnforcementOrder == true)
              .OrderByDescending(d => d.CreationTime)
           .ToPagedListAsync(dto, HttpContext.RequestAborted);

            return new PagedDto<EnforcementOrderListDto>(total, _mapper.Map<List<EnforcementOrderListDto>>(items));
        }

        /// <summary>
        /// 区域分类统计
        /// </summary>
        /// <returns></returns>
        [HttpGet("regional_classification_statistics")]
        public async Task<object> GetRegionalClassificationStatisticsAsync(DateTime StartTime, DateTime EndTime)
        {
            var areaCode = _sessionContext.OrgAreaCode ?? "511500";
            var list = await _enforcementOrdersRepository.Queryable()
               .Includes(x => x.Order)
               .Where(x => x.Order.Id != null)
               .Where(x => x.Order.StartTime >= StartTime && x.Order.StartTime <= EndTime)
               .LeftJoin<SystemArea>((x, o) => x.Order.AreaCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")) == o.Id)
               .Where((x, o) => x.Order.Status >= EOrderStatus.Filed)
               .WhereIF(areaCode != "511500", (x, o) => x.Order.AreaCode.StartsWith(areaCode))
               .GroupBy((x, o) => new
               {
                   AreaCode = x.Order.AreaCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")),
                   o.AreaName,
               })
               .Select((x, o) => new
               {
                   AreaCode = x.Order.AreaCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")),
                   AreaName = o.AreaName,
                   OrderCountNum = SqlFunc.AggregateCount(x.Order.AreaCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6"))),
                   TheClueIsTrue = SqlFunc.AggregateSum(SqlFunc.IIF(x.IsTheClueTrue.HasValue && x.IsTheClueTrue.Value == true, 1, 0)),
                   TheClueIsNotTrue = SqlFunc.AggregateSum(SqlFunc.IIF(x.IsTheClueTrue.HasValue && x.IsTheClueTrue.Value == false, 1, 0)),
                   EnforcementOrder = SqlFunc.AggregateSum(SqlFunc.IIF(x.IsEnforcementOrder, 1, 0))
               }).MergeTable()
                .Where(x => x.AreaCode != "519800" && x.AreaCode != "519900")
                .OrderByDescending(it => it.OrderCountNum)
                .ToListAsync();
            return list;
        }

        /// <summary>
        /// 区域分类统计---明细
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("regional_classification_statistics_order_list")]
        public async Task<PagedDto<EnforcementOrderListDto>> GetRegionalClassificationStatisticsOrderListAsync([FromQuery] QueryRegionalClassificationStatisticsDto dto)
        {
            var (total, items) = await _enforcementOrdersRepository.Queryable()
            .Includes(x => x.Order)
            .Where(d => d.Order.Id != null)
            .Where(d => d.Order.StartTime >= dto.StartTime && d.Order.StartTime <= dto.EndTime)
            .WhereIF(!string.IsNullOrEmpty(dto.AreaCode), d => d.Order.AreaCode.StartsWith(dto.AreaCode))
            .WhereIF(dto.TheClueIsTrue == true, d => d.IsTheClueTrue == true)
            .WhereIF(dto.TheClueIsNotTrue == true, d => d.IsTheClueTrue == false)
            .WhereIF(dto.EnforcementOrder == true, d => d.IsEnforcementOrder == true)
              .OrderByDescending(d => d.CreationTime)
           .ToPagedListAsync(dto, HttpContext.RequestAborted);

            return new PagedDto<EnforcementOrderListDto>(total, _mapper.Map<List<EnforcementOrderListDto>>(items));
        }

        /// <summary>
        /// 部门满意度统计
        /// </summary>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="TypeId">1:办件结果 2:办件态度</param>
        /// <returns></returns>
        [HttpGet("enforcement_visit_org_satisfaction_statistics")]
        public async Task<object> GetVisitAndOrgSatisfactionStatisticsAsync(DateTime StartTime, DateTime EndTime, int TypeId)
        {
            var list = await _enforcementOrdersRepository.Queryable()
                 .LeftJoin<OrderVisit>((x, o) => x.Id == o.OrderId)
                 .LeftJoin<OrderVisitDetail>((x, o, p) => o.Id == p.VisitId)
                .Where((x, o, p) => o.VisitTime >= StartTime && o.VisitTime <= EndTime && p.VisitTarget == EVisitTarget.Org && o.VisitState == EVisitState.Visited && !string.IsNullOrEmpty(p.VisitOrgCode))
                .GroupBy((x, o, p) => new
                {
                    VisitOrgCode = p.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6"))
                })
                .Select((x, o, p) => new VisitAndOrgSatisfactionStatisticsDto()
                {
                    OrgCode = p.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6")),
                    TotalSumCount = SqlFunc.AggregateCount(p.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("6"))),
                    VerySatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "5", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "5", 1, 0))),//非常满意数
                    SatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "4", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "4", 1, 0))), //满意数
                    RegardedAsSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "-1", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "-1", 1, 0))),//视为满意
                    DefaultSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "0", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "0", 1, 0))),//默认满意
                    NoSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "2", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "2", 1, 0))),//不满意
                    NoEvaluateCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "7", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "7", 1, 0))),//未做评价
                    NoPutThroughCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "6", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "6", 1, 0))),//未接通
                })
                .MergeTable()
                .LeftJoin<SystemOrganize>((it, o) => it.OrgCode == o.Id)
                .Select((it, o) => new VisitAndOrgSatisfactionStatisticsDto()
                {
                    OrgName = o.Name,
                    OrgCode = it.OrgCode,
                    OrgType = o.OrgType,
                    TotalSumCount = it.TotalSumCount,
                    VerySatisfiedCount = it.VerySatisfiedCount,//非常满意数
                    SatisfiedCount = it.SatisfiedCount, //满意数
                    RegardedAsSatisfiedCount = it.RegardedAsSatisfiedCount,//视为满意
                    DefaultSatisfiedCount = it.DefaultSatisfiedCount,//默认满意
                    NoSatisfiedCount = it.NoSatisfiedCount,//不满意
                    NoEvaluateCount = it.NoEvaluateCount,//未做评价
                    NoPutThroughCount = it.NoPutThroughCount,//未接通
                })
                .ToListAsync();


            var sumModel = new VisitAndOrgSatisfactionStatisticsDto()
            {
                OrgName = "总计",
                TotalSumCount = list.Sum(x => x.TotalSumCount),
                VerySatisfiedCount = list.Sum(x => x.VerySatisfiedCount),
                SatisfiedCount = list.Sum(x => x.SatisfiedCount),
                RegardedAsSatisfiedCount = list.Sum(x => x.RegardedAsSatisfiedCount),
                DefaultSatisfiedCount = list.Sum(x => x.DefaultSatisfiedCount),
                NoSatisfiedCount = list.Sum(x => x.NoSatisfiedCount),
                NoEvaluateCount = list.Sum(x => x.NoEvaluateCount),
                NoPutThroughCount = list.Sum(x => x.NoPutThroughCount),
            };


            return new { DataList = list, SumModel = sumModel };
        }

        /// <summary>
        /// 部门满意度统计----子级
        /// </summary>
        /// <param name="StartTime"></param>
        /// <param name="EndTime"></param>
        /// <param name="TypeId">1:办件结果 2:办件态度</param>
        /// <param name="OrgCode"></param>
        /// <returns></returns>
        [HttpGet("enforcement_visit_org_satisfaction_statistics_child")]
        public async Task<object> GetVisitAndOrgSatisfactionStatisticsChildAsync(DateTime StartTime, DateTime EndTime, int TypeId, string OrgCode)
        {
            var list = await _enforcementOrdersRepository.Queryable()
                 .LeftJoin<OrderVisit>((x, o) => x.Id == o.OrderId)
                 .LeftJoin<OrderVisitDetail>((x, o, p) => o.Id == p.VisitId)
                 .Where((x, o, p) => o.VisitTime >= StartTime && o.VisitTime <= EndTime && p.VisitTarget == EVisitTarget.Org)
                 .Where((x, o, p) => o.VisitState == EVisitState.Visited && !string.IsNullOrEmpty(p.VisitOrgCode))
                 .WhereIF(!string.IsNullOrEmpty(OrgCode) && OrgCode == "001", (x, o, p) => p.VisitOrgCode == OrgCode)
                 .WhereIF(!string.IsNullOrEmpty(OrgCode) && OrgCode != "001", (x, o, p) => p.VisitOrgCode.StartsWith(OrgCode))
                .GroupBy((x, o, p) => new
                {
                    VisitOrgCode = p.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("9"))
                })
                .Select((x, o, p) => new VisitAndOrgSatisfactionStatisticsDto()
                {
                    OrgCode = p.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("9")),
                    TotalSumCount = SqlFunc.AggregateCount(p.VisitOrgCode.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("9"))),
                    VerySatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "5", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "5", 1, 0))),//非常满意数
                    SatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "4", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "4", 1, 0))), //满意数
                    RegardedAsSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "-1", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "-1", 1, 0))),//视为满意
                    DefaultSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "0", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "0", 1, 0))),//默认满意
                    NoSatisfiedCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "2", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "2", 1, 0))),//不满意
                    NoEvaluateCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "7", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "7", 1, 0))),//未做评价
                    NoPutThroughCount = SqlFunc.IIF(TypeId == 1, SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgProcessingResults, "Key") == "6", 1, 0)), SqlFunc.AggregateSum(SqlFunc.IIF(SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == "6", 1, 0))),//未接通
                })
                .MergeTable()
                .LeftJoin<SystemOrganize>((it, o) => it.OrgCode == o.Id)
                .Select((it, o) => new VisitAndOrgSatisfactionStatisticsDto()
                {
                    OrgName = o.Name,
                    OrgCode = it.OrgCode,
                    OrgType = o.OrgType,
                    TotalSumCount = it.TotalSumCount,
                    VerySatisfiedCount = it.VerySatisfiedCount,//非常满意数
                    SatisfiedCount = it.SatisfiedCount, //满意数
                    RegardedAsSatisfiedCount = it.RegardedAsSatisfiedCount,//视为满意
                    DefaultSatisfiedCount = it.DefaultSatisfiedCount,//默认满意
                    NoSatisfiedCount = it.NoSatisfiedCount,//不满意
                    NoEvaluateCount = it.NoEvaluateCount,//未做评价
                    NoPutThroughCount = it.NoPutThroughCount,//未接通
                })
                .ToListAsync();


            var sumModel = new VisitAndOrgSatisfactionStatisticsDto()
            {
                OrgName = "总计",
                TotalSumCount = list.Sum(x => x.TotalSumCount),
                VerySatisfiedCount = list.Sum(x => x.VerySatisfiedCount),
                SatisfiedCount = list.Sum(x => x.SatisfiedCount),
                RegardedAsSatisfiedCount = list.Sum(x => x.RegardedAsSatisfiedCount),
                DefaultSatisfiedCount = list.Sum(x => x.DefaultSatisfiedCount),
                NoSatisfiedCount = list.Sum(x => x.NoSatisfiedCount),
                NoEvaluateCount = list.Sum(x => x.NoEvaluateCount),
                NoPutThroughCount = list.Sum(x => x.NoPutThroughCount),
            };


            return new { DataList = list, SumModel = sumModel };
        }

        ///// <summary>
        ///// 部门满意度统计---明细
        ///// </summary>
        ///// <param name="dto"></param>
        ///// <returns></returns>
        //[HttpGet("enforcement_visit_org_satisfaction_statistics_order_list")]
        //public async Task<PagedDto<EnforcementOrgSatisfactionOrderListDto>> GetVisitAndOrgSatisfactionStatisticsOrderListAsync([FromQuery] QueryOrgSatisfactionStatisticsDto dto)
        //{
        //    dto.EndTime = dto.EndTime.AddDays(1).AddSeconds(-1);

        //    var (total, items) = await _enforcementOrdersRepository.Queryable()
        //        .Includes(x => x.Order)
        //        .Where(x => x.Order.Id != null)
        //        .LeftJoin<OrderVisit>((x, o) => x.Id == o.OrderId)
        //        .LeftJoin<OrderVisitDetail>((x, o, p) => o.Id == p.VisitId)
        //        .Where((x, o, p) => o.VisitTime >= dto.StartTime && o.VisitTime <= dto.EndTime && p.VisitTarget == EVisitTarget.Org)
        //        .Where((x, o, p) => o.VisitState == EVisitState.Visited && !string.IsNullOrEmpty(p.VisitOrgCode))
        //        .WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.OrgCode == "001", (x, o, p) => p.VisitOrgCode == dto.OrgCode)
        //        .WhereIF(!string.IsNullOrEmpty(dto.OrgCode) && dto.OrgCode != "001", (x, o, p) => p.VisitOrgCode.StartsWith(dto.OrgCode))
        //         .WhereIF(dto.TypeId == 1, (x, o, p) => SqlFunc.JsonField(p.OrgProcessingResults, "Key") == dto.DateValue)
        //        .WhereIF(dto.TypeId == 2, (x, o, p) => SqlFunc.JsonField(p.OrgHandledAttitude, "Key") == dto.DateValue)
        //        .Select((x, o, p) => new EnforcementOrgSatisfactionOrderListDto
        //        {
        //            Id = x.Id,
        //            WorkflowId = x.Order.WorkflowId,
        //            VisitId = o.Id,
        //            Status = x.Order.Status,
        //            No = x.Order.No,
        //            SourceChannel = x.Order.SourceChannel,
        //            SourceChannelCode = x.Order.SourceChannelCode,
        //            FromPhone = x.Order.FromPhone,
        //            TransferPhone = x.Order.TransferPhone,
        //            FromName = x.Order.FromName,
        //            Contact = x.Order.Contact,
        //            AcceptType = x.Order.AcceptType,
        //            AcceptTypeCode = x.Order.AcceptTypeCode,
        //            EmergencyLevel = x.Order.EmergencyLevel,
        //            Title = x.Order.Title,
        //            HotspotId = x.Order.HotspotId,
        //            HotspotName = x.Order.HotspotName,
        //            HotspotSpliceName = x.Order.HotspotSpliceName,
        //            CreationTime = x.Order.CreationTime,
        //            IsProvince = x.Order.IsProvince,
        //            ProvinceNo = x.Order.ProvinceNo,
        //            ActualHandleStepName = x.Order.ActualHandleStepName,
        //            ActualHandleTime = x.Order.ActualHandleTime,
        //            ExpiredTime = x.Order.ExpiredTime,
        //            NearlyExpiredTime = x.Order.NearlyExpiredTime,
        //            FiledTime = x.Order.FiledTime,
        //            OrgLevelOneCode = x.Order.OrgLevelOneCode,
        //            OrgLevelOneName = x.Order.OrgLevelOneName,
        //            ActualHandlerName = x.Order.ActualHandlerName,
        //            StartTime = x.Order.StartTime,
        //            ActualHandleOrgName = x.Order.ActualHandleOrgName,
        //            ActualHandleOrgCode = x.Order.ActualHandleOrgCode,
        //            IsEnforcementOrder = x.IsEnforcementOrder,
        //            IsPassTheBuckOrder = x.IsPassTheBuckOrder,
        //            IsTheClueTrue = x.IsTheClueTrue,
        //            EventTypeName = x.EventTypeName,
        //            EventTypeId = x.EventTypeId,
        //            EventTypeSpliceName = x.EventTypeSpliceName,
        //        })
        //       .MergeTable()
        //       .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

        //    return new PagedDto<EnforcementOrgSatisfactionOrderListDto>(total, _mapper.Map<IReadOnlyList<EnforcementOrgSatisfactionOrderListDto>>(items));

        //}

        /// <summary>
        /// 处理司法历史工单数据
        /// </summary>
        /// <param name="Year"></param>
        /// <param name="Month"></param>
        /// <returns></returns>
        [HttpGet("add_enforcement_old_order")]
        public async Task AddEnforcementOldOrder(int Year, int Month)
        {
            DateTime StartDate = DateTime.Parse(Year + "-" + Month + "-01 00:00:00");
            DateTime EndDate = StartDate.AddMonths(1).AddSeconds(-1);

            var list = await _orderRepository.Queryable()
                .Where(p => p.CreationTime >= StartDate && p.CreationTime <= EndDate && p.Status >= EOrderStatus.Filed && p.AcceptTypeCode != "10")
                .Select(p => new EnforcementOldOrder()
                {
                    Id = p.Id,
                    No = p.No,
                    HotspotId = p.HotspotId,
                    HandleTime = p.ActualHandleTime,
                    OrgLevelOneCode = p.OrgLevelOneCode,
                    ActualHandleOrgCode = p.ActualHandleOrgCode
                })
                .ToListAsync();

            if (list != null && list.Count > 0)
            {
                //查询指定热点数据
                var hotList = await _enforcementHotspotRepository.Queryable().ToListAsync();

                //查询指定部门数据
                var JudicialManagementOrg = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.JudicialManagementOrg).ToList();

                foreach (var item in list)
                {
                    bool isAdd = false;

                    //如果是特定热点写入数据
                    if (hotList.Exists(p => p.Id == item.HotspotId))
                        isAdd = true;

                    if (!string.IsNullOrEmpty(item.OrgLevelOneCode))
                    {
                        //如果是特定部门办理写入数据
                        if (JudicialManagementOrg.Exists(p => p.DicDataValue.Trim() == item.OrgLevelOneCode))
                            isAdd = true;
                    }

                    if (isAdd)
                    {
                        //是否存在此工单
                        if (!await _enforcementOrdersRepository.AnyAsync(p => p.Id == item.Id, HttpContext.RequestAborted))
                        {
                            //  不存在写入
                            EnforcementOrders enforcementOrders = new()
                            {
                                Id = item.Id,
                                OrderNo = item.No,
                                IsEnforcementOrder = false,
                                IsTheClueTrue = null,
                                IsPassTheBuckOrder = false,
                                CreationTime = item.HandleTime != null ? item.HandleTime.Value : DateTime.Now
                            };
                            await _enforcementOrdersRepository.AddAsync(enforcementOrders, HttpContext.RequestAborted);

                        }
                    }
                }
            }
        }
    }
}
