package com.younike.system.task;

import com.younike.system.domain.*;
import com.younike.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 统计任务
 */
@Component("statTask")
public class StatTask
{

    public static final String SPLIT = ",";
    /**
     * 任务日志
     */
    @Autowired
    private ITaskLogService taskLogService;

    @Autowired
    private IOrderService orderService;

    @Autowired
    private IMerchantService merchantService;

    @Autowired
    private IServerUserService serverUserService;

    @Autowired
    private IGoodsServerDimensionService goodsServerDimensionService;

    /**
     *  营业数据统计
     *
     *  统计近90天的数据
     */
    public void merchantBizStat(){
        TaskLog taskLog = new TaskLog();
        taskLog.setTaskName("营业数据统计");
        taskLog.setExecutionTime(LocalDateTime.now());
        try {
            /* 获取商家近90天订单列表 */
            // 003:服务完成（待确认） 004:已完成
            String[] orderStats = new String[]{"003","004"};
            List<OrderStat> orders = orderService.listLastOrders(90, orderStats);
            // 商铺分组集合
            Map<Long, List<OrderStat>> merchantMap = orders.stream().collect(Collectors.groupingBy(OrderStat::getMerchantId));
            // 服务人员分组集合
            Map<Long, List<OrderStat>> serverMap = orders.stream().collect(Collectors.groupingBy(OrderStat::getServerId));
            // 服务人员+商品分组集合
            Map<String, List<OrderStat>> serverGoodsMap = orders.stream().collect(Collectors.groupingBy(orderStat -> orderStat.getServerId() + SPLIT + orderStat.getGoodsId()));

            /* 更新商铺统计信息 */
            List<Merchant> merchantList = new ArrayList<>();
            merchantMap.forEach((id, list) -> {
                Merchant merchant = new Merchant();
                merchant.setMerchantId(id);
                // 成交量
                merchant.setSales(list.size());
                // 已评分订单
                List<OrderStat> scoredList = list.stream().filter(orderStat -> orderStat.getScore() != null).collect(Collectors.toList());
                if (scoredList.size() > 0) {
                    // 商家评分
                    merchant.setScore(scoredList.stream().map(OrderStat::getScore).reduce(BigDecimal::add).get()
                            .divide(BigDecimal.valueOf(scoredList.size()), 1, RoundingMode.HALF_UP));
                    // 好评率
                    merchant.setRate(BigDecimal.valueOf(scoredList.stream().filter(orderStat -> orderStat.getScore().compareTo(BigDecimal.valueOf(4L))>= 0).count()).
                            divide(BigDecimal.valueOf(scoredList.size()), 2, RoundingMode.HALF_UP));
                } else {
                    merchant.setScore(BigDecimal.ZERO);
                    merchant.setRate(BigDecimal.ZERO);
                }
                merchantList.add(merchant);
            });
            merchantService.updateMerchants(merchantList);

            /* 更新商铺统计信息 */
            List<ServerUser> users = new ArrayList<>();
            serverMap.forEach((id, list) -> {
                ServerUser serverUser = new ServerUser();
                serverUser.setServerId(id);
                // 成交量
                serverUser.setOrderCount(list.size());
                // 已评分订单
                List<OrderStat> scoredList = list.stream().filter(orderStat -> orderStat.getScore() != null).collect(Collectors.toList());
                if (scoredList.size() > 0) {
                    // 商家评分
                    serverUser.setScore(scoredList.stream().map(OrderStat::getScore).reduce(BigDecimal::add).get()
                            .divide(BigDecimal.valueOf(scoredList.size()), 1, RoundingMode.HALF_UP));
                    // 好评率
                    serverUser.setRate(BigDecimal.valueOf(scoredList.stream().filter(orderStat -> orderStat.getScore().compareTo(BigDecimal.valueOf(4L))>= 0).count()).
                            divide(BigDecimal.valueOf(scoredList.size()), 2, RoundingMode.HALF_UP));
                } else {
                    serverUser.setScore(BigDecimal.ZERO);
                    serverUser.setRate(BigDecimal.ZERO);
                }
                users.add(serverUser);
            });
            serverUserService.updateServerUsers(users);

            /* 更新服务人员-服务统计信息 -- goods_server_dimension表 */
            serverGoodsMap.forEach((id, list) -> {
                Long serverId = Long.parseLong(id.split(SPLIT)[0]);
                Long goodsId = Long.parseLong(id.split(SPLIT)[1]);
                if (list.size() > 0) {
                    // 所有的评价服务
                    List<GoodsCommentDimension> goodsCommentDimensionList = new ArrayList<>();
                    list.forEach(os ->  goodsCommentDimensionList.addAll(os.getGoodsCommentDimensionList()));
                    Map<String, List<GoodsCommentDimension>> dimensionMap = goodsCommentDimensionList.stream().collect(Collectors.groupingBy(GoodsCommentDimension::getDimensionId));
                    // 查询既有的评价统计数据
                    List<GoodsServerDimension>  goodsServerDimensions = goodsServerDimensionService.selectGoodsServerDimensionByServerIdAndGoodsId(serverId, goodsId);
                    if (goodsServerDimensions.size() > 0) {
                        // 旧的评价维度ID（防止服务评价维度修改）
                        Set<String> oldDids = new HashSet<>();
                        goodsServerDimensions.forEach(gsd -> {
                            List<GoodsCommentDimension> goodsCommentDimensions = dimensionMap.get(gsd.getDimensionId());
                            if (goodsCommentDimensions != null && goodsCommentDimensions.size() > 0) {
                                gsd.setScore(goodsCommentDimensions.stream().map(GoodsCommentDimension::getScore).reduce(BigDecimal::add).get()
                                        .divide(BigDecimal.valueOf(goodsCommentDimensions.size()), 1, RoundingMode.HALF_UP));
                            }
                            oldDids.add(gsd.getDimensionId());
                        });
                        // 执行更新操作
                        goodsServerDimensionService.updateGoodsServerDimensions(goodsServerDimensions);
                        Set<String> dimensionSet = dimensionMap.keySet();
                        if (!dimensionSet.equals(oldDids)) {
                            // 新旧维度不一致，插入新维度数据
                            dimensionSet.forEach(did -> {
                                if (!oldDids.contains(did)) {
                                    GoodsServerDimension gsd = new GoodsServerDimension();
                                    gsd.setServerId(serverId);
                                    gsd.setGoodsId(goodsId);
                                    gsd.setScore(dimensionMap.get(did).stream().map(GoodsCommentDimension::getScore).reduce(BigDecimal::add).get()
                                            .divide(BigDecimal.valueOf(dimensionMap.get(did).size()), 1, RoundingMode.HALF_UP));
                                    // 执行新增操作
                                    goodsServerDimensionService.insertGoodsServerDimension(gsd);
                                }
                            });
                        }

                    } else {
                        // 不存在既有评价数据
                        dimensionMap.forEach((dId, dList) -> {
                            if (dList !=null && dList.size() > 0) {
                                GoodsServerDimension gsd = new GoodsServerDimension();
                                gsd.setServerId(serverId);
                                gsd.setGoodsId(goodsId);
                                gsd.setScore(dList.stream().map(GoodsCommentDimension::getScore).reduce(BigDecimal::add).get()
                                        .divide(BigDecimal.valueOf(dList.size()), 1, RoundingMode.HALF_UP));
                                goodsServerDimensions.add(gsd);
                            }
                        });
                        // 执行新增操作
                        goodsServerDimensionService.insertGoodsServerDimensions(goodsServerDimensions);
                    }
                }
            });
            taskLog.setTaskResult(1);
        } catch (Exception e) {
            taskLog.setTaskResult(0);
            taskLog.setErrorLog(e.getMessage());
        } finally {
            taskLogService.insertTaskLog(taskLog);
        }
    }

    public static void main(String[] args) {

        Set<String> set1 = new HashSet<>();

        set1.add("1");
        set1.add("20");
        set1.add("35");
        set1.add("14");
        set1.add("5");

        System.out.println("Set 2 values : " + set1);

        Set<String> set2 = new HashSet<>();

        set2.add("1");
        set2.add("5");
        set2.add("14");
        set2.add("20");
        set2.add("35");

        System.out.println("Set 2 values : " + set2);

        // Method 1: Using equals() method
        boolean isEquals = set1.equals(set2);
        System.out.println("Comparing in different ways ");
        System.out.println("Way 1 with equals :: " + isEquals);

        // Method 2: Using containsALl()
        boolean havingAll = set1.containsAll(set2);
        System.out.println("Way 2 with containsAll :: " + havingAll);

        // Method 3: Using removeAll()
        boolean removedAll = set1.removeAll(set2);
        System.out.println("Way 3 with removeAll :: " + removedAll);
    }
}
