package com.hai.openApi.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.common.utils.DateUtil;
import com.hai.dao.ApiOrderMapper;
import com.hai.entity.ApiMerchants;
import com.hai.entity.ApiOrder;
import com.hai.entity.ApiOrderExample;
import com.hai.entity.HighOrder;
import com.hai.enum_type.OrderStatusEnum;
import com.hai.openApi.service.ApiOrderCreateHandleService;
import com.hai.openApi.service.ApiOrderService;
import com.hai.order.model.CreateOrderChildModel;
import com.hai.order.model.CreateOrderModel;
import com.hai.order.service.OrderPayBeforeService;
import com.hai.order.service.OrderPayService;
import com.hai.order.service.OrderService;
import com.hai.order.type.OrderChildGoodsType;
import com.hai.order.type.OrderPayType;
import com.hai.order.type.OrderProductType;
import com.hai.order.type.OrderStatus;
import com.hai.order.utils.OrderUtil;
import com.hai.service.ApiMerchantsService;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service("apiOrderService")
public class ApiOrderServiceImpl implements ApiOrderService {

    @Resource
    private ApiMerchantsService apiMerchantsService;

    @Resource
    private ApiOrderMapper apiOrderMapper;

    @Resource
    private ApiOrderCreateHandleService orderCreateHandleService;

    @Resource
    private OrderService orderService;

    @Resource
    private OrderPayBeforeService orderPayBeforeService;

    @Resource
    private OrderPayService orderPayService;



