package com.hzs.sale.order.controller;

import com.hzs.common.core.constant.CountryConstants;
import com.hzs.common.core.constant.msg.MemberMsgConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.service.RedisService;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.domain.member.account.CuMemberAccount;
import com.hzs.common.domain.member.ext.CuMemberAccountExt;
import com.hzs.common.domain.sale.order.SaOrder;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.util.TransactionUtils;
import com.hzs.sale.order.param.OrderItemsParam;
import com.hzs.sale.order.param.OrderParam;
import com.hzs.sale.order.param.OrderReturn;
import com.hzs.sale.order.param.WaresItemsParam;
import com.hzs.sale.order.service.ISaOrderService;
import com.hzs.sale.shopping.service.IShoppingCartService;
import com.hzs.sale.shopping.vo.ProductGroup;
import com.hzs.sale.shopping.vo.ShoppingCartRedis;
import com.hzs.sale.shopping.vo.ShoppingCartVO;
import com.hzs.system.base.IAreaServiceApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
public abstract class ParentOrderController extends BaseController {

    @DubboReference
    IAreaServiceApi iAreaServiceApi;

    private ISaOrderService orderService;

    protected RedisService redisService;

    @Autowired
    protected IShoppingCartService shoppingCartService;

    @Autowired
    public void setRedisService(RedisService redisService) {
        this.redisService = redisService;
    }

    @Autowired
    public void setOrderService(ISaOrderService orderService) {
        this.orderService = orderService;
    }

    public ISaOrderService getOrderService() {
        return orderService;
    }

    /**
     * 检查输入的条件
     *
     * @param orderParam 条件
     * @return boolean
     */
    protected Boolean checkRecPostageMsgBoolean(@RequestBody OrderParam orderParam) {
        return orderParam.getSpecialArea() != null
                && orderParam.getDeliveryWay() != null && orderParam.getTransType() != null
                && orderParam.getRecProvince() != null && orderParam.getRecCity() != null
                && orderParam.getOrderItemsParams() != null
                && orderParam.getOrderItemsParams().size() > 0;
    }

    /**
     * 初始化参数
     *
     * @param orderParam 参数
     */
    protected void initSecurityOrderParam(OrderParam orderParam) {
        orderParam.setSystemType(SecurityUtils.getSystemType());
        orderParam.setCenterCodeId(SecurityUtils.getUserId());
        initPkCountry(orderParam);
        if (orderParam.getPostage() == null) {
            orderParam.setPostage(BigDecimal.ZERO);
        }
        if (orderParam.getTransType() == null) {
            // 国内默认陆运 海外默认海运
            if (orderParam.getPkSettleCountry().equals(CountryConstants.CHINA_COUNTRY)) {
                orderParam.setTransType(ETransportType.LAND.getValue());
            } else {
                orderParam.setTransType(ETransportType.LAND.getValue());
            }
        }
    }

    protected void initPkCountry(OrderParam orderParam) {
        if (orderParam.getPkSettleCountry() == null) {
            orderParam.setPkSettleCountry(SecurityUtils.getPkCountry());
        }
        orderParam.setPkLoginSettleCountry(SecurityUtils.getPkCountry());
    }

    protected CuMemberAccount getCuMemberAccount(OrderParam orderParam) {
        CuMemberAccount cuMemberAccount = CuMemberAccount.builder().pkMember(orderParam.getCenterCodeId()).build();
        cuMemberAccount.setPkCountry(orderParam.getPkLoginSettleCountry());
        return cuMemberAccount;
    }

    /**
     * 验证会员账户、会员状态
     *
     * @param orderParam 参数
     * @return AjaxResult
     */
    protected AjaxResult validateMemberAccount(OrderParam orderParam) {
        List<CuMemberAccountExt> cuMemberAccountExtList = getOrderService().queryMemberAccountByCondition(getCuMemberAccount(orderParam));
        if (cuMemberAccountExtList == null || cuMemberAccountExtList.size() <= 0) {
            return AjaxResult.error(TransactionUtils.getContent(MemberMsgConstants.CENTER_NOT_EXISTS));
        }
        CuMemberAccountExt cuMemberAccountExt = cuMemberAccountExtList.get(0);
        // 验证密码
        if (!SecurityUtils.matchesPassword(orderParam.getPayPwd(), cuMemberAccountExt.getPayPwd())) {
            return AjaxResult.error(TransactionUtils.getContent(MemberMsgConstants.MEMBER_PASSWORD_NOT_MATCH));
        }
        // 验证账户状态、钱包状态
        if (cuMemberAccountExt.getAccountStatus() != EAccountStatus.NORMAL.getValue()) {
            return AjaxResult.error(TransactionUtils.getContent(MemberMsgConstants.MEMBER_ACCOUNT_STATUS_LOCK));
        }
        return AjaxResult.success(cuMemberAccountExt);
    }


