using DocumentFormat.OpenXml.Wordprocessing;
using Hotline.Application.Bulletin;
using Hotline.Article;
using Hotline.Caching.Interfaces;
using Hotline.FlowEngine.Workflows;
using Hotline.Orders;
using Hotline.Push.Notifies;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Settings;
using Hotline.Settings.Hotspots;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.Article;
using Hotline.Share.Dtos.DataSharingSearch;
using Hotline.Share.Dtos.FlowEngine.Workflow;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Dtos.WebPortal;
using Hotline.Share.Enums.Article;
using Hotline.Share.Enums.FlowEngine;
using Hotline.Share.Enums.Order;
using Hotline.Share.Enums.Push;
using Hotline.WebPortal;
using MapsterMapper;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.Formula.Functions;
using SqlSugar;
using System.Threading;
using XF.Domain.Exceptions;
using XF.Domain.Repository;

namespace Hotline.Api.Controllers
{
    /// <summary>
    /// 提供给DS查询数据用
    /// </summary>
    public class DataSharingController : BaseController
    {
        private readonly IMapper _mapper;
        private readonly IOrderRepository _orderRepository;
        private readonly IRepository<Bulletin> _bulletinRepository;
        private readonly IBulletinApplication _bulletinApplication;
        private readonly ISystemDicDataCacheManager _sysDicDataCacheManager;
        private readonly IRepository<WorkflowTrace> _workflowTraceRepository;
        private readonly IRepository<Hotspot> _hotspotTypeRepository;
        private readonly IMediator _mediator;
        private readonly IRepository<OldPublicData> _oldPublicDataRepository;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mapper"></param>
        /// <param name="orderRepository"></param>
        /// <param name="bulletinRepository"></param>
        /// <param name="bulletinApplication"></param>
        /// <param name="sysDicDataCacheManager"></param>
        /// <param name="workflowTraceRepository"></param>
        /// <param name="hotspotTypeRepository"></param>
        /// <param name="mediator"></param>
        /// <param name="oldPublicDataRepository"></param>
        public DataSharingController(IMapper mapper,
            IOrderRepository orderRepository,
            IRepository<Bulletin> bulletinRepository,
            IBulletinApplication bulletinApplication,
            ISystemDicDataCacheManager sysDicDataCacheManager,
            IRepository<WorkflowTrace> workflowTraceRepository,
            IRepository<Hotspot> hotspotTypeRepository,
            IMediator mediator,
            IRepository<OldPublicData> oldPublicDataRepository)
        {
            _mapper = mapper;
            _orderRepository = orderRepository;
            _bulletinRepository = bulletinRepository;
            _bulletinApplication = bulletinApplication;
            _sysDicDataCacheManager = sysDicDataCacheManager;
            _workflowTraceRepository = workflowTraceRepository;
            _hotspotTypeRepository = hotspotTypeRepository;
            _mediator = mediator;
            _oldPublicDataRepository = oldPublicDataRepository;
        }

        /// <summary>
        /// 查询受理类型
        /// </summary>
        /// <returns></returns>
        [HttpPost("get_accept_type_list")]
        [AllowAnonymous]
        public async Task<List<AcceptTypeList>> GetAcceptTypeList()
        {
            //查询数据
            var data = _sysDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.AcceptType);
            List<AcceptTypeList> acceptTypeList = new List<AcceptTypeList>();
            if (data != null && data.Count > 0)
            {
                foreach (var item in data)
                {
                    acceptTypeList.Add(new AcceptTypeList()
                    {
                        Name = item.DicDataName,
                        Value = item.DicDataValue
                    });
                }
            }
            return acceptTypeList;
        }