    @Override
    @Transactional(rollbackFor=Exception.class,propagation= Propagation.REQUIRES_NEW)
    public ApiOrder createOrder(JSONObject object) throws Exception {

        ApiOrder apiOrder = new ApiOrder();


        //  获取下单内容
        JSONObject dataObject = JSONObject.parseObject(object.getString("content"));


        CreateOrderModel createOrderModel = new CreateOrderModel();
        createOrderModel.setChildOrderList(new ArrayList<>());

        // 查询订单
        Map<String , Object> orderMap = new HashMap<>();
        orderMap.put("mchOrderNo" , object.getString("orderNo"));
        List<ApiOrder> apiOrderList = getOrderByMap(orderMap);

        ApiMerchants apiMerchants = apiMerchantsService.findByMchId(object.getString("merchId"));

        createOrderModel.setMemName(apiMerchants.getMerchantName());
        createOrderModel.setMemPhone(apiMerchants.getPhone());
        createOrderModel.setCompanyId(2L);
        createOrderModel.setOrderNo(OrderUtil.generateOrderNo());

        // 判断订单号是否重复
        if (apiOrderList.size() > 0) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.ORDER_ALREADY_EXISTS);
        }

        // 处理星巴克订单
        if (OrderProductType.PRODUCT_TYPE1.getNumber().equals(object.getInteger("productType"))) {
            apiOrder = orderCreateHandleService.starbucksHandle(object);

            // 组装子订单内容
            CreateOrderChildModel createOrderChildModel = new CreateOrderChildModel();
            createOrderChildModel.setMemName(apiMerchants.getMerchantName());
            createOrderChildModel.setMemPhone(apiMerchants.getPhone());
            createOrderChildModel.setCompanyId(2L);
            createOrderChildModel.setGoodsType(OrderChildGoodsType.TYPE9.getNumber());
            createOrderChildModel.setCustomerMobile(dataObject.getString("customerMobile"));
            createOrderChildModel.setOrderItems(dataObject.getJSONArray("data"));
            createOrderChildModel.setStoreCode(dataObject.getString("storeCode"));
            createOrderChildModel.setSaleCount(1);
            createOrderChildModel.setIsTyAgent(false);
            createOrderChildModel.setGoodsPrice(apiOrder.getOrderPrice());
            // 组装订单
            createOrderModel.getChildOrderList().add(createOrderChildModel);
            orderService.createOrder(createOrderModel);
        }



        // 处理肯德基订单
        if (OrderProductType.PRODUCT_TYPE2.getNumber().equals(object.getInteger("productType"))) {
            apiOrder = orderCreateHandleService.kfcHandle(object);

            String orderItems = JSONObject.parseObject(apiOrder.getContent()).getString("orderItems");

            orderItems = orderItems.substring(0 , orderItems.length() - 1);

            // 组装子订单内容
            CreateOrderChildModel createOrderChildModel = new CreateOrderChildModel();
            createOrderChildModel.setMemName(apiMerchants.getMerchantName());
            createOrderChildModel.setMemPhone(apiMerchants.getPhone());
            createOrderChildModel.setCompanyId(2L);
            createOrderChildModel.setGoodsType(OrderChildGoodsType.TYPE4.getNumber());
            createOrderChildModel.setCustomerMobile(dataObject.getString("customerMobile"));
            createOrderChildModel.setEatType(dataObject.getInteger("eatType"));
            createOrderChildModel.setStoreCode(dataObject.getString("storeCode"));
            createOrderChildModel.setOrderItems(orderItems);
            createOrderChildModel.setSaleCount(1);
            createOrderChildModel.setIsTyAgent(false);
            createOrderChildModel.setGoodsPrice(apiOrder.getOrderPrice());
            // 组装订单
            createOrderModel.getChildOrderList().add(createOrderChildModel);
            orderService.createOrder(createOrderModel);
        }

        // 处理会员充值订单
        if (OrderProductType.PRODUCT_TYPE3.getNumber().equals(object.getInteger("productType"))) {
            apiOrder = orderCreateHandleService.memberRechargeHandle(object);

            // 组装子订单内容
            CreateOrderChildModel createOrderChildModel = new CreateOrderChildModel();
            createOrderChildModel.setMemName(apiMerchants.getMerchantName());
            createOrderChildModel.setMemPhone(apiMerchants.getPhone());
            createOrderChildModel.setCompanyId(2L);
            createOrderChildModel.setGoodsType(OrderChildGoodsType.TYPE10.getNumber());
            createOrderChildModel.setGoodsId(Long.valueOf(apiOrder.getExt1()));
            createOrderChildModel.setRechargeContent(dataObject.getString("mobile"));
            createOrderChildModel.setCustomerMobile(dataObject.getString("mobile"));
            createOrderChildModel.setSaleCount(1);
            createOrderChildModel.setIsTyAgent(false);
            createOrderChildModel.setGoodsPrice(apiOrder.getOrderPrice());

            // 组装订单
            createOrderModel.getChildOrderList().add(createOrderChildModel);
            orderService.createOrder(createOrderModel);
        }

        // 处理加油订单
        if (OrderProductType.PRODUCT_TYPE6.getNumber().equals(object.getInteger("productType"))) {
            apiOrder = orderCreateHandleService.oilHandle(object);

            // 组装子订单内容
            CreateOrderChildModel createOrderChildModel = new CreateOrderChildModel();
            createOrderChildModel.setMemName(apiMerchants.getMerchantName());
            createOrderChildModel.setMemPhone(apiMerchants.getPhone());
            createOrderChildModel.setCompanyId(2L);
            createOrderChildModel.setGoodsType(OrderChildGoodsType.TYPE3.getNumber());
            createOrderChildModel.setGasGunNo(dataObject.getString("gasGunNo"));
            createOrderChildModel.setGasOilNo(dataObject.getString("gasOilNo"));
            createOrderChildModel.setStoreId(dataObject.getLong("storeCode"));
            createOrderChildModel.setGoodsId(dataObject.getLong("storeCode"));
            createOrderChildModel.setSaleCount(1);
            createOrderChildModel.setIsTyAgent(false);
            createOrderChildModel.setGoodsPrice(apiOrder.getOrderPrice());

            // 组装订单
            createOrderModel.getChildOrderList().add(createOrderChildModel);
            orderService.createOrder(createOrderModel);
        }

        // 处理话费充值订单
        if (OrderProductType.PRODUCT_TYPE9.getNumber().equals(object.getInteger("productType"))) {
            apiOrder = orderCreateHandleService.mobileHandle(object);

            // 组装子订单内容
            CreateOrderChildModel createOrderChildModel = new CreateOrderChildModel();
            createOrderChildModel.setMemName(apiMerchants.getMerchantName());
            createOrderChildModel.setMemPhone(apiMerchants.getPhone());
            createOrderChildModel.setCompanyId(2L);
            createOrderChildModel.setGoodsType(OrderChildGoodsType.TYPE6.getNumber());
            createOrderChildModel.setGoodsId(dataObject.getLong("productId"));
            createOrderChildModel.setRechargeContent(dataObject.getString("mobile"));
            createOrderChildModel.setSaleCount(1);
            createOrderChildModel.setIsTyAgent(false);
            createOrderChildModel.setGoodsPrice(apiOrder.getOrderPrice());

            // 组装订单
            createOrderModel.getChildOrderList().add(createOrderChildModel);
            orderService.createOrder(createOrderModel);
        }

        // 处理停车券订单
        if (OrderProductType.PRODUCT_TYPE13.getNumber().equals(object.getInteger("productType"))) {

            apiOrder = orderCreateHandleService.mobileHandle(object);

            // 组装子订单内容
            CreateOrderChildModel createOrderChildModel = new CreateOrderChildModel();
            createOrderChildModel.setMemName(apiMerchants.getMerchantName());
            createOrderChildModel.setMemPhone(apiMerchants.getPhone());
            createOrderChildModel.setCompanyId(2L);
            createOrderChildModel.setGoodsType(OrderChildGoodsType.TYPE6.getNumber());
            createOrderChildModel.setGoodsId(dataObject.getLong("productId"));
            createOrderChildModel.setRechargeContent(dataObject.getString("mobile"));
            createOrderChildModel.setSaleCount(1);
            createOrderChildModel.setIsTyAgent(false);
            createOrderChildModel.setGoodsPrice(apiOrder.getOrderPrice());

            // 组装订单
            createOrderModel.getChildOrderList().add(createOrderChildModel);
            orderService.createOrder(createOrderModel);

        }



        apiOrder.setOrderNo(createOrderModel.getOrderNo());
        apiOrder.setStatus(1);

        // 当前账号余额是否可以充值当前金额
        if (apiMerchants.getAmounts().compareTo(apiOrder.getCostPrice()) < 0) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.INSUFFICIENT_BALANCE);
        }

        apiOrderMapper.insert(apiOrder);

        return apiOrder;

    }


    @Override
    @Transactional(rollbackFor=Exception.class,propagation= Propagation.REQUIRES_NEW)
    public ApiOrder payOrder(JSONObject object)  throws Exception{

        ApiMerchants apiMerchants = apiMerchantsService.findByMchId(object.getString("merchId"));

        ApiOrder apiOrder = findByOrderNo(object.getString("mchOrderNo") , null);

        // 查询订单
        HighOrder order = orderService.getOrderDetailByNo(object.getString("orderNo"));

        if(!order.getOrderStatus().equals(OrderStatus.STATUS1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.ORDER_NO_STAY_PAY, "");
        }

        // 支付业务交易
        orderPayBeforeService.payOrderCheck(order);

        // 处理订单
        HighOrder highOrder = orderPayService.apiMchAmount(order.getOrderNo() , apiMerchants , apiOrder);

        if (highOrder == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.PAY_FAIL, "");
        }

        if (highOrder.getExceptionStatus()) {
            apiOrder.setWhetherException(true);
            apiOrder.setRemark("当前订单存在异常请联系客服！");
        }

        if (!Objects.equals(highOrder.getOrderStatus(), OrderStatus.STATUS1.getNumber())) {
            apiOrder.setStatus(highOrder.getOrderStatus());
            apiOrder.setUpdateTime(new Date());
            apiOrderMapper.updateByPrimaryKey(apiOrder);
        }

        return apiOrder;

    }

    @Override
    public List<ApiOrder> getOrderByMap(Map<String, Object> map) {

        ApiOrderExample example = new ApiOrderExample();
        ApiOrderExample.Criteria criteria = example.createCriteria();


        if (MapUtils.getInteger(map, "productType") != null) {
            criteria.andProductTypeEqualTo(MapUtils.getInteger(map, "productType"));
        }
        if (StringUtils.isNotBlank(MapUtils.getString(map, "orderNo"))) {
            criteria.andOrderNoEqualTo(MapUtils.getString(map, "orderNo"));
        }
        if (StringUtils.isNotBlank(MapUtils.getString(map, "mchOrderNo"))) {
            criteria.andMchOrderNoEqualTo(MapUtils.getString(map, "mchOrderNo"));
        }
        if (StringUtils.isNotBlank(MapUtils.getString(map, "merchId"))) {
            criteria.andMchIdEqualTo(MapUtils.getString(map, "merchId"));
        }
        if (StringUtils.isNotBlank(MapUtils.getString(map, "createTimeS")) && StringUtils.isNotBlank(MapUtils.getString(map, "createTimeE"))) {
            criteria.andCreateTimeBetween(
                    DateUtil.format(MapUtils.getString(map, "createTimeS"), "yyyy-MM-dd HH:mm:ss"),
                    DateUtil.format(MapUtils.getString(map, "createTimeE"), "yyyy-MM-dd HH:mm:ss"));
        }

        return apiOrderMapper.selectByExample(example);
    }


    @Override
    public ApiOrder findByOrderNo(String mchOrderNo , String orderNo) {
        ApiOrderExample example = new ApiOrderExample();
        ApiOrderExample.Criteria criteria = example.createCriteria();

        if (mchOrderNo != null) {
            criteria.andMchOrderNoEqualTo(mchOrderNo);
        }

        if (orderNo != null) {
            criteria.andOrderNoEqualTo(orderNo);
        }

        List<ApiOrder> list = apiOrderMapper.selectByExample(example);

        if (list.size() > 0) {
            return list.get(0);
        }

        return null;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void refund(String orderNo) {
        HighOrder order = orderService.getOrderDetailByNo(orderNo);
        if (order == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的的订单");
        }
        if (!order.getOrderStatus().equals(OrderStatusEnum.type2.getType())
                && !order.getOrderStatus().equals(OrderStatusEnum.type3.getType())
                && !order.getOrderStatus().equals(OrderStatusEnum.type7.getType())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "订单当前状态无法退款");
        }
        if (!order.getPayType().equals(OrderPayType.PAY_TYPE9.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "支付方式错误");
        }

        ApiOrder apiOrder = findByOrderNo(null , orderNo);
        ApiMerchants merchants = apiMerchantsService.findByMchId(apiOrder.getMchId());

        if (apiOrder.getStatus() == 1 || apiOrder.getStatus() == 4 || apiOrder.getStatus() == 5) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "订单当前状态无法退款");
        }

        apiOrder.setStatus(4);
        apiOrder.setUpdateTime(new Date());
        apiOrderMapper.updateByPrimaryKey(apiOrder);


        Map<String, Object> map = new HashMap<>();
        map.put("sourceType", 100);
        map.put("sourceContent",  "退款金额：" + apiOrder.getCostPrice() + " 元");
        apiMerchantsService.recharge(merchants.getId(), apiOrder.getCostPrice(), map);


    }
}
