package com.gic.haoban.manage.service.service.content.adaptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.Page;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.business.order.dto.ordermanage.ListOrderItemDTO;
import com.gic.business.order.dto.ordermanage.OrderOutInfoDTO;
import com.gic.business.order.qdto.ordermanage.OrderInfoQDTO;
import com.gic.business.order.service.ordermanage.OrderInfoOutApiService;
import com.gic.haoban.manage.api.enums.content.MaterialInteractRecordEventType;
import com.gic.haoban.manage.service.pojo.bo.content.InteractRecordExtendInfoBO;
import com.gic.haoban.manage.service.pojo.bo.content.context.InteractRecordMessageContext;
import com.gic.haoban.manage.service.pojo.bo.content.message.InteractRecordMessageBO;
import com.gic.haoban.manage.service.pojo.qo.content.InteractRecordQO;
import com.gic.haoban.manage.service.service.content.InteractRecordService;
import com.gic.member.api.dto.info.MemberBaseInfoDTO;
import com.gic.member.api.dto.info.MemberPersonalInfoDTO;
import com.gic.member.api.dto.info.MemberSummaryInfoDTO;
import com.gic.member.api.dto.info.qo.QueryMemberInfoDTO;
import com.gic.member.api.service.MemberOutApiService;
import com.gic.order.api.dto.OrderDTO;
import com.gic.order.api.dto.OrderItemDTO;
import com.gic.order.api.dto.req.MemberOrderOptional;
import com.gic.order.api.service.member.MemberOrderReadApiService;
import com.gic.orderecommerce.api.constant.OrderChannelEnum;
import com.gic.orderecommerce.api.dto.EorderDTO;
import com.gic.orderecommerce.api.dto.EorderItemDTO;
import com.gic.orderecommerce.api.dto.MallEorderDTO;
import com.gic.orderecommerce.api.service.EcommerceOrderOutputApiService;
import com.gic.store.goods.dto.goods.GoodsSpuInfoDTO;
import com.gic.store.goods.dto.qdto.GoodsListQDTO;
import com.gic.store.goods.service.GoodsCenterApiService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author MUSI
 * @Date 2023/3/29 3:48 PM
 * @Description
 * @Version
 **/
@Slf4j
@Component
public class InteractRecordMessageBuilder {

    @Autowired
    private InteractRecordService interactRecordService;
    @Autowired
    MemberOutApiService memberOutApiService;
    @Autowired
    OrderInfoOutApiService orderInfoOutApiService;
    @Autowired
    private GoodsCenterApiService goodsCenterApiService;
    @Autowired
    private EcommerceOrderOutputApiService ecommerceOrderOutputApiService;
    @Autowired
    private MemberOrderReadApiService memberOrderReadApiService;

    /**
     * 计算互动记录的访问次数
     * // 通过clerkId、memberId、materialId 查询之前存在的记录总数，本次是第几次访问 在之前的记录总数上加1
     *
     * @param context
     */
    public void calcCustomerVisitTimes(InteractRecordMessageContext context) {
        InteractRecordQO searchQo = new InteractRecordQO();
        searchQo.setClerkId(context.getInteractRecordMessageBO().getClerkId());
        searchQo.setMemberId(context.getInteractRecordMessageBO().getMemberId());
        if (StringUtils.isBlank(searchQo.getMemberId())) {
            searchQo.setUnionId(context.getInteractRecordMessageBO().getUnionId());
        }
        searchQo.setPageSize(1);
        searchQo.setBizId(context.getBizId());
        Integer count = interactRecordService.countInteractRecord(searchQo);
        context.setTimes(count + 1);
    }

    /**
     * 冗余会员信息
     * @param context
     */
    public void redundantMemberInfo(InteractRecordMessageContext context) {
        String memberId = context.getInteractRecordMessageBO().getMemberId();
        if (StringUtils.isBlank(memberId)) {
            log.info("互动记录冗余会员信息 会员不存在");
            return;
        }
        InteractRecordMessageContext.MemberInfo memberInfo = this.queryMemberInfo(memberId);
        context.setMemberInfo(memberInfo);
    }