    protected SaOrder getSaOrderQueryParam(OrderParam orderParam) {
        SaOrder saOrder = SaOrder.builder()
                .orderCode(orderParam.getOrderCode())
                .orderStatus(EOrderStatus.WAIT_PAY.getValue())
                .orderType(orderParam.getSpecialArea()).build();
        saOrder.setPkCountry(orderParam.getPkSettleCountry());
        return saOrder;
    }

    /**
     * 查询订单返回值，用于支付
     *
     * @param saOrder    订单
     * @param orderParam 参数
     */
    protected OrderReturn getOrderReturn(SaOrder saOrder, OrderParam orderParam) {
        // 封装订单信息
        long maxPayTime = getOrderService().getIsToBePayTime(orderParam.getPkSettleCountry(), saOrder.getOrderType());
        //查询带关闭参数
        BigDecimal orderAmount = saOrder.getOrderAmount();
        Map<Integer, String> areaMap = iAreaServiceApi.getAreaMap(orderParam.getPkSettleCountry()).getData();
        OrderReturn orderReturn = OrderReturn.builder()
                .orderCode(saOrder.getOrderCode())
                .orderAmount(ComputeUtil.computeAdd(orderAmount, saOrder.getPostage()))
                .specialArea(saOrder.getOrderType())
                .isToBePay(EYesNo.NO.getIntValue())
                .pkCountry(saOrder.getPkCountry())
                .postage(saOrder.getPostage())
                .deliveryWay(saOrder.getDeliveryWay())
                .transType(saOrder.getTranType())
                .recName(saOrder.getRecName())
                .recPhone(saOrder.getRecPhone())
                .recProvince(areaMap.get(saOrder.getRecProvince()))
                .recCity(areaMap.get(saOrder.getRecCity()))
                .recCounty(areaMap.get(saOrder.getRecCounty()))
                .recAddress(saOrder.getRecAddress())
                .build();
        if (maxPayTime > 0) {
            orderReturn.setIsToBePay(EYesNo.YES.getIntValue());
            // 计算订单目前秒数
            long currentTime = DateUtils.parseDateToSecond() - DateUtils.parseDateToSecond(saOrder.getCreationTime());
            long payTime = maxPayTime - currentTime;
            if (payTime < 0) {
                payTime = 0;
            }
            orderReturn.setPayTime(payTime);
        }
        return orderReturn;
    }

    /**
     * 将购物车的数量转换到sku种
     */
    protected void convertShoppingCarToSku(OrderParam orderParam) {
        ShoppingCartVO shoppingCartVO = new ShoppingCartVO();
        shoppingCartVO.setDeleteList(orderParam.getDeleteList());
        List<ShoppingCartRedis> shoppingCartRedisList = shoppingCartService.queryShopping(orderParam.getCenterCodeId(), shoppingCartVO);
        List<OrderItemsParam> orderItemsParamList = new ArrayList<>(shoppingCartRedisList.size());
        shoppingCartRedisList.forEach(shoppingCartRedis -> {
            OrderItemsParam orderItemsParam = OrderItemsParam.builder()
                    .pkId(shoppingCartRedis.getPkId())
                    .channel(shoppingCartRedis.getSource())
                    .waresCode(shoppingCartRedis.getWaresCode())
                    .quantity(shoppingCartRedis.getNumber())
                    .build();
            List<WaresItemsParam> waresItemsParamList = new ArrayList<>(shoppingCartRedis.getProductGroup().size());
            for (ProductGroup productGroup : shoppingCartRedis.getProductGroup()) {
                WaresItemsParam waresItemsParam = WaresItemsParam.builder()
                        .pkWaresSpecsSku(productGroup.getPkSkuId())
                        .quantity(productGroup.getQuantity())
                        .build();
                waresItemsParamList.add(waresItemsParam);
            }
            orderItemsParam.setWaresItemsParamList(waresItemsParamList);
            orderItemsParamList.add(orderItemsParam);
        });
        orderParam.setOrderItemsParams(orderItemsParamList);
    }

}
