using JiaZhiQuan.Common.Messaging;
using JiaZhiQuan.Common.Messaging.Models;
using JiaZhiQuan.Common.Models;
using JiaZhiQuan.Common.Models.PO;
using JiaZhiQuan.Common.Models.VO.UE;
using JiaZhiQuan.Common.Utils.Extend;
using Newtonsoft.Json;
using NPOI.Util;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using Wicture.DbRESTFul.Infrastructure.Repository;
using static JiaZhiQuan.Common.Models.MallGoodsModel.RefundModel;

namespace JiaZhiQuan.Common {
    public partial class RepositoryExtension {

        private static async Task MakeOrderNotification(DbRESTFulRepository repository, Producer producer, string orderId, int orderType, int newState)
        {
            if (orderType == 2 || orderType == 3)
            {
                var orderInfo = await repository.QuerySingleOrDefaultAsync<dynamic>(
                    $"select orderId, buyerId, sellerId, `source`, closeReason, earnestMoneyRefunded, receiveAt, receiveExpireAt from ue_order_hang where orderId={orderId}");
                if (orderInfo != null)
                {
                    if (orderInfo.source == 2)
                    {
                        if (newState == -1)
                        {
                            if (orderInfo.earnestMoneyRefunded == 0 || orderInfo.earnestMoneyRefunded == 3)
                                await repository.MakeHangSaleOrderPlatformClosedMessage(producer,
                                    (long)orderInfo.buyerId, (long)orderInfo.sellerId, (long)orderInfo.orderId,
                                    (string)orderInfo.closeReason);
                            else
                                await repository.MakeHangSaleOrderPlatformClosedMessage(producer,
                                    (long)orderInfo.buyerId, (long)orderInfo.sellerId, (long)orderInfo.orderId, true,
                                    (string)orderInfo.closeReason);
                        }
                        else if (newState == -2)
                        {
                            await repository.MakeHangSaleOrderPayExpireCloseMessage(producer, (long)orderInfo.buyerId,
                                (long)orderInfo.orderId);
                        }
                        else if (newState == -3)
                        {
                            
                        }
                        else if (newState == -4)
                        {
                            await repository.MakeHangSaleOrderRefusePickUpClosedMessage(producer,
                                (long)orderInfo.buyerId, (long)orderInfo.sellerId, (long)orderInfo.orderId);
                        }
                        else if (newState == -5)
                        {
                            await repository.MakeHangSaleOrderExpirePickUpClosedMessage(producer,
                                (long)orderInfo.buyerId, (long)orderInfo.sellerId, (long)orderInfo.orderId);
                        }
                        else if (newState == 2)
                        {
                            await repository.MakeHangSaleOrderWaitDeliveryMessage(producer, (long)orderInfo.buyerId,
                                (long)orderInfo.sellerId, (long)orderInfo.orderId);
                        }
                        else if (newState == 3)
                        {
                            await repository.MakeHangSaleOrderWaitReceiveMessage(producer, (long)orderInfo.buyerId,
                                (long)orderInfo.orderId);
                        }
                        else if (newState == 4)
                        {
                            await repository.MakeHangSaleOrderWaitPickUpMessage(producer, (long)orderInfo.buyerId,
                                (long)orderInfo.sellerId, (long)orderInfo.orderId);
                        }
                        else if (newState == 5)
                        {
                            await repository.MakeHangSaleOrderBuyerSignForMessage(producer, (long)orderInfo.buyerId,
                                (long)orderInfo.sellerId, (long)orderInfo.orderId, (DateTime?)orderInfo.receiveAt >= (DateTime?)orderInfo.receiveExpireAt);
                        }
                        else if (newState == 6)
                        {
                            await repository.MakeHangSaleOrderPickUpMessage(producer, (long)orderInfo.buyerId,
                                (long)orderInfo.sellerId, (long)orderInfo.orderId);
                        }
                    }
                }
            }
        }
        
        /// <summary>
        /// orderType 订单类型。1：寄售订单，2：销售订单-寄售 3，销售订单-挂售
        /// operateType 操作人类型：0 平台 1 买家 2 卖家 3 运营人员
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="orderId">订单id</param>
        /// <param name="newState">新状态</param>
        /// <param name="orderType"></param>
        /// <param name="conn"></param>
        /// <param name="trans"></param>
        /// <returns></returns>
        public static async Task<InsertResult> RecordOrderLog(this DbRESTFulRepository repository, Producer producer, string orderId,
            int newState,int orderType,string eventDesc,string operatorId, int operatorType,
            IDbConnection conn = null, IDbTransaction trans = null) {
            var now=DateTime.Now;
            var eventName = orderType switch {
                1 => BuildPostOrderEventName(newState),
                2 => BuildSaleOrderEventName(newState),
                3 => BuildSaleOrderEventNameForPub(newState),
                _ => throw new Exception("不支持的订单类型")
            };
            await MakeOrderNotification(repository, producer, orderId, orderType, newState);
            var eventInfo = new {
                orderId,
                eventName,
                eventDesc,
                operatorId,
                operatorType,
                createAt=now,
            };
            return await repository.SimpleInsert("mall_order_change_events", eventInfo, conn, trans);
        }