    /**
     * 查询会员信息
     * @param memberId
     * @return
     */
    public InteractRecordMessageContext.MemberInfo queryMemberInfo(String memberId) {
        QueryMemberInfoDTO queryMemberInfoDTO = QueryMemberInfoDTO
                .queryByMemberId(memberId)
                .setMemberBaseInfoDTO(true)
                .setMemberPersonalInfoDTO(true);
        ServiceResponse<MemberSummaryInfoDTO> serviceResponse = memberOutApiService.queryMemberInfo(queryMemberInfoDTO);
        if (!serviceResponse.isSuccess() || serviceResponse.getResult() == null) {
            log.info("查询会员信息为空 {}", memberId);
            return null;
        }
        MemberSummaryInfoDTO summaryInfoDTO = serviceResponse.getResult();
        MemberBaseInfoDTO memberBaseInfoDTO = summaryInfoDTO.getMemberBaseInfoDTO();
        MemberPersonalInfoDTO memberPersonalInfoDTO = summaryInfoDTO.getMemberPersonalInfoDTO();

        String phoneNumber = null;
        String memberName = null;
        String memberNickName = null;
        String memberImageUrl = null;
        if (memberBaseInfoDTO != null) {
            phoneNumber = memberBaseInfoDTO.getPhoneNumber();
        }
        if (memberPersonalInfoDTO != null) {
            memberName = memberPersonalInfoDTO.getMemberName();
            memberNickName = memberPersonalInfoDTO.getThirdNickname();
            memberImageUrl = memberPersonalInfoDTO.getThirdImgUrl();
        }
        InteractRecordMessageContext.MemberInfo memberInfo = new InteractRecordMessageContext
                .MemberInfo(memberName,  memberNickName, phoneNumber, memberImageUrl);
        return memberInfo;
    }

    /**
     * 计算会员是否有过订单
     * @param context
     */
    public void calcHaveOrderNum(InteractRecordMessageContext context) {
        String memberId = context.getInteractRecordMessageBO().getMemberId();
        if (StringUtils.isBlank(memberId)) {
            log.info("互动记录冗余会员信息 会员id不存在");
            return;
        }
        String enterpriseId = context.getInteractRecordMessageBO().getEnterpriseId();
        context.setHasDeal(false);
        // 查询会员全渠道订单
        boolean hasOrder = this.queryMemberHasOrder(memberId, enterpriseId);
        context.setHasDeal(hasOrder);
    }

    /**
     * 计算会员的订单
     * @param memberId
     * @param enterpriseId
     * @return
     */
    public boolean queryMemberHasOrder(String memberId, String enterpriseId) {
        ServiceResponse<Integer> response = memberOrderReadApiService.countByMember(enterpriseId, memberId, null);
        if (null != response && response.getResult() != null && response.getResult() > 0) {
            return true;
        }
        for (OrderChannelEnum value : OrderChannelEnum.values()) {
            Page<MallEorderDTO> eorderDTOPage = ecommerceOrderOutputApiService.queryEorderListByMemberId(enterpriseId, memberId, null, 1, 1, value.getChannelCode());
            if (eorderDTOPage != null && CollectionUtils.isNotEmpty(eorderDTOPage.getResult())) {
                return true;
            }
        }
        return false;
    }


    /**
     * 冗余订单项信息
     * @param
     * @return
     */
    public InteractRecordExtendInfoBO.ExtendOrderInfo buildMaterialOrderItemInfo(String enterpriseId, String orderNumber,
                                                                                 String memberId,
                                                                                 String orderId,
                                                                                 Integer orderType) {
        if (orderType == null) {
            return null;
        }
        if (orderType == 1) {
            return buildMallOrderItemInfo(enterpriseId, orderNumber);
        }
        if (orderType == 2) {
            return this.buildOnlineOrderItemInfo(enterpriseId, memberId, orderId);
        }
        if (orderType == 3) {
            return this.buildOfflineOrderItemInfo(enterpriseId, memberId, orderId);
        }
        return null;
    }

