package com.slodon.b2b2c.util;

import com.slodon.b2b2c.bo.*;
import com.slodon.b2b2c.business.example.*;
import com.slodon.b2b2c.business.pojo.*;
import com.slodon.b2b2c.core.constant.GoodsConst;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.enums.ProvinceJson;
import com.slodon.b2b2c.enums.StatsConstant;
import com.slodon.b2b2c.enums.TerminalJson;
import com.slodon.b2b2c.goods.example.GoodsBrandExample;
import com.slodon.b2b2c.goods.example.GoodsExample;
import com.slodon.b2b2c.goods.pojo.Goods;
import com.slodon.b2b2c.goods.pojo.GoodsBrand;
import com.slodon.b2b2c.member.example.MemberBalanceRechargeExample;
import com.slodon.b2b2c.member.example.MemberExample;
import com.slodon.b2b2c.member.pojo.Member;
import com.slodon.b2b2c.member.pojo.MemberBalanceRecharge;
import com.slodon.b2b2c.model.business.*;
import com.slodon.b2b2c.model.goods.GoodsBrandModel;
import com.slodon.b2b2c.model.goods.GoodsModel;
import com.slodon.b2b2c.model.member.MemberBalanceRechargeModel;
import com.slodon.b2b2c.model.member.MemberModel;
import com.slodon.b2b2c.model.seller.StoreModel;
import com.slodon.b2b2c.seller.example.StoreExample;
import com.slodon.b2b2c.seller.pojo.Store;
import com.slodon.b2b2c.statistics.pojo.MemberBehavior;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

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

/**
 * 统计数据获取工具类
 */
@Component
public class StatsDataUtil {

    @Resource
    private OrderModel orderModel;
    @Resource
    private OrderExtendModel orderExtendModel;
    @Resource
    private OrderProductModel orderProductModel;
    @Resource
    private GoodsModel goodsModel;
    @Resource
    private OrderReturnModel orderReturnModel;
    @Resource
    private OrderAfterServiceModel orderAfterServiceModel;
    @Resource
    private MemberBalanceRechargeModel memberBalanceRechargeModel;
    @Resource
    private MemberModel memberModel;
    @Resource
    private GoodsBrandModel goodsBrandModel;
    @Resource
    private StoreModel storeModel;
    @Resource
    private MongoTemplate mongoTemplate;

    //region 基础数据查库

    /**
     * 查询一段时间内的统计基础数据
     *
     * @param startTime 统计开始时间
     * @param endTime   统计结束时间
     * @return
     */
    public StatsBasicDataBO searchStatsBasicData(Date startTime, Date endTime,String webSite) {
        //1.时间段内的订单
        OrderExample orderExample = new OrderExample();
        orderExample.setCreateTimeAfter(startTime);
        orderExample.setCreateTimeBefore(endTime);
        List<Order> orderList = orderModel.getOrderList(orderExample, null);

        //订单扩展列表
        List<OrderExtend> orderExtendList = new ArrayList<>();

        //2.订单货品列表
        List<OrderProduct> orderProductList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(orderList)) {
            //时间段内的订单货品
            StringBuilder orderSns = new StringBuilder();//构造orderSnIn

            orderList.forEach(order -> {
                orderSns.append(",'").append(order.getOrderSn()).append("'");
            });

            //查询订单扩展
            OrderExtendExample extendExample = new OrderExtendExample();
            extendExample.setOrderSnIn(orderSns.toString().substring(1));
            orderExtendList = orderExtendModel.getOrderExtendList(extendExample, null);

            //查询订单货品
            OrderProductExample orderProductExample = new OrderProductExample();
            orderProductExample.setOrderSnIn(orderSns.toString().substring(1));
            orderProductList = orderProductModel.getOrderProductList(orderProductExample, null);
        }

        //3.查询一段时间内完成的退款退货单
        OrderReturnExample orderReturnExample = new OrderReturnExample();
        orderReturnExample.setCompleteTimeAfter(startTime);
        orderReturnExample.setCompleteTimeBefore(endTime);
        List<OrderReturn> orderReturnList = orderReturnModel.getOrderReturnList(orderReturnExample, null);

