using DotNetCore.CAP;
using Hotline.Orders;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Enums.Order;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using StackExchange.Redis;
using System.Reflection;
using XF.Domain.Authentications;
using XF.Domain.Exceptions;
using XF.Domain.Repository;

namespace Hotline.Api.Controllers
{
    public class OrderProvinceZmhdController : BaseController
    {
        private readonly ILogger<OrderProvinceZmhdController> _logger;
        private readonly ISessionContext _sessionContext;
        private readonly IMapper _mapper;
        private readonly ICapPublisher _capPublisher;
        private readonly IOrderRepository _orderRepository;
        private readonly IRepository<OrderProvinceZmhd> _orderProvinceZmhdRepository;

        public OrderProvinceZmhdController(ILogger<OrderProvinceZmhdController> logger,
            ISessionContext sessionContext,
            IMapper mapper,
            ICapPublisher capPublisher,
            IOrderRepository orderRepository,
            IRepository<OrderProvinceZmhd> orderProvinceZmhdRepository)
        {
            _logger = logger;
            _sessionContext = sessionContext;
            _mapper = mapper;
            _capPublisher = capPublisher;
            _orderRepository = orderRepository;
            _orderProvinceZmhdRepository = orderProvinceZmhdRepository;
        }

        /// <summary>
        /// 查询列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("getorderlist")]
        public async Task<PagedDto<OrderDto>> GetOrderList([FromQuery] OrderProvinceZmhdDto dto)
        {
            RefAsync<int> total = 0;
            var items = await _orderRepository.Queryable()
                .Where(p => p.SourceChannelCode == "SZMHD"  && p.Status >= EOrderStatus.Filed && p.Source == ESource.ProvinceStraight)
                .WhereIF(!string.IsNullOrEmpty(dto.No), p => p.No == dto.No)
                .WhereIF(!string.IsNullOrEmpty(dto.ProvinceNo), p => p.ProvinceNo == dto.ProvinceNo)
                 .WhereIF(!string.IsNullOrEmpty(dto.ReceiveProvinceNo), p => p.ReceiveProvinceNo == dto.ReceiveProvinceNo)
                .WhereIF(!string.IsNullOrEmpty(dto.Title), p => p.Title.StartsWith(dto.Title!))
                .WhereIF(!string.IsNullOrEmpty(dto.AnswerOu), p => p.ActualHandleOrgName == dto.AnswerOu)
                .WhereIF(!string.IsNullOrEmpty(dto.AuditFirstName), p => p.AuditFirstName == dto.AuditFirstName)
                .WhereIF(dto.IsProvinceZmhd.HasValue, p => p.IsProvinceZmhd == dto.IsProvinceZmhd)
                .WhereIF(dto.StartTime.HasValue, d => d.AuditFirstTime >= dto.StartTime) //初审时间开始
                .WhereIF(dto.EndTime.HasValue, d => d.AuditFirstTime <= dto.EndTime) //初审时间结束
                .OrderByDescending(d => d.CreationTime)
                .ToPageListAsync(dto.PageIndex, dto.PageSize, total, HttpContext.RequestAborted);

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

        /// <summary>
        /// 查询政民互动发布详情
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpGet("getorderprovincezmhdinfo")]
        public async Task<PublicOrderProvinceZmhdDto> GetOrderProvinceZmhdInfo(string Id)
        {
            var info = await _orderProvinceZmhdRepository.GetAsync(p => p.Id == Id, HttpContext.RequestAborted);
            if (info == null)
                throw UserFriendlyException.SameMessage("查询失败");

            return _mapper.Map<PublicOrderProvinceZmhdDto>(info);
        }

        /// <summary>
        /// 政民互动发布
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task AddOrderProvinceZmhd([FromBody] AddOrderProvinceZmhdDto dto)
        {
            if (string.IsNullOrEmpty(dto.AnswerContent))
                throw UserFriendlyException.SameMessage("整理结果不能为空！");

            if (string.IsNullOrEmpty(dto.PublicOpinion))
                throw UserFriendlyException.SameMessage("公开意见不能为空！");

            if (dto.PublicOpinion.Length > 300)
                throw UserFriendlyException.SameMessage("公开意见不能超过300字符！");

            var order = await _orderRepository.GetAsync(p => p.Id == dto.OrderId, HttpContext.RequestAborted);
            if (order == null)
                throw UserFriendlyException.SameMessage("工单查询失败！");

            OrderProvinceZmhd orderProvinceZmhd = new()
            {
                No = order.No,
                ProvinceNo = order.ReceiveProvinceNo,
                OrderId = order.Id,
                Title = order.Title,
                AnswerTime = order.ActualHandleTime,
                AnswerOu = order.ActualHandleOrgName,
                AnswerContent = dto.AnswerContent,
                AuditFirstName = _sessionContext.UserName,
                AuditFirstTime = DateTime.Now,
                AuditSecondName = _sessionContext.UserName,
                PublishDate = DateTime.Now,
                PublicOpinion = dto.PublicOpinion
            };
            //查询是否已经发布过
            var info = await _orderProvinceZmhdRepository.GetAsync(p => p.OrderId == order.Id, HttpContext.RequestAborted);
            if (info != null)
                throw UserFriendlyException.SameMessage("此工单已公开！");

            //发布
            var id = await _orderProvinceZmhdRepository.AddAsync(orderProvinceZmhd, HttpContext.RequestAborted);
            if (string.IsNullOrEmpty(id))
                throw UserFriendlyException.SameMessage("公开失败！");

            //修改工单发布数据
            order.IsProvinceZmhd = true;
            order.AuditFirstName = _sessionContext.UserName;
            order.AuditFirstTime = orderProvinceZmhd.AuditFirstTime;
            order.OrderProvinceZmhdId = orderProvinceZmhd.Id;
            await _orderRepository.UpdateAsync(order, HttpContext.RequestAborted);

            //推送数据
            var publishPublishOrder = _mapper.Map<PublicOrderProvinceZmhdDto>(orderProvinceZmhd);
            publishPublishOrder.ProvinceNo = order.ReceiveProvinceNo;
            await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderProvinceZmhd, publishPublishOrder);
        }

    }
}