    private InteractRecordExtendInfoBO.ExtendOrderInfo buildMallOrderItemInfo(String enterpriseId, String orderNumber) {
        OrderInfoQDTO orderInfoQDTO = new OrderInfoQDTO();
        orderInfoQDTO.setOrderNumber(orderNumber);
        orderInfoQDTO.setEnterpriseId(enterpriseId);
        ServiceResponse<OrderOutInfoDTO> serviceResponse =
                orderInfoOutApiService.queryOrderInfo(orderInfoQDTO);
        if (!serviceResponse.isSuccess()) {
            log.info("查询订单信息异常 {}", JSON.toJSONString(serviceResponse));
            return null;
        }

        List<String> goodsIds = serviceResponse.getResult()
                .getOrderItems()
                .stream()
                .map(ListOrderItemDTO::getMallProId)
                .distinct()
                .collect(Collectors.toList());
        Map<String, Integer> goodsSourceTypeMap = this.queryGoodsSimpleInfo(enterpriseId, goodsIds);

        OrderOutInfoDTO orderOutInfoDTO = serviceResponse.getResult();
        InteractRecordExtendInfoBO.ExtendOrderInfo extendOrderInfo = new InteractRecordExtendInfoBO.ExtendOrderInfo();
        extendOrderInfo.setOrderNumber(orderOutInfoDTO.getOrderNumber());
        extendOrderInfo.setOrderCreateTime(orderOutInfoDTO.getCreateTime());
        extendOrderInfo.setOrderTotalNum(orderOutInfoDTO.getOrderItems().size());
        extendOrderInfo.setOrderPay(orderOutInfoDTO.getReceivableAmount());
        extendOrderInfo.setRealPay(orderOutInfoDTO.getPayAmount());
        List<InteractRecordExtendInfoBO.ExtendGoodsInfo> goodsInfos = orderOutInfoDTO.getOrderItems()
                .stream()
                .map(item -> {
                    InteractRecordExtendInfoBO.ExtendGoodsInfo goodsInfo = new InteractRecordExtendInfoBO.ExtendGoodsInfo();
                    goodsInfo.setGoodsId(item.getMallProId());
                    goodsInfo.setGoodsCode(item.getProCode());
                    goodsInfo.setGoodsName(item.getMallProName());
                    goodsInfo.setOrderNum(item.getMallProNumber().intValue());
                    goodsInfo.setGoodsImageUrl(item.getMallProImageUrl());
                    goodsInfo.setSalePrice(BigDecimal.valueOf(item.getMallProPrice()));
                    goodsInfo.setGoodsNorm(this.convertSkuNorm(item.getMallProSkuAttr()));
                    Integer sourceType = Optional.ofNullable(goodsSourceTypeMap.get(item.getMallProId())).orElse(2);
                    goodsInfo.setSourceType(sourceType);
                    return goodsInfo;
                })
                .collect(Collectors.toList());
        extendOrderInfo.setOrderGoodsInfos(goodsInfos);
        return extendOrderInfo;
    }

