package com.slodon.b2b2c.controller.integral.seller;

import com.slodon.b2b2c.aop.VendorLogger;
import com.slodon.b2b2c.core.config.DomainUrlUtil;
import com.slodon.b2b2c.core.constant.GoodsConst;
import com.slodon.b2b2c.core.constant.MemberTplConst;
import com.slodon.b2b2c.core.constant.OrderConst;
import com.slodon.b2b2c.core.controller.BaseController;
import com.slodon.b2b2c.core.express.TracesResult;
import com.slodon.b2b2c.core.express.TrackUtil;
import com.slodon.b2b2c.core.response.JsonResult;
import com.slodon.b2b2c.core.response.PageVO;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.*;
import com.slodon.b2b2c.integral.example.*;
import com.slodon.b2b2c.integral.pojo.*;
import com.slodon.b2b2c.model.integral.*;
import com.slodon.b2b2c.model.seller.StoreExpressSettingModel;
import com.slodon.b2b2c.model.system.ExpressModel;
import com.slodon.b2b2c.seller.example.StoreExpressSettingExample;
import com.slodon.b2b2c.seller.pojo.StoreExpressSetting;
import com.slodon.b2b2c.seller.pojo.Vendor;
import com.slodon.b2b2c.starter.mq.entity.MessageSendProperty;
import com.slodon.b2b2c.starter.mq.entity.MessageSendVO;
import com.slodon.b2b2c.system.pojo.Express;
import com.slodon.b2b2c.vo.integral.IntegralOrderDetailVO;
import com.slodon.b2b2c.vo.integral.IntegralOrderProductVO;
import com.slodon.b2b2c.vo.integral.IntegralOrderVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.slodon.b2b2c.core.constant.StarterConfigConst.MQ_EXCHANGE_NAME;
import static com.slodon.b2b2c.core.constant.StarterConfigConst.MQ_QUEUE_NAME_MEMBER_MSG;

@Api(tags = "seller-订单管理")
@RestController
@RequestMapping("v3/integral/seller/integral/order")
public class SellerIntegralOrderController extends BaseController {

    @Resource
    private IntegralOrderModel integralOrderModel;
    @Resource
    private IntegralOrderProductModel integralOrderProductModel;
    @Resource
    private IntegralOrderLogModel integralOrderLogModel;
    @Resource
    private IntegralOrderPayModel integralOrderPayModel;
    @Resource
    private IntegralOrderReserveModel integralOrderReserveModel;
    @Resource
    private StoreExpressSettingModel storeExpressSettingModel;
    @Resource
    private ExpressModel expressModel;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RabbitTemplate rabbitTemplate;

