package com.zm.order.tool.server.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.github.dozermapper.core.Mapper;
import com.google.common.collect.Lists;
import com.zm.order.tool.server.builder.SearchRequestBuilder;
import com.zm.order.tool.server.dao.RefundDao;
import com.zm.order.tool.server.dto.OrderDTO;
import com.zm.order.tool.server.dto.RefundDTO;
import com.zm.order.tool.server.enums.BizTypeEnum;
import com.zm.order.tool.server.model.BaseIndexOrder;
import com.zm.order.tool.server.model.Order;
import com.zm.order.tool.server.model.QxdIndexOrder;
import com.zm.order.tool.server.model.Refund;
import com.zm.order.tool.server.query.RefundQuery;
import com.zm.order.tool.server.query.SearchOrderQuery;
import com.zm.order.tool.server.service.ExceptionConstants;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * @Description 餐饮业务处理
 * @Author: ph
 * @Date: 2019/12/9 19:47
 */
@Component
public class QxdBusinessHandler implements BusinessHandler {

    private static final Logger logger = LoggerFactory.getLogger(QxdBusinessHandler.class);

    @Autowired
    private Mapper mapper;

    @Autowired
    private RefundDao refundDao;

    /**
     * 订单已关闭
     */
    private static final Integer ORDER_CLOSE_STATUS = 6;

    /**
     * 订单已支付
     */
    private static final Integer ORDER_PAYED_STATUS = 1;

    /**
     * 企小店-完成退款 order_refund --> status
     */
    private static final Integer REFUND_COMPLETED_STATUS = 2;

    @Override
    public Integer bizType() {
        return BizTypeEnum.PT.getType();
    }

    /**
     * 同步es参数构建
     * @param order
     * @return: com.zm.order.biz.model.BaseIndexOrder
     * @Date:   2020/3/30 4:06 PM
     */
    @Override
    public BaseIndexOrder buildIndexOrder(Order order) {
        QxdIndexOrder indexOrder = mapper.map(order, QxdIndexOrder.class);
        // 基本参数构建
        buildBaseInfo(order, indexOrder);
        return indexOrder;
    }

    /**
     * 同步es基本参数构建
     * @param order
     * @param indexOrder
     * @return: void
     * @Date:   2020/3/31 3:58 PM
     */
    private void buildBaseInfo(Order order, QxdIndexOrder indexOrder) {
        indexOrder.setOrderId(order.getId());
        // 查询优惠订单场景，DiscountAmount在es中没有查询索引，无法直接查询
        if (Objects.nonNull(order.getDiscountAmount()) && order.getDiscountAmount() > 0) {
            indexOrder.setDiscount(1);
        }

        // 设置是否退款完成
        indexOrder.setRefundCompleted(0);
        final boolean refundFlag = Objects.equals(order.getStatus(), ORDER_CLOSE_STATUS) && Objects.equals(order.getPayStatus(), ORDER_PAYED_STATUS);
        if (refundFlag) {
            RefundQuery refundQuery = new RefundQuery();
            refundQuery.setOrderNo(order.getOrderNo());
            List<Refund> refundList = refundDao.selectList(refundQuery);
            if (!CollectionUtils.isEmpty(refundList)) {
                for (Refund refund : refundList) {
                    if (Objects.equals(refund.getStatus(), REFUND_COMPLETED_STATUS)) {
                        indexOrder.setRefundCompleted(1);
                    }
                }
            }
        }

        // 获取全局搜索参数
        Map<String, Object> extraMap = order.getExtraMap();
        indexOrder.setGlobalSearch(Optional.ofNullable(extraMap).map(extMap -> extMap.get("globalSearch") + "").orElse(null));
    }

    /**
     * es查询参数构建
     * @param searchOrderQuery
     * @return: org.elasticsearch.search.builder.SearchSourceBuilder
     * @Date:   2020/3/30 4:06 PM
     */
    @Override
    public SearchSourceBuilder buildSearchSourceBuilder(SearchOrderQuery searchOrderQuery) {
        SearchSourceBuilder searchSourceBuilder = SearchRequestBuilder.buildOrderSearchBuilder(searchOrderQuery);
        return searchSourceBuilder;
    }

    @Override
    public List<BaseIndexOrder> parseIndexOrder(SearchHit[] searchHits) {
        List<BaseIndexOrder> list = Lists.newArrayListWithCapacity(searchHits.length);
        for (int i = 0; i < searchHits.length; i++) {
            SearchHit searchHit = searchHits[i];
            BaseIndexOrder t = JSON.parseObject(searchHit.getSourceAsString(), QxdIndexOrder.class);
            list.add(t);
        }
        return list;
    }

    /**
     * 获取退款总金额（单个订单）
     * @param refundDTO 退款模型
     * @return: java.lang.Integer
     * @Date:   2020/3/23 11:47 AM
     */
    @Override
    public Integer getRefundAmount(RefundDTO refundDTO) {
        Integer refundAmount = 0;
        if (Objects.equals(REFUND_COMPLETED_STATUS, refundDTO.getStatus())) {
            refundAmount = refundDTO.getRefundAmount();
        }
        return refundAmount;
    }

    /**
     * 获取订单模型
     * @param baseIndexOrder
     * @param orderDTO
     * @param order
     * @return: com.zm.order.biz.model.BaseIndexOrder
     * @Date:   2020/3/30 4:03 PM
     */
    @Override
    public BaseIndexOrder getOrderDto(BaseIndexOrder baseIndexOrder, OrderDTO orderDTO, Order order) {
        QxdIndexOrder qxdIndexOrder = (QxdIndexOrder) baseIndexOrder;
        orderDTO.setRefundCompleted(qxdIndexOrder.getRefundCompleted());
        if (order != null && Objects.nonNull(order.getActivityInfo())) {
            try {
//                orderDTO.setActivityInfoMap(JSONObject.parseObject(order.getActivityInfo()));
            }catch (JSONException e){
                logger.error("QxdBusinessHandler[getOrderDtos]convertObject failed because ActivityInfo not json，ActivityInfo: {},cause by: {}",
                        order.getActivityInfo(), e);
                throw new RuntimeException(ExceptionConstants.ACTIVITY_INFO_ERROR.getErrorMessage());
            }
        }
        return qxdIndexOrder;
    }

    /**
     * 聚合查询
     * @param searchOrderQuery
     * @param searchSourceBuilder
     * @return: void
     * @Date:   2020/3/23 4:00 PM
     */
    private void buildComplexSearchInfo(SearchOrderQuery searchOrderQuery, SearchSourceBuilder searchSourceBuilder) {
        if (!StringUtils.isEmpty(searchOrderQuery.getAmountField())) {
            AggregationBuilder sumBuilder = AggregationBuilders.sum("amount").field(searchOrderQuery.getAmountField());
            searchSourceBuilder.aggregation(sumBuilder);
        }
    }

    /**
     * 基本信息
     * @param boolQueryBuilder
     * @param searchOrderQuery
     * @return: void
     * @Date:   2020/3/23 4:00 PM
     */
    private void buildBaseSearchInfo(BoolQueryBuilder boolQueryBuilder, SearchOrderQuery searchOrderQuery) {
        boolQueryBuilder.must(QueryBuilders.termQuery("isDeleted", 0));

        if (Objects.nonNull(searchOrderQuery.getGlobalSearch())) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("globalSearch", searchOrderQuery.getGlobalSearch()));
        }
    }
}