    private InteractRecordExtendInfoBO.ExtendOrderInfo buildOnlineOrderItemInfo(String enterpriseId, String memberId, String orderId) {
        // 基础侧线上单
        EorderDTO eorderDTO = ecommerceOrderOutputApiService.getEorderWholeByMemberIdAndOrderId(memberId, orderId);
        if (eorderDTO == null) {
            log.info("根据订单好查询订单异常 {}", JSON.toJSONString(eorderDTO));
            return null;
        }
        InteractRecordExtendInfoBO.ExtendOrderInfo extendOrderInfo = new InteractRecordExtendInfoBO.ExtendOrderInfo();
        extendOrderInfo.setOrderNumber(eorderDTO.getOrderNo());
        extendOrderInfo.setOrderCreateTime(eorderDTO.getOrderCreateTime());
        extendOrderInfo.setOrderPay(BigDecimal.valueOf(eorderDTO.getTotalAmount()));
        extendOrderInfo.setRealPay(BigDecimal.valueOf(eorderDTO.getPaymentAmount()));

        if (CollectionUtils.isNotEmpty(eorderDTO.getItem())) {
            extendOrderInfo.setOrderTotalNum(eorderDTO.getItem().size());
            List<String> goodsCodes = eorderDTO.getItem()
                    .stream()
                    .map(EorderItemDTO::getGoodsCode)
                    .distinct()
                    .collect(Collectors.toList());
            Map<String, Integer> goodsInfoSourceTypeMap = this.queryGoodsSourceTypeWithCodes(enterpriseId, goodsCodes);
            List<InteractRecordExtendInfoBO.ExtendGoodsInfo> extendGoodsInfos = new ArrayList<>();
            for (EorderItemDTO eorderItemDTO : eorderDTO.getItem()) {
                InteractRecordExtendInfoBO.ExtendGoodsInfo extendGoodsInfo = new InteractRecordExtendInfoBO.ExtendGoodsInfo();
                extendGoodsInfo.setGoodsId(eorderItemDTO.getGoodsId());
                extendGoodsInfo.setGoodsName(eorderItemDTO.getGoodsTitle());
                extendGoodsInfo.setGoodsImageUrl(eorderItemDTO.getImageUrl());
                extendGoodsInfo.setGoodsCode(eorderItemDTO.getGoodsCode());
                extendGoodsInfo.setGoodsNorm(eorderItemDTO.getSkuValue());
                extendGoodsInfo.setOrderNum(eorderItemDTO.getSkuNum());
                extendGoodsInfo.setSalePrice(BigDecimal.valueOf(eorderItemDTO.getPrice()));
                extendGoodsInfo.setSourceType(goodsInfoSourceTypeMap.get(eorderItemDTO.getGoodsCode()));
                if (extendGoodsInfo.getSourceType() == null) {
                    extendGoodsInfo.setSourceType(2);
                }
                extendGoodsInfos.add(extendGoodsInfo);
            }
            extendOrderInfo.setOrderGoodsInfos(extendGoodsInfos);
        }
        return extendOrderInfo;
    }

    /**
     * 构建线下订单数据
     * @param enterpriseId
     * @return
     */
    private InteractRecordExtendInfoBO.ExtendOrderInfo buildOfflineOrderItemInfo(String enterpriseId, String memberId, String orderId) {

        ServiceResponse<OrderDTO> serviceResponse = memberOrderReadApiService.queryById(enterpriseId, memberId, orderId, MemberOrderOptional.item());
        if (!serviceResponse.isSuccess() || serviceResponse.getResult() == null) {
            log.info("查询订单异常 {}", JSON.toJSONString(serviceResponse));
            return null;
        }
        OrderDTO orderDTO = serviceResponse.getResult();
        InteractRecordExtendInfoBO.ExtendOrderInfo extendOrderInfo = new InteractRecordExtendInfoBO.ExtendOrderInfo();
        extendOrderInfo.setOrderNumber(orderDTO.getOrderNumber());
        extendOrderInfo.setOrderCreateTime(orderDTO.getOrderTime());
        extendOrderInfo.setOrderTotalNum(orderDTO.getItemNum());
        extendOrderInfo.setOrderPay(BigDecimal.valueOf(orderDTO.getPaidAmount()));
        extendOrderInfo.setRealPay(BigDecimal.valueOf(orderDTO.getPayAmount()));
        if (CollectionUtils.isNotEmpty(orderDTO.getList())) {
            extendOrderInfo.setOrderTotalNum(orderDTO.getList().size());

            List<String> goodsCodes = orderDTO.getList()
                    .stream()
                    .map(OrderItemDTO::getProductCode)
                    .distinct()
                    .collect(Collectors.toList());
            Map<String, Integer> goodsSourceTypeMap = this.queryGoodsSourceTypeWithCodes(enterpriseId, goodsCodes);

            List<InteractRecordExtendInfoBO.ExtendGoodsInfo> extendGoodsInfos = new ArrayList<>();
            for (OrderItemDTO orderItemDTO : orderDTO.getList()) {
                InteractRecordExtendInfoBO.ExtendGoodsInfo extendGoodsInfo = new InteractRecordExtendInfoBO.ExtendGoodsInfo();
                extendGoodsInfo.setGoodsName(orderItemDTO.getProductName());
                extendGoodsInfo.setGoodsImageUrl(orderItemDTO.getQcloudImageUrl());
                extendGoodsInfo.setGoodsCode(orderItemDTO.getProductCode());
                if (StringUtils.isNotBlank(orderItemDTO.getAttrbute())) {
                    List<JSONObject> jsonObjects = JSON.parseArray(orderItemDTO.getAttrbute(), JSONObject.class);
                    if (CollectionUtils.isNotEmpty(jsonObjects)) {
                        List<String> norms = jsonObjects
                                .stream()
                                .map(item -> {
                                    String key = item.getString("key");
                                    String value = item.getString("value");
                                    return key + "," + value;
                                })
                                .collect(Collectors.toList());
                        extendGoodsInfo.setGoodsNorm(StringUtils.join(norms, ";"));
                    }
                }
                extendGoodsInfo.setOrderNum(orderItemDTO.getNumber());
                extendGoodsInfo.setSalePrice(Optional.ofNullable(orderItemDTO.getUnitPrice()).map(BigDecimal::new).orElse(null));
                extendGoodsInfo.setSourceType(Optional.ofNullable(goodsSourceTypeMap.get(orderItemDTO.getProductCode())).orElse(2));
                extendGoodsInfos.add(extendGoodsInfo);
            }
            extendOrderInfo.setOrderGoodsInfos(extendGoodsInfos);
        }
        return extendOrderInfo;
    }