        public static async Task<InsertResult> RecordOrderLogs(this DbRESTFulRepository repository, Producer producer, 
            List<string> orderIds,
            int newState, int orderType, string eventDesc, string operatorId, int operatorType,
            IDbConnection conn = null, IDbTransaction trans = null) {
            var now = DateTime.Now;
            var eventName = orderType switch {
                1 => BuildPostOrderEventName(newState),
                2 => BuildSaleOrderEventName(newState),
                3 => BuildSaleOrderEventNameForPub(newState),
                _ => throw new Exception("不支持的订单类型")
            };
            var events = orderIds.Select(orderId => new {
                orderId,
                eventName,
                eventDesc,
                operatorId,
                operatorType,
                createAt = now,
            });
            var inSql = events.BuildBatchInsertsql("mall_order_change_events", "orderId,eventName");
            var cnt = await repository.QuerySingleOrDefaultAsync<int>(inSql, null, conn, trans);
            foreach (var orderId in orderIds)
            {
                await MakeOrderNotification(repository, producer, orderId, orderType, newState);
            }
            return new InsertResult { count = cnt };
        }
        //添加模拟浏览任务。
        public static async Task AddGoodsMockViewTask(this DbRESTFulRepository repository, 
            List<long> goodsIds, IDbConnection conn = null, IDbTransaction trans = null) {
            var rand = new Random();
            if(null==goodsIds|| goodsIds.Count() == 0) { return; }
            var now = DateTime.Now;
            var mockTasks = goodsIds.Select(g => {
                var addCount = rand.Next(CommonConst.MinViewCnt, CommonConst.MaxViewCnt);
                var hours = rand.Next(CommonConst.MinViewHours, CommonConst.MaxViewHours);
                if (hours <= 0 || addCount <= 0) throw new Exception("模拟浏览数计算不正常");
                return new {
                    targetId = g,
                    //需添加数
                    addCount,
                    //需耗时
                    hours,
                    type = "GOODS_VIEW",
                    state = 0,
                    createAt = now,
                    lastExecTime=now,
                    remindCount = addCount,
                };
            });
            var inSql = mockTasks.BuildBatchInsertsql("ue_mock_task", "targetId,addCount,createAt");
            await repository.QuerySingleOrDefaultAsync<int>(inSql, null, conn, trans);
        }

        //发送计算商品推荐分的消息
        public static async Task SendCalRecommendScoreMsg(this DbRESTFulRepository repository,
            Producer producer, RecommendScoreModel model) {
            await producer.ProduceAsync(StatisticActionModel.GetMsgKey(), new StatisticActionModel {
                Type = StatisticActionType.GOODS_RECOMMEND_SCORE,
                Content = JsonConvert.SerializeObject(model)
            });
        }

        //寄售订单
        private static string BuildPostOrderEventName(int orderState) {
            return orderState switch {
                -1 => "后台关闭订单",
                -2 => "卖家已签收退货，系统关闭订单",
                -3 => "平台鉴定未通过，不退货，系统关闭订单",
                1 => "卖家已发货，等待平台收货",
                2 => "平台已收货，等待鉴定",
                3 => "平台鉴定通过，等待卖家上架",
                4 => "平台鉴定未通过，等待平台退货",
                5 => "卖家取回商品 (无偿) ，等待平台退货",
                6 => "商品已上架",
                7 => "卖家拒绝上架，等待平台退货",
                8 => "卖家超时未上架，等待平台退货",
                9 => "买家已付款，等待交易完成",
                10 => "卖家取回商品 (有偿) ，等待平台退货",
                11 => "寄售成功",
                12 => "销售订单关闭，重新上架中",
                13 => "平台已退货，等待卖家签收",
                _ => throw new Exception("不支持的订单状态")
            };
        }
        //销售订单-寄售
        private static string BuildSaleOrderEventName(int orderState) {
            return orderState switch {
                -1 => "后台关闭订单",
                -2 => "买家超时未支付，系统关闭订单",
                -3=> "买家关闭订单",
                1 => "等待买家付款",
                2 => "买家已付款，等待平台发货",
                3 => "平台已发货，等待买家签收",
                4 => "待提待",
                5 => "买家已签收，交易成功",
                _ => throw new Exception("不支持的订单状态")
            };
        }
        //销售订单-挂售
        private static string BuildSaleOrderEventNameForPub(int orderState) {
            return orderState switch {
                -1 => "后台关闭订单",
                -2 => "买家超时未支付，系统关闭订单；",
                -3 => "买家关闭订单；",
                -4 => "买家拒绝取货，扣除保证金，交易关闭；",
                -5=> "买家超时未取货，扣除保证金，交易关闭；",
                1 => "等待买家付款",
                2 => "买家已付款，选择快递收货，等待卖家发货；",
                3 => "卖家已发货，等待买家签收；",
                4 => "买家已付款，选择线下收货，等待买家取货；",
                5 => "买家已签收，交易成功；",
                6=> "买家已取货，交易成功；",
                _ => throw new Exception("不支持的订单状态")
            };
        }
    }
}