    @ApiOperation("订单列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderSn", value = "订单号", paramType = "query"),
            @ApiImplicitParam(name = "memberName", value = "会员名称", paramType = "query"),
            @ApiImplicitParam(name = "startTime", value = "下单开始时间", paramType = "query"),
            @ApiImplicitParam(name = "endTime", value = "下单结束时间", paramType = "query"),
            @ApiImplicitParam(name = "orderState", value = "订单状态：0-已取消；10-待付款订单；20-代发货订单；30-待收货订单；40-已完成;50-已关闭", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("list")
    public JsonResult<PageVO<IntegralOrderVO>> list(HttpServletRequest request, String orderSn, String memberName,
                                                    Date startTime, Date endTime, Integer orderState) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        IntegralOrderExample example = new IntegralOrderExample();
        example.setStoreId(vendor.getStoreId());
        example.setOrderSnLike(orderSn);
        example.setMemberNameLike(memberName);
        example.setCreateTimeAfter(startTime);
        example.setCreateTimeBefore(endTime);
        example.setOrderState(orderState);
        example.setDeleteState(OrderConst.DELETE_STATE_0);
        List<IntegralOrder> list = integralOrderModel.getIntegralOrderList(example, pager);
        List<IntegralOrderVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (IntegralOrder integralOrder : list) {
                IntegralOrderVO vo = new IntegralOrderVO(integralOrder);
                //获取订单货品列表信息
                IntegralOrderProductExample orderProductExample = new IntegralOrderProductExample();
                orderProductExample.setOrderSn(integralOrder.getOrderSn());
                List<IntegralOrderProduct> orderProductList = integralOrderProductModel.getIntegralOrderProductList(orderProductExample, null);
                AssertUtil.notEmpty(orderProductList, "订单货品不存在");
                List<IntegralOrderProductVO> productListVOS = new ArrayList<>();
                orderProductList.forEach(orderProduct -> {
                    productListVOS.add(new IntegralOrderProductVO(orderProduct));
                });
                vo.setOrderProductList(productListVOS);
                vos.add(vo);
            }
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("订单详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderSn", value = "订单号", required = true)
    })
    @PostMapping("detail")
    public JsonResult<IntegralOrderDetailVO> detail(HttpServletRequest request, String orderSn) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        IntegralOrder order = integralOrderModel.getOrdersWithOpByOrderSn(orderSn);
        AssertUtil.notNull(order, "无此订单");
        AssertUtil.isTrue(!vendor.getStoreId().equals(order.getStoreId()), "您无权操作此订单");

        //获取订单支付信息
        IntegralOrderPayExample orderPayExample = new IntegralOrderPayExample();
        orderPayExample.setPaySn(order.getPaySn());
        IntegralOrderPay orderPay = integralOrderPayModel.getIntegralOrderPayList(orderPayExample, null).get(0);

        IntegralOrderDetailVO detailVO = new IntegralOrderDetailVO(order, orderPay);
        List<IntegralOrderProductVO> productVOS = new ArrayList<>();
        //获取货品信息
        order.getOrderProductList().forEach(orderProduct -> {
            productVOS.add(new IntegralOrderProductVO(orderProduct));
        });
        detailVO.setOrderProductList(productVOS);
        //获取订单日志信息
        IntegralOrderLogExample orderLogExample = new IntegralOrderLogExample();
        orderLogExample.setOrderSn(order.getOrderSn());
        orderLogExample.setOrderBy("log_time asc");
        List<IntegralOrderLog> orderLogList = integralOrderLogModel.getIntegralOrderLogList(orderLogExample, null);
        detailVO.setOrderLogList(orderLogList);
        //虚拟商品查询预留信息
        if (order.getIsVirtualGoods() == GoodsConst.IS_VIRTUAL_GOODS_2) {
            IntegralOrderReserveExample example = new IntegralOrderReserveExample();
            example.setOrderSn(orderSn);
            example.setOrderBy("reserve_id asc");
            List<IntegralOrderReserve> orderReserveList = integralOrderReserveModel.getIntegralOrderReserveList(example, null);
            detailVO.setOrderReserveList(orderReserveList);
        }
        return SldResponse.success(detailVO);
    }

    @ApiOperation("发货")
    @VendorLogger(option = "发货")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderSn", value = "订单号", required = true, paramType = "query"),
            @ApiImplicitParam(name = "deliverType", value = "发货类型：0-物流发货，1-无需物流", paramType = "query"),
            @ApiImplicitParam(name = "expressId", value = "快递公司id(物流发货时必填)", paramType = "query"),
            @ApiImplicitParam(name = "expressNumber", value = "快递单号(物流发货时必填)", paramType = "query"),
            @ApiImplicitParam(name = "deliverName", value = "联系人(无需物流时必填)", paramType = "query"),
            @ApiImplicitParam(name = "deliverMobile", value = "联系电话(无需物流时必填)", paramType = "query")
    })
    @PostMapping("deliver")
    public JsonResult deliver(HttpServletRequest request, String orderSn, Integer deliverType, Integer expressId,
                              String expressNumber, String deliverName, String deliverMobile) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        //查询订单信息
        IntegralOrder orderDb = integralOrderModel.getIntegralOrderByOrderSn(orderSn);
        AssertUtil.isTrue(!orderDb.getStoreId().equals(vendor.getStoreId()), "您无权处理此订单");
        AssertUtil.isTrue(orderDb.getOrderState() != OrderConst.ORDER_STATE_20, "非待发货订单，无法发货");

        //虚拟商品发货直接修改订单状态
        if (orderDb.getIsVirtualGoods() == GoodsConst.IS_VIRTUAL_GOODS_2) {
            IntegralOrder order = new IntegralOrder();
            order.setOrderId(orderDb.getOrderId());
            order.setOrderState(OrderConst.ORDER_STATE_30);
            order.setDeliverTime(new Date());
            integralOrderModel.updateIntegralOrder(order);

            //保存订单日志
            integralOrderLogModel.insertOrderLog(OrderConst.LOG_ROLE_VENDOR, vendor.getVendorId(), vendor.getVendorName(),
                    orderSn, OrderConst.ORDER_STATE_30, "商品发货");
        } else {
            String expressName, expressNo;
            IntegralOrder order = new IntegralOrder();
            order.setOrderId(orderDb.getOrderId());
            order.setDeliverType(deliverType);
            if (deliverType == OrderConst.DELIVER_TYPE_0) {
                AssertUtil.notNullOrZero(expressId, "快递公司id不能为空");
                AssertUtil.notEmpty(expressNumber, "快递单号不能为空");

                Express express = expressModel.getExpressByExpressId(expressId);
                AssertUtil.notNull(express, "获取快递公司信息为空，请重试");
                order.setExpressId(expressId);
                order.setExpressCode(express.getExpressCode());
                order.setExpressName(express.getExpressName());
                order.setExpressNumber(expressNumber);
                expressName = express.getExpressName();
                expressNo = expressNumber;
            } else {
                AssertUtil.notEmpty(deliverName, "联系人不能为空");
                AssertUtil.notEmpty(deliverMobile, "联系电话不能为空");
                order.setDeliverName(deliverName);
                order.setDeliverMobile(deliverMobile);
                expressName = "商家自行配送";
                expressNo = "-";
            }
            order.setDeliverTime(new Date());
            order.setOrderState(OrderConst.ORDER_STATE_30);
            integralOrderModel.updateIntegralOrder(order);

            //保存订单日志
            integralOrderLogModel.insertOrderLog(OrderConst.LOG_ROLE_VENDOR, vendor.getVendorId(), vendor.getVendorName(),
                    orderSn, OrderConst.ORDER_STATE_30, "商品发货");

            //会员消息通知
            //微信通知
            List<MessageSendProperty> messageSendPropertyList = new ArrayList<>();
            messageSendPropertyList.add(new MessageSendProperty("first", "您的订单已发货"));
            messageSendPropertyList.add(new MessageSendProperty("keyword1", orderSn));
            messageSendPropertyList.add(new MessageSendProperty("keyword2", expressName));
            messageSendPropertyList.add(new MessageSendProperty("keyword3", expressNo));
            messageSendPropertyList.add(new MessageSendProperty("remark", "点击查看订单详情。"));
            messageSendPropertyList.add(new MessageSendProperty("url", DomainUrlUtil.SLD_H5_URL + "/standard/point/order/detail?orderSn=" + orderSn));
            String msgLinkInfo = "{\"type\":\"order_news\",\"orderType\":\"integral_order\",\"orderSn\":\"" + orderDb.getOrderSn() + "\"}";
            String[] templateParam = {orderSn, TimeUtil.getDateTimeString(new Date())};
            MessageSendVO messageSendVO = new MessageSendVO(messageSendPropertyList, orderDb.getMemberId(),
                    MemberTplConst.GOODS_DELIVERY_REMINDER, msgLinkInfo, templateParam);
            //发送到mq
            rabbitTemplate.convertAndSend(MQ_EXCHANGE_NAME, MQ_QUEUE_NAME_MEMBER_MSG, messageSendVO);
        }
        return SldResponse.success("订单发货成功");
    }

    @ApiOperation("批量发货")
    @VendorLogger(option = "批量发货")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderSns", value = "订单号字符串,以逗号隔开", required = true)
    })
    @PostMapping("batchDeliver")
    public JsonResult batchDeliver(HttpServletRequest request, @RequestParam("orderSns") String orderSns) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        StringBuilder orderSnList = new StringBuilder();
        String[] orderSnArr = orderSns.split(",");
        for (String orderSn : orderSnArr) {
            //查询订单信息
            IntegralOrder orderDb = integralOrderModel.getIntegralOrderByOrderSn(orderSn);
            AssertUtil.isTrue(!orderDb.getStoreId().equals(vendor.getStoreId()), "您无权处理此订单");
            AssertUtil.isTrue(orderDb.getOrderState() != OrderConst.ORDER_STATE_20, "非待发货订单，无法发货");

            if (orderDb.getIsGenerateFacesheet() != OrderConst.IS_GENERATE_FACE__SHEET_1) {
                orderSnList.append(",").append(orderSn);
            } else {
                //修改电子面单订单状态
                IntegralOrder order = new IntegralOrder();
                order.setOrderId(orderDb.getOrderId());
                order.setOrderSn(orderSn);
                order.setOrderState(OrderConst.ORDER_STATE_30);
                order.setDeliverTime(new Date());
                integralOrderModel.updateIntegralOrder(order);

                //保存订单日志
                integralOrderLogModel.insertOrderLog(OrderConst.LOG_ROLE_VENDOR, vendor.getVendorId(), vendor.getVendorName(),
                        orderSn, OrderConst.ORDER_STATE_30, "商品发货");

                //会员消息通知
                //微信通知
                List<MessageSendProperty> messageSendPropertyList = new ArrayList<>();
                messageSendPropertyList.add(new MessageSendProperty("first", "您的订单已发货"));
                messageSendPropertyList.add(new MessageSendProperty("keyword1", orderSn));
                messageSendPropertyList.add(new MessageSendProperty("keyword2", orderDb.getExpressName()));
                messageSendPropertyList.add(new MessageSendProperty("keyword3", orderDb.getExpressNumber()));
                messageSendPropertyList.add(new MessageSendProperty("remark", "点击查看订单详情。"));
                messageSendPropertyList.add(new MessageSendProperty("url", DomainUrlUtil.SLD_H5_URL + "/standard/point/order/detail?orderSn=" + orderSn));
                String msgLinkInfo = "{\"type\":\"order_news\",\"orderType\":\"integral_order\",\"orderSn\":\"" + orderDb.getOrderSn() + "\"}";
                String[] templateParam = {orderSn, TimeUtil.getDateTimeString(new Date())};
                MessageSendVO messageSendVO = new MessageSendVO(messageSendPropertyList, orderDb.getMemberId(),
                        MemberTplConst.GOODS_DELIVERY_REMINDER, msgLinkInfo, templateParam);
                //发送到mq
                rabbitTemplate.convertAndSend(MQ_EXCHANGE_NAME, MQ_QUEUE_NAME_MEMBER_MSG, messageSendVO);
            }
        }
        return SldResponse.success("订单发货成功");
    }

    @ApiOperation("查看物流")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderSn", value = "订单号", required = true, paramType = "query")
    })
    @GetMapping("getTrace")
    public JsonResult<TracesResult> getTrace(HttpServletRequest request, String orderSn) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        //查询订单信息
        IntegralOrder order = integralOrderModel.getIntegralOrderByOrderSn(orderSn);
        AssertUtil.isTrue(!vendor.getStoreId().equals(order.getStoreId()), "您无权查看此订单物流");
        AssertUtil.isTrue(order.getIsVirtualGoods() == GoodsConst.IS_VIRTUAL_GOODS_2, "该订单为虚拟商品订单，没有物流信息");

        if (order.getOrderState() > OrderConst.ORDER_STATE_20 && StringUtil.isEmpty(order.getExpressCode())) {
            TracesResult tracesResult = new TracesResult();
            tracesResult.setExpressName(order.getDeliverName());
            tracesResult.setExpressNumber(order.getDeliverMobile());
            tracesResult.setType("1");
            return SldResponse.success(tracesResult);
        } else {
            AssertUtil.isTrue(StringUtil.isEmpty(order.getExpressCode()), "快递公司编号信息为空");

            TracesResult tracesResult;
            String expressType = stringRedisTemplate.opsForValue().get("express_type");
            if ("1".equals(expressType)) {
                //快递鸟
                tracesResult = this.getExpressTrack1(order.getOrderSn(), order.getExpressCode(), order.getExpressName(),
                        order.getExpressNumber(), order.getStoreId(), order.getReceiverMobile().substring(7, 11));
            } else {
                //快递100
                tracesResult = this.getExpressTrack2(order.getReceiverMobile(), order.getExpressCode(), order.getExpressName(),
                        order.getExpressNumber());
            }
            return SldResponse.success(tracesResult);
        }
    }

    /**
     * 获取快递鸟物流轨迹
     *
     * @param orderSn        订单号
     * @param expressCode    快递编码
     * @param expressName    快递公司
     * @param expressNumber  快递单号
     * @param storeId        店铺id
     * @param receiverMobile 收货人手机号
     * @return 物流信息轨迹
     */
    public TracesResult getExpressTrack1(String orderSn, String expressCode, String expressName, String expressNumber, Long storeId, String receiverMobile) {
        //快递鸟电商ID
        String eBusinessId;
        //快递鸟电商加密私钥
        String appKey;
        String accountSetting = stringRedisTemplate.opsForValue().get("express_account_setting");
        if (StringUtil.isEmpty(accountSetting) || "1".equals(accountSetting)) {
            eBusinessId = stringRedisTemplate.opsForValue().get("express_ebusinessid");
            AssertUtil.notNull(eBusinessId, "请完善快递鸟配置信息：");
            appKey = stringRedisTemplate.opsForValue().get("express_apikey");
            AssertUtil.notNull(appKey, "请完善快递鸟配置信息：");
        } else {
            StoreExpressSettingExample example = new StoreExpressSettingExample();
            example.setStoreId(storeId);
            List<StoreExpressSetting> list = storeExpressSettingModel.getStoreExpressSettingList(example, null);
            AssertUtil.notEmpty(list, "请完善快递鸟配置信息：");

            eBusinessId = list.get(0).getBusinessId();
            AssertUtil.notNull(eBusinessId, "请完善快递鸟配置信息：");
            appKey = list.get(0).getAppKey();
            AssertUtil.notNull(appKey, "请完善快递鸟配置信息：");
        }
        return TrackUtil.getKdniaoTrack(orderSn, expressCode, expressName, expressNumber, eBusinessId, appKey, receiverMobile);
    }

    /**
     * 获取快递100物流轨迹
     *
     * @param phone         手机号
     * @param expressCode   快递编码
     * @param expressName   快递公司
     * @param expressNumber 快递单号
     * @return 物流信息轨迹
     */
    public TracesResult getExpressTrack2(String phone, String expressCode, String expressName, String expressNumber) {
        String key = stringRedisTemplate.opsForValue().get("express_100_key");
        AssertUtil.notNull(key, "请设置快递100 授权key");
        String customer = stringRedisTemplate.opsForValue().get("express_100_customer");
        AssertUtil.notNull(customer, "请设置快递100 授权码");
        return TrackUtil.getKd100Track(phone, expressCode, expressName, expressNumber, key, customer);
    }
}