    private Map<String, Integer> queryGoodsSimpleInfo(String enterpriseId, List<String> goodsIds) {
        GoodsListQDTO goodsListQDTO = new GoodsListQDTO();
        goodsListQDTO.setEnterpriseId(enterpriseId);
        goodsListQDTO.setIncludeGoodsIds(goodsIds);
        goodsListQDTO.setPageSize(goodsIds.size() + 1);
        ServiceResponse<Page<GoodsSpuInfoDTO>> serviceResponse =
                goodsCenterApiService.queryStoreGoodsList(goodsListQDTO);
        if (!serviceResponse.isSuccess() || CollectionUtils.isEmpty(serviceResponse.getResult().getResult())) {
            return Collections.emptyMap();
        }
        return serviceResponse.getResult()
                .getResult()
                .stream()
                .collect(Collectors.toMap(GoodsSpuInfoDTO::getGoodsId, GoodsSpuInfoDTO::getSourceType, (v1, v2) -> v1));
    }

    private Map<String, Integer> queryGoodsSourceTypeWithCodes(String enterpriseId, List<String> goodsCodes) {
        GoodsListQDTO goodsListQDTO = new GoodsListQDTO();
        goodsListQDTO.setEnterpriseId(enterpriseId);
        goodsListQDTO.setGoodsCodes(goodsCodes);
        goodsListQDTO.setPageSize(goodsCodes.size() + 1);
        ServiceResponse<Page<GoodsSpuInfoDTO>> serviceResponse =
                goodsCenterApiService.queryStoreGoodsList(goodsListQDTO);
        if (!serviceResponse.isSuccess() || CollectionUtils.isEmpty(serviceResponse.getResult().getResult())) {
            return Collections.emptyMap();
        }
        return serviceResponse.getResult()
                .getResult()
                .stream()
                .collect(Collectors.toMap(GoodsSpuInfoDTO::getGoodsCode, GoodsSpuInfoDTO::getSourceType, (v1, v2) -> v1));
    }

    private String convertSkuNorm(String skuAttr) {
        if (StringUtils.isBlank(skuAttr)) {
            return null;
        }
        List<JSONObject> jsonObjects = JSON.parseArray(skuAttr, JSONObject.class);
        List<String> norms = jsonObjects
                .stream()
                .map(item -> {
                    String propName = item.getString("propName");
                    String valueName = item.getString("valueName");
                    return propName + "," + valueName;
                })
                .collect(Collectors.toList());
        return StringUtils.join(norms, ",");
    }

    /**
     * 组装浏览商品事件
     * @param context
     */
    private void buildVisitProduct(InteractRecordMessageContext context) {
        InteractRecordMessageBO interactRecordMessageBO = context.getInteractRecordMessageBO();
        if (!MaterialInteractRecordEventType.VISIT_PRODUCT.getCode().equals(interactRecordMessageBO.getEventType())) {
            return;
        }
    }


}