        /// <summary>
        /// 根据工单编号和密码查询信件详情
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("get_order_detail_by_no_pwd")]
        public async Task<OrderDto> GetOrderDetail([FromBody] GetOrderNoPwdDto dto)
        {
            var order = await _orderRepository.Queryable()
                  .Where(p => p.No == dto.No && p.Password == dto.Password)
                  .WhereIF(!string.IsNullOrEmpty(dto.SourceChannelCode), p => p.SourceChannelCode == dto.SourceChannelCode)
                  .FirstAsync();

            return _mapper.Map<OrderDto>(order);
        }

        /// <summary>
        /// 根据工单编号查询信件详情
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("get_order_detail_by_no")]
        public async Task<OrderDto> GetOrderDetailByNo([FromBody] GetOrderDetailDto dto)
        {
            var order = await _orderRepository.Queryable()
                 .Where(p => p.No == dto.No)
                 .FirstAsync();
            return _mapper.Map<OrderDto>(order);
        }

        /// <summary>
        /// 根据工单Id查询信件详情
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("get_order_detail_by_id")]
        public async Task<PublishDto> GetOrderDetailById([FromBody] GetOrderDetailDto dto)
        {
            var order = await _orderRepository.Queryable()
                 .Includes(d => d.OrderPublish)
                 .Where(p => p.Id == dto.Id)
                 .FirstAsync();
            return _mapper.Map<PublishDto>(order);
        }

        /// <summary>
        /// 平台查询自己写入的工单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("get_order_list_own")]
        [AllowAnonymous]
        public async Task<PagedDto<OrderDto>> GetOrderByList([FromBody] GetOrderList dto)
        {
            var (total, items) = await _orderRepository.Queryable()
                .Where(p => p.SourceChannelCode == dto.SourceChannelCode)
                .WhereIF(!string.IsNullOrEmpty(dto.No), p => p.No == dto.No)
                .WhereIF(!string.IsNullOrEmpty(dto.Title), p => p.Title.Contains(dto.Title))
                .WhereIF(!string.IsNullOrEmpty(dto.Mobile), p => p.Contact.Contains(dto.Mobile))
                .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), p => p.AcceptTypeCode == dto.AcceptTypeCode)
                .WhereIF(dto.StartTime.HasValue, p => p.CreationTime >= dto.StartTime)
                .WhereIF(dto.EndTime.HasValue, p => p.CreationTime < dto.EndTime)
                .WhereIF(dto.HandleStateCode == "1", p => p.Status < EOrderStatus.Filed)
                .WhereIF(dto.HandleStateCode == "2", p => p.Status >= EOrderStatus.Filed)
                .OrderByDescending(p => p.CreationTime)
                .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

            return new PagedDto<OrderDto>(total, _mapper.Map<IReadOnlyList<OrderDto>>(items));
        }

        /// <summary>
        /// 查询工单发布后公开的数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("get_order_list_publish")]
        [AllowAnonymous]
        public async Task<PagedDto<PublishDto>> GetOrderByListOpen([FromBody] GetOrderList dto)
        {
            var (total, items) = await _orderRepository.Queryable()
               .Where(p => p.IsPublicity == true)
                .WhereIF(!string.IsNullOrEmpty(dto.No), p => p.No == dto.No)
                .WhereIF(!string.IsNullOrEmpty(dto.Title), p => p.Title.Contains(dto.Title))
                .WhereIF(!string.IsNullOrEmpty(dto.Mobile), p => p.Contact.Contains(dto.Mobile))
                .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), p => p.AcceptTypeCode == dto.AcceptTypeCode)
                .WhereIF(dto.StartTime.HasValue, p => p.CreationTime >= dto.StartTime)
                .WhereIF(dto.EndTime.HasValue, p => p.CreationTime < dto.EndTime)
                .WhereIF(!string.IsNullOrEmpty(dto.AreaCode), p => p.AreaCode == dto.AreaCode)
                .OrderByDescending(p => p.CreationTime)
                .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

            return new PagedDto<PublishDto>(total, _mapper.Map<IReadOnlyList<PublishDto>>(items));
        }

        /// <summary>
        /// 查询工单发布后公开的数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("get_order_list_publish_all")]
        [AllowAnonymous]
        public async Task<PagedDto<PublishOrderAllDto>> GetOrderByListAllOpen([FromBody] GetOrderList dto)
        {
            var (total, items) = await _orderRepository.Queryable()
                .Where(p => p.IsPublicity == true)
                .WhereIF(!string.IsNullOrEmpty(dto.No), p => p.No == dto.No)
                .WhereIF(!string.IsNullOrEmpty(dto.Title), p => p.Title.Contains(dto.Title))
                .WhereIF(!string.IsNullOrEmpty(dto.Mobile), p => p.Contact.Contains(dto.Mobile))
                .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), p => p.AcceptTypeCode == dto.AcceptTypeCode)
                .WhereIF(dto.StartTime.HasValue, p => p.CreationTime >= dto.StartTime)
                .WhereIF(dto.EndTime.HasValue, p => p.CreationTime < dto.EndTime)
                .WhereIF(!string.IsNullOrEmpty(dto.AreaCode), p => p.AreaCode == dto.AreaCode)
               .OrderByDescending(p => p.CreationTime)
                .Select(p => new PublishOrderAllDto
                {
                    OrderId = p.Id,
                    FromName = p.FromName,
                    Contact = p.Contact,
                    OrderNo = p.No,
                    Title = p.Title,
                    SourceChannel = p.SourceChannel,
                    SourceChannelCode = p.SourceChannelCode,
                    AcceptType = p.AcceptType,
                    AcceptTypeCode = p.AcceptTypeCode,
                    HotspotName = p.HotspotName,
                    Content = p.Content,
                    State = p.Status >= EOrderStatus.Filed ? "办理完成" : "办理中",
                    ActualOpinion = p.ActualOpinion,
                    AcceptTime = p.CreationTime,
                    PubDate = p.OrderPublish.CreationTime,
                    FiledTime = p.FiledTime
                })
                .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

            //var queryold = _oldPublicDataRepository.Queryable()
            //          .WhereIF(!string.IsNullOrEmpty(dto.No), p => p.OrderNo == dto.No)
            //          .WhereIF(!string.IsNullOrEmpty(dto.Title), p => p.Title.Contains(dto.Title))
            //          .WhereIF(!string.IsNullOrEmpty(dto.Mobile), p => p.Contact.Contains(dto.Mobile))
            //          .WhereIF(!string.IsNullOrEmpty(dto.AcceptTypeCode), p => p.AcceptTypeCode == dto.AcceptTypeCode)
            //          .WhereIF(dto.StartTime.HasValue, p => p.PubDate >= dto.StartTime)
            //          .WhereIF(dto.EndTime.HasValue, p => p.PubDate < dto.EndTime)
            //           .Select(p => new PublishOrderAllDto
            //           {
            //               OrderId = p.OrderId,
            //               FromName = p.FromName,
            //               Contact = p.Contact,
            //               OrderNo = p.OrderNo,
            //               Title = p.Title,
            //               SourceChannel = p.SourceChannel,
            //               SourceChannelCode = p.SourceChannelCode,
            //               AcceptType = p.AcceptType,
            //               AcceptTypeCode = p.AcceptTypeCode,
            //               HotspotName = p.HotspotName,
            //               Content = p.Content,
            //               State = p.State == "1" ? "办理完成" : "办理中",
            //               ActualOpinion = p.ActualOpinion,
            //               AcceptTime = p.CreationTime,
            //               PubDate = p.PubDate,
            //               FiledTime = p.FiledTime
            //           });

            //var (total, items) = await _orderRepository.UnionAll(queryNew, queryold)
            //    .OrderByDescending(p => p.PubDate)
            //     .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

            return new PagedDto<PublishOrderAllDto>(total, items);
        }

        /// <summary>
        /// 根据工单编号和密码查询流程
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("get_workflow_by_no_pwd")]
        [AllowAnonymous]
        public async Task<List<WorkflowTraceDto>> GetWorkflowByNoPwd([FromBody] GetOrderNoPwdDto dto)
        {
            var order = await _orderRepository.Queryable()
                  .Where(p => p.No == dto.No && p.Password == dto.Password)
                  .WhereIF(!string.IsNullOrEmpty(dto.SourceChannelCode), p => p.SourceChannelCode == dto.SourceChannelCode)
                  .FirstAsync();
            List<WorkflowTraceDto> workflow = new();
            if (order == null)
                return workflow;

            var data = await _workflowTraceRepository.Queryable()
                    .Where(p => p.ExternalId == order.Id && p.ModuleCode == "OrderHandle" && p.Status == EWorkflowStepStatus.Handled && p.TraceState == EWorkflowTraceState.Normal)
                   .OrderBy(p => p.CreationTime)
                    .ToListAsync();
            workflow = _mapper.Map<List<WorkflowTraceDto>>(data);
            return workflow;
        }

        /// <summary>
        /// 查询公告列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("query_bulletin_list")]
        [AllowAnonymous]
        public async Task<PagedDto<BulletinDto>> QueryBulletinList([FromBody] GetBulletinListDto dto)
        {
            var (total, items) = await _bulletinRepository.Queryable()
                .Where(p => p.LoseEfficacyTime >= DateTime.Now)
                .Where(p => SqlFunc.JsonListObjectAny(p.PushRanges, "Key", dto.PushRanges))
                .Where(p => p.IsArrive == true && p.BulletinState == EBulletinState.ReviewPass)
                .WhereIF(!string.IsNullOrEmpty(dto.BulletinTypeId), d => d.BulletinTypeId == dto.BulletinTypeId)
                .OrderByDescending(p => p.BulletinTime)
                .ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

            return new PagedDto<BulletinDto>(total, _mapper.Map<IReadOnlyList<BulletinDto>>(items));
        }

        /// <summary>
        /// 公告详情
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("get_bulletin_detail")]
        [AllowAnonymous]
        public async Task<BulletinDto> GetBulletinEntity([FromBody] GetOrderDetailDto dto)
        {
            var model = await _bulletinRepository.Queryable()
                .Includes(x => x.ExaminMan)
                .FirstAsync(x => x.Id == dto.Id && x.IsArrive == true && x.BulletinState == EBulletinState.ReviewPass, HttpContext.RequestAborted);

            if (model != null)
            {
                model.ReadedNum = model.ReadedNum++;
                await _bulletinRepository.UpdateAsync(model, HttpContext.RequestAborted);
            }

            if (model != null && !string.IsNullOrEmpty(model.Content))
                model.Content = _bulletinApplication.GetSiteUrls(model.Content);

            return _mapper.Map<BulletinDto>(model);
        }

        /// <summary>
        /// 今日受理分类统计
        /// </summary>
        /// <returns></returns>
        [HttpPost("get_pur_type_report")]
        [AllowAnonymous]
        public async Task<object> GetPurTypeReport()
        {
            var list = await _orderRepository.Queryable()
                 .Where(p => p.CreationTime >= Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:00:00")))
                .Where(p => p.CreationTime <= Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 23:59:59")))
                .Where(p => p.AcceptTypeCode != null && p.AcceptType != null)
                .Select(it => new
                {
                    it.AcceptType,
                    it.AcceptTypeCode
                })
                .MergeTable()//将查询出来的结果合并成一个新表
                 .GroupBy(it => new { it.AcceptType, it.AcceptTypeCode })//对新表进行分组
                 .Select(it => new
                 {
                     PurTypeName = it.AcceptType,
                     Count = SqlFunc.AggregateCount(it.AcceptTypeCode)
                 })
                 .ToListAsync();
            return list;
        }

        /// <summary>
        /// 今日统计
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("get_day_count")]
        public async Task<object> GetDayCount()
        {
            var startDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:00:00"));
            var endDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 23:59:59"));

            var getStatistDto = await _orderRepository.Queryable()
                 .Select(p => new GetStatistDto
                 {
                     AllCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.Status >= EOrderStatus.WaitForAccept, 1, 0)),
                     AllTrandCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.Status >= EOrderStatus.Filed, 1, 0)),
                     DayCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.CreationTime >= startDate && p.CreationTime <= endDate && p.Status > EOrderStatus.WaitForAccept, 1, 0)),
                     DayTrandCount = SqlFunc.AggregateSum(SqlFunc.IIF(p.ActualHandleTime >= startDate && p.ActualHandleTime <= endDate && p.Status >= EOrderStatus.Filed, 1, 0)),
                 })
                 .FirstAsync();

            ////今日已办结
            //var dayTrandCount = await _orderRepository.Queryable().Where(p => p.CreationTime >= Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:00:00")) &&
            //p.CreationTime <= Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 23:59:59")) && p.Status >= EOrderStatus.Filed).CountAsync();

            ////今日总量
            //var dayCount = await _orderRepository.Queryable().Where(p => p.CreationTime >= Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:00:00")) &&
            //p.CreationTime <= Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 23:59:59"))).CountAsync();

            ////总共已办结
            //var allTrandCount = await _orderRepository.Queryable().Where(p => p.Status >= EOrderStatus.Filed).CountAsync();

            ////总共总量
            //var allCount = await _orderRepository.Queryable().Where(p => p.Status >= EOrderStatus.WaitForAccept).CountAsync();

            return getStatistDto;

        }

        /// <summary>
        /// 查询热点分类
        /// </summary>
        /// <returns></returns>
        [HttpPost("get_hotspot_statistics_list")]
        [AllowAnonymous]
        public async Task<object> GetHotspotStatistics()
        {
            var list = await _hotspotTypeRepository.Queryable()
                .LeftJoin<Order>((it, o) => it.Id == o.HotspotId)
                .Where((it, o) => o.CreationTime >= Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:00:00")))
                .Where((it, o) => o.CreationTime <= Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 23:59:59")))
                .Where((it, o) => o.Id != null && o.HotspotId != null)
                .GroupBy((it, o) => new { Id = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("2")) })
                .Select((it, o) => new
                {
                    HotspotCode = it.Id.Substring(SqlFunc.MappingColumn<int>("0"), SqlFunc.MappingColumn<int>("2")),
                    SumCount = SqlFunc.AggregateCount(it.HotSpotName)
                })
                .MergeTable()
                .LeftJoin<Hotspot>((x, q) => x.HotspotCode == q.Id)
                .Select((x, q) => new
                {
                    Name = q.HotSpotName,
                    Value = x.SumCount
                })
                .ToListAsync();

            return list;
        }

        /// <summary>
        ///  随手拍网格员-短信接口
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("grid_operator_send_sms")]
        [AllowAnonymous]
        public async Task<string> GridOperatorSendSms([FromBody] GridOperatorSendSmsDto dto)
        {
            if (dto == null)
                return "数据获取失败";
            var order = await _orderRepository.GetAsync(p => p.No == dto.ReplyCode, HttpContext.RequestAborted);
            if (order == null)
                return "工单查询失败";

            var messageDto = new Share.Dtos.Push.MessageDto
            {
                PushBusiness = EPushBusiness.OrderSend,
                ExternalId = order.Id,
                OrderId = order.Id,
                PushPlatform = EPushPlatform.Sms,
                Remark = order.Title,
                Name = dto.MemberName,
                TemplateCode = "1010",
                Params = new List<string>() { dto.AppealNumber },
                TelNumber = dto.MemberMobile,

            };
            if (dto.SendType == "2")
            {
                messageDto.TemplateCode = "1011";
                messageDto.PushBusiness = EPushBusiness.OrderExpire;
            }

            await _mediator.Publish(new PushMessageNotify(messageDto), HttpContext.RequestAborted);
            return "提交成功";
        }
    }
}