        //4.售后单列表
        List<OrderAfterService> orderAfterServiceList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(orderReturnList)) {
            //拼接afsSns,查询售后单
            StringBuilder afsSns = new StringBuilder();
            orderReturnList.forEach(orderReturn -> {
                afsSns.append(",'").append(orderReturn.getAfsSn()).append("'");
            });

            //查询售后单
            OrderAfterServiceExample orderAfterServiceExample = new OrderAfterServiceExample();
            orderAfterServiceExample.setAfsSnIn(afsSns.toString().substring(1));
            orderAfterServiceList = orderAfterServiceModel.getOrderAfterServiceList(orderAfterServiceExample, null);
        }

        //5.查询一段时间内的用户行为数据
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and("behaviorTime").gte(startTime).lte(endTime);
        criteria.and("webSite").is(webSite);
        query.addCriteria(criteria);
        List<MemberBehavior> memberBehaviorList = mongoTemplate.find(query, MemberBehavior.class, "stats_member_behavior");

        //6.查询一段时间内的会员充值单
        MemberBalanceRechargeExample memberBalanceRechargeExample = new MemberBalanceRechargeExample();
        memberBalanceRechargeExample.setCreateTimeAfter(startTime);
        memberBalanceRechargeExample.setCreateTimeBefore(endTime);
        List<MemberBalanceRecharge> memberBalanceRechargeList = memberBalanceRechargeModel.getMemberBalanceRechargeList(memberBalanceRechargeExample, null);

        //7.查询一段时间内有统计数据的所有商品
        List<Goods> goodsList = new ArrayList<>();
        Set<Long> goodsIdSet = new HashSet<>();
        //todo 有订单|有售后|有浏览|。。。将所有商品一起查询
        orderProductList.forEach(orderProduct -> goodsIdSet.add(orderProduct.getGoodsId()));
        orderAfterServiceList.forEach(afterService -> goodsIdSet.add(afterService.getGoodsId()));
        memberBehaviorList.forEach(memberBehavior -> {
            if (!StringUtil.isNullOrZero(memberBehavior.getGoodsId())) {
                goodsIdSet.add(memberBehavior.getGoodsId());
            }
        });
        if (!CollectionUtils.isEmpty(goodsIdSet)) {
            //拼接商品ids
            StringBuilder goodsIds = new StringBuilder();
            goodsIdSet.forEach(goodsId -> {
                goodsIds.append(",").append(goodsId);
            });

            //查询一段时间有统计信息的商品
            GoodsExample goodsExample = new GoodsExample();
            goodsExample.setGoodsIdIn(goodsIds.toString().substring(1));
            goodsExample.setWebSite(webSite);
            goodsList = goodsModel.getGoodsList(goodsExample, null);
        }

        //8.查询一段时间内有统计数据的所有会员
        List<Member> memberList = new ArrayList<>();
        Set<Integer> memberIdSet = new HashSet<>();
        //todo 有订单|有售后|有充值|有浏览。。。将所有会员一起查询
        orderList.forEach(order -> memberIdSet.add(order.getMemberId()));
        orderReturnList.forEach(orderReturn -> memberIdSet.add(orderReturn.getMemberId()));
        memberBalanceRechargeList.forEach(memberBalanceRecharge -> memberIdSet.add(memberBalanceRecharge.getMemberId()));
        memberBehaviorList.forEach(memberBehavior -> memberIdSet.add(memberBehavior.getMemberId()));
        if (!CollectionUtils.isEmpty(memberIdSet)) {
            //拼接会员id
            StringBuilder memberIds = new StringBuilder();
            memberIdSet.forEach(memberId -> {
                memberIds.append(",").append(memberId);
            });

            //查询一段时间内有统计数据的所有会员
            MemberExample memberExample = new MemberExample();
            memberExample.setMemberIdIn(memberIds.toString().substring(1));
            memberExample.setWebSite(webSite);
            memberList = memberModel.getMemberList(memberExample, null);
        }

        //9.查询一段时间内新注册的会员
        MemberExample memberExample = new MemberExample();
        memberExample.setRegisterTimeAfter(startTime);
        memberExample.setRegisterTimeBefore(endTime);
        memberExample.setWebSite(webSite);
        List<Member> newMemberList = memberModel.getMemberList(memberExample, null);

        //10.查询一段时间内新增的商品
        GoodsExample goodsExample = new GoodsExample();
        goodsExample.setCreateTimeAfter(startTime);
        goodsExample.setCreateTimeBefore(endTime);
        goodsExample.setWebSite(webSite);
        List<Goods> newGoodsList = goodsModel.getGoodsList(goodsExample, null);

        //11.查询一段时间内新增的品牌
        GoodsBrandExample goodsBrandExample = new GoodsBrandExample();
        goodsBrandExample.setCreateTimeAfter(startTime);
        goodsBrandExample.setCreateTimeBefore(endTime);
        goodsBrandExample.setState(GoodsConst.BRAND_STATE_1);
        goodsBrandExample.setWebSite(webSite);
        List<GoodsBrand> newGoodsBrandList = goodsBrandModel.getGoodsBrandList(goodsBrandExample, null);

        //12.查询一段时间内新增的店铺
        StoreExample storeExample = new StoreExample();
        storeExample.setCreateTimeAfter(startTime);
        storeExample.setCreateTimeBefore(endTime);
        List<Store> newStoreList = storeModel.getStoreList(storeExample, null);

        //13.查询所有用户注册的行为
        Query query1 = new Query();
        Criteria criteria1 = new Criteria();
        criteria1.and("behaviorType").is(StatsConstant.MEMBER_REGISTER);
        criteria1.and("webSite").is(webSite);
        query1.addCriteria(criteria1);
        List<MemberBehavior> memberRegisterBehaviorList = mongoTemplate.find(query1, MemberBehavior.class, "stats_member_behavior");

        //14.查询所有店铺
        List<Store> storeList = storeModel.getStoreList(new StoreExample(), null);

        //set基础数据
        StatsBasicDataBO basicDataBO = new StatsBasicDataBO();
        basicDataBO.setOrderList(orderList);
        basicDataBO.setOrderExtendList(orderExtendList);
        basicDataBO.setOrderProductList(orderProductList);
        basicDataBO.setOrderReturnList(orderReturnList);
        basicDataBO.setOrderAfterServiceList(orderAfterServiceList);
        basicDataBO.setGoodsList(goodsList);
        basicDataBO.setMemberBehaviorList(memberBehaviorList);
        basicDataBO.setMemberBalanceRechargeList(memberBalanceRechargeList);
        basicDataBO.setMemberList(memberList);
        basicDataBO.setNewMemberList(newMemberList);
        basicDataBO.setNewGoodsList(newGoodsList);
        basicDataBO.setNewBrandList(newGoodsBrandList);
        basicDataBO.setNewStoreList(newStoreList);
        basicDataBO.setMemberRegisterBehaviorList(memberRegisterBehaviorList);
        basicDataBO.setStoreList(storeList);

        //基础数据二次处理,必须在所有基础数据set完毕后调用
        basicDataBO.basicDataTreatment();

        return basicDataBO;
    }
    //endregion

    //region 构造统计数据

    /**
     * 构造品牌统计数据
     *
     * @param basicDataBO 基础数据
     * @return
     */
    public Collection<BrandOrderBO> buildBrandStatsInfo(StatsBasicDataBO basicDataBO) {

        Map<Integer/*brandId*/, BrandOrderBO> brandOrderBOMap = new HashMap<>(); //品牌销售信息map
        //构造品牌和订单的关联关系
        basicDataBO.getGoodsList().forEach(goods -> {
            if (!StringUtil.isNullOrZero(goods.getBrandId())) {
                //商品品牌不为空时才统计
                if (brandOrderBOMap.containsKey(goods.getBrandId())) {
                    BrandOrderBO brandOrderBO = brandOrderBOMap.get(goods.getBrandId());
                    //将商品对应的订单货品列表，添加到品牌关联信息中
                    brandOrderBO.getOrderProductList().addAll(basicDataBO.getGoodsOrderProductMap().getOrDefault(goods.getGoodsId(), new ArrayList<>()));
                    //将商品对应的订单退货列表，添加到品牌关联信息中
                    brandOrderBO.getOrderReturnList().addAll(basicDataBO.getGoodsReturnMap().getOrDefault(goods.getGoodsId(), new ArrayList<>()));
                } else {
                    //新增一个品牌订单关联信息
                    BrandOrderBO brandOrderBO = new BrandOrderBO();
                    brandOrderBO.setBrandId(goods.getBrandId());
                    brandOrderBO.setBrandName(goods.getBrandName());
                    //将商品对应的订单货品列表，添加到品牌关联信息中
                    brandOrderBO.getOrderProductList().addAll(basicDataBO.getGoodsOrderProductMap().getOrDefault(goods.getGoodsId(), new ArrayList<>()));
                    //将商品对应的订单退货列表，添加到品牌关联信息中
                    brandOrderBO.getOrderReturnList().addAll(basicDataBO.getGoodsReturnMap().getOrDefault(goods.getGoodsId(), new ArrayList<>()));
                    brandOrderBOMap.put(goods.getBrandId(), brandOrderBO);
                }
            }
        });

        return brandOrderBOMap.values();
    }

    /**
     * 构造分类统计数据
     *
     * @param basicDataBO 基础数据
     * @return
     */
    public Collection<CategoryOrderBO> buildCategoryStatsInfo(StatsBasicDataBO basicDataBO) {

        Map<Integer/*categoryId*/, CategoryOrderBO> categoryOrderBOMap = new HashMap<>(); //分类销售信息map
        //构造分类和订单的关联关系
        basicDataBO.getGoodsList().forEach(goods -> {
            if (!StringUtil.isNullOrZero(goods.getCategoryId1())) {
                //商品分类不为空时才统计
                if (categoryOrderBOMap.containsKey(goods.getCategoryId1())) {
                    CategoryOrderBO categoryOrderBO = categoryOrderBOMap.get(goods.getCategoryId1());
                    //将商品对应的订单货品列表，添加到分类关联信息中
                    categoryOrderBO.getOrderProductList().addAll(basicDataBO.getGoodsOrderProductMap().getOrDefault(goods.getGoodsId(), new ArrayList<>()));
                    //将商品对应的订单退货列表，添加到分类关联信息中
                    categoryOrderBO.getOrderReturnList().addAll(basicDataBO.getGoodsReturnMap().getOrDefault(goods.getGoodsId(), new ArrayList<>()));
                } else {
                    //新增一个分类订单关联信息
                    CategoryOrderBO categoryOrderBO = new CategoryOrderBO();
                    categoryOrderBO.setCategoryId(goods.getCategoryId1());
                    categoryOrderBO.setCategoryName(goods.getCategoryPath().substring(0, goods.getCategoryPath().indexOf("->")));
                    categoryOrderBO.getOrderProductList().addAll(basicDataBO.getGoodsOrderProductMap().getOrDefault(goods.getGoodsId(), new ArrayList<>()));
                    //将商品对应的订单退货列表，添加到分类关联信息中
                    categoryOrderBO.getOrderReturnList().addAll(basicDataBO.getGoodsReturnMap().getOrDefault(goods.getGoodsId(), new ArrayList<>()));
                    categoryOrderBOMap.put(goods.getCategoryId1(), categoryOrderBO);
                }
            }
        });

        return categoryOrderBOMap.values();
    }

    /**
     * 构造商品统计数据
     *
     * @param basicDataBO 基础数据
     * @return
     */
    public Collection<GoodsStatsBO> buildGoodsStatsInfo(StatsBasicDataBO basicDataBO) {
        List<GoodsStatsBO> goodsStatsBOS = new ArrayList<>();
        //遍历商品列表构造商品统计数据
        basicDataBO.getGoodsList().forEach(goods -> {
            GoodsStatsBO goodsStatsBO = new GoodsStatsBO();
            goodsStatsBO.setGoods(goods);
            goodsStatsBO.getOrderProductList().addAll(basicDataBO.getGoodsOrderProductMap().getOrDefault(goods.getGoodsId(), new ArrayList<>()));
            goodsStatsBO.getOrderReturnList().addAll(basicDataBO.getGoodsReturnMap().getOrDefault(goods.getGoodsId(), new ArrayList<>()));
            goodsStatsBO.getMemberBehaviorList().addAll(basicDataBO.getGoodsMemberBehaviorMap().getOrDefault(goods.getGoodsId(), new ArrayList<>()));
            goodsStatsBOS.add(goodsStatsBO);
        });

        return goodsStatsBOS;
    }

    /**
     * 构造会员统计数据
     *
     * @param basicDataBO 基础数据
     * @return
     */
    public Collection<MemberStatsBO> buildMemberStatsInfo(StatsBasicDataBO basicDataBO) {
        List<MemberStatsBO> memberStatsBOS = new ArrayList<>();

        //遍历会员列表构造会员统计数据
        basicDataBO.getMemberList().forEach(member -> {
            MemberStatsBO memberStatsBO = new MemberStatsBO();
            memberStatsBO.setMember(member);
            memberStatsBO.getOrderList().addAll(basicDataBO.getMemberOrderMap().getOrDefault(member.getMemberId(), new ArrayList<>()));
            memberStatsBO.getOrderReturnList().addAll(basicDataBO.getMemberOrderReturnMap().getOrDefault(member.getMemberId(), new ArrayList<>()));
            memberStatsBO.getMemberBalanceRechargeList().addAll(basicDataBO.getMemberBalanceRechargeMap().getOrDefault(member.getMemberId(), new ArrayList<>()));
            if (!(CollectionUtils.isEmpty(memberStatsBO.getOrderList())
                    && CollectionUtils.isEmpty(memberStatsBO.getOrderReturnList())
                    && CollectionUtils.isEmpty(memberStatsBO.getMemberBalanceRechargeList()))) {
                memberStatsBOS.add(memberStatsBO);
            }
        });

        return memberStatsBOS;
    }

    /**
     * 构造店铺会员统计数据
     *
     * @param basicDataBO 基础数据
     * @return
     */
    public Collection<MemberStoreStatsBO> buildMemberStoreStatsInfo(StatsBasicDataBO basicDataBO) {
        List<MemberStoreStatsBO> memberStoreStatsBOS = new ArrayList<>();

        //遍历会员-店铺分组列表构造店铺会员统计数据
        basicDataBO.getMemberStoreSet().forEach(memberStoreId -> {
            List<Order> orderList = basicDataBO.getMemberStoreOrderMap().getOrDefault(memberStoreId, new ArrayList<>());
            List<OrderReturn> orderReturnList = basicDataBO.getMemberStoreOrderReturnMap().getOrDefault(memberStoreId, new ArrayList<>());

            MemberStoreStatsBO memberStoreStatsBO = new MemberStoreStatsBO();
            memberStoreStatsBO.getOrderList().addAll(orderList);
            memberStoreStatsBO.getOrderReturnList().addAll(orderReturnList);
            if (CollectionUtils.isEmpty(orderList)) {
                //无订单信息，从退货单中查询会员店铺信息
                OrderReturn orderReturn = orderReturnList.get(0);
                memberStoreStatsBO.setMemberId(orderReturn.getMemberId());
                memberStoreStatsBO.setMemberName(orderReturn.getMemberName());
                memberStoreStatsBO.setStoreId(orderReturn.getStoreId());
                memberStoreStatsBO.setStoreName(orderReturn.getStoreName());
            } else {
                //从订单中获取会员店铺信息
                Order order = orderList.get(0);
                memberStoreStatsBO.setMemberId(order.getMemberId());
                memberStoreStatsBO.setMemberName(order.getMemberName());
                memberStoreStatsBO.setStoreId(order.getStoreId());
                memberStoreStatsBO.setStoreName(order.getStoreName());
            }
            memberStoreStatsBOS.add(memberStoreStatsBO);
        });

        return memberStoreStatsBOS;
    }

    /**
     * 构造省份统计数据
     *
     * @param basicDataBO 基础数据
     * @return
     */
    public Collection<ProvinceStatsBO> buildProvinceStatsInfo(StatsBasicDataBO basicDataBO) {
        Collection<ProvinceStatsBO> provinceStatsBOS = new ArrayList<>();
        //每个省份都统计，不管有没有数据
        ProvinceJson.provinceMap.forEach((provinceCode, provinceName) -> {
            ProvinceStatsBO provinceStatsBO = new ProvinceStatsBO();
            provinceStatsBO.setProvinceCode(provinceCode);
            provinceStatsBO.setProvinceName(provinceName);
            provinceStatsBO.getOrderList().addAll(basicDataBO.getProvinceOrderMap().getOrDefault(provinceCode, new ArrayList<>()));
            provinceStatsBO.getOrderReturnList().addAll(basicDataBO.getProvinceOrderReturnMap().getOrDefault(provinceCode, new ArrayList<>()));
            provinceStatsBO.setNewMemberNum(basicDataBO.getProvinceNewMemberNumMap().getOrDefault(provinceCode, 0));
            provinceStatsBO.setNewStoreNum(basicDataBO.getProvinceNewStoreNumMap().getOrDefault(provinceCode, 0));
            provinceStatsBOS.add(provinceStatsBO);
        });

        return provinceStatsBOS;
    }

    /**
     * 构造店铺统计数据
     *
     * @param basicDataBO 基础数据
     * @return
     */
    public Collection<StoreStatsBO> buildStoreStatsInfo(StatsBasicDataBO basicDataBO) {
        Collection<StoreStatsBO> storeStatsBOS = new ArrayList<>();
        //每个店铺都统计，不管有没有数据
        basicDataBO.getStoreList().forEach(store -> {
            StoreStatsBO storeStatsBO = new StoreStatsBO();
            storeStatsBO.setStoreId(store.getStoreId());
            storeStatsBO.setStoreName(store.getStoreName());
            storeStatsBO.getOrderList().addAll(basicDataBO.getStoreOrderMap().getOrDefault(store.getStoreId(), new ArrayList<>()));
            storeStatsBO.getOrderProductList().addAll(basicDataBO.getStoreOrderProductMap().getOrDefault(store.getStoreId(), new ArrayList<>()));
            storeStatsBO.getOrderReturnList().addAll(basicDataBO.getStoreOrderReturnMap().getOrDefault(store.getStoreId(), new ArrayList<>()));
            storeStatsBO.getMemberBehaviorList().addAll(basicDataBO.getStoreMemberBehaviorMap().getOrDefault(store.getStoreId(), new ArrayList<>()));
            storeStatsBO.getStoreNewGoodsList().addAll(basicDataBO.getStoreNewGoodsMap().getOrDefault(store.getStoreId(), new ArrayList<>()));
            storeStatsBO.getNewMemberList().addAll(basicDataBO.getNewMemberList());
            storeStatsBOS.add(storeStatsBO);
        });

        return storeStatsBOS;
    }

    /**
     * 构造终端统计数据
     *
     * @param basicDataBO 基础数据
     * @return
     */
    public Collection<TerminalStatsBO> buildTerminalStatsInfo(StatsBasicDataBO basicDataBO) {
        Collection<TerminalStatsBO> terminalStatsBOS = new ArrayList<>();
        //每个终端都统计，不管有没有数据
        TerminalJson.terminalMap.forEach((terminalCode, terminalName) -> {
            TerminalStatsBO terminalStatsBO = new TerminalStatsBO();
            terminalStatsBO.setTerminalCode(terminalCode);
            terminalStatsBO.setTerminalName(terminalName);
            terminalStatsBO.getOrderList().addAll(basicDataBO.getTerminalOrderMap().getOrDefault(terminalCode, new ArrayList<>()));
            terminalStatsBO.getMemberBehaviorList().addAll(basicDataBO.getTerminalMemberBehaviorMap().getOrDefault(terminalCode, new ArrayList<>()));
            terminalStatsBO.getNewMemberList().addAll(basicDataBO.getTerminalNewMemberMap().getOrDefault(terminalCode, new ArrayList<>()));
            terminalStatsBO.getRechargeMemberSet().addAll(basicDataBO.getTerminalRechargeMemberMap().getOrDefault(terminalCode, new HashSet<>()));
            terminalStatsBOS.add(terminalStatsBO);
        });

        return terminalStatsBOS;
    }
    //endregion
}
