package com.xxfc.platform.order.biz;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.db.PageResult;
import com.github.pagehelper.Page;
import com.github.wxiaoqi.security.admin.entity.BaseUserMemberLevel;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.xxfc.platform.order.Utils.OrderDateUtils;
import com.xxfc.platform.order.contant.enumerate.OrderInquiryType;
import com.xxfc.platform.order.entity.MembersOrder;
import com.xxfc.platform.order.entity.OrderStatistics;
import com.xxfc.platform.order.mapper.OrderStatisticsMapper;
import com.xxfc.platform.order.pojo.HomePageOrderData;
import com.xxfc.platform.order.pojo.Member;
import com.xxfc.platform.order.pojo.MembersOrderDto;
import com.xxfc.platform.order.pojo.OrderQuery;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author Administrator
 */
@Service
public class OrderStatisticsBiz extends BaseBiz<OrderStatisticsMapper, OrderStatistics> {
    @Autowired
    private DailyVehicleOrderStatisticsBiz vehicleBiz;


    @Autowired
    private DailyTravelOrderStatisticsBiz TravelBiz;

    @Autowired
    private DailyMembersOrderStatisticsBiz membersBiz;

    public HomePageOrderData getTotalOrder(Integer companyId) {
        HomePageOrderData result = new HomePageOrderData();
        ArrayList<HomePageOrderData> orderStatistics = new ArrayList<>();

        OrderStatistics vehicle = vehicleBiz.findAll(companyId);
        if (vehicle != null) {
            HomePageOrderData data = new HomePageOrderData() {{
                setTotalOrders(vehicle.getTotalGmv().subtract(vehicle.getTotalReturnGmv()));
                setAdditionalIndemnity(vehicle.getTotalCompensation()
                        .add(vehicle.getTotalForfeit())
                        .add(vehicle.getTotalDefaultMoney())
                        .add(vehicle.getTotalExpenditure().subtract(vehicle.getTotalGmv().subtract(vehicle.getTotalReturnGmv())))
                );
            }};
            orderStatistics.add(data);
        }
        OrderStatistics tour = TravelBiz.findAll(companyId);

        if (vehicle != null) {
            HomePageOrderData data = new HomePageOrderData() {{
                setTotalOrders(tour.getTotalGmv().subtract(tour.getTotalReturnGmv()));
                setAdditionalIndemnity(tour.getTotalDefaultMoney());
            }};
            orderStatistics.add(data);
        }
        OrderStatistics member = membersBiz.findAll(companyId);
        if (vehicle != null) {
            HomePageOrderData data = new HomePageOrderData() {{
                setTotalOrders(member.getTotalGmv());

            }};
            orderStatistics.add(data);
        }


        result.setTotalOrders(orderStatistics.stream().map(HomePageOrderData::getTotalOrders).filter(o -> Objects.nonNull(o)).reduce(BigDecimal.ZERO, BigDecimal::add));

        result.setTotalOutstandingDeposit(orderStatistics.stream().map(HomePageOrderData::getTotalOutstandingDeposit).filter(o -> Objects.nonNull(o)).reduce(BigDecimal.ZERO, BigDecimal::add));

        result.setAdditionalIndemnity(orderStatistics.stream().map(HomePageOrderData::getAdditionalIndemnity).filter(o -> Objects.nonNull(o)).reduce(BigDecimal.ZERO, BigDecimal::add));

        return result;
    }

    public PageResult<MembersOrderDto> getMemberOrderStatistics(List<BaseUserMemberLevel> memberLevels, OrderQuery query) {
        List<MembersOrder> membersOrderList = membersBiz.getMemberOrderStatistics(query);

        //按每天分类
        if (CollectionUtil.isEmpty(membersOrderList)) {
            return null;
        }
        //按每天分类
        if (CollectionUtil.isEmpty(memberLevels)) {
            throw new BaseException("获取不到会员信息");
        }
        //获取会员等级对应的名称
        HashMap<Integer, String> map = Maps.newHashMap();
        for (BaseUserMemberLevel memberLevel : memberLevels) {
            map.put(memberLevel.getLevel(), memberLevel.getName());
        }
        //按查询条件获取统计信息
        ArrayList<MembersOrderDto> arrayList = Lists.newArrayList();
        if (OrderInquiryType.DAY.getCode().equals(query.getType())) {
            for (MembersOrder mb : membersOrderList) {
                MembersOrderDto mbdto = new MembersOrderDto();
                //设置时间段
                mbdto.setTimeSlot(mb.getPeriod());
                TotalPaymentAndMemberName(map, mb, mbdto);
                arrayList.add(mbdto);
            }
        } else {
            if (membersOrderList.size() == 1) {
                MembersOrder mb = membersOrderList.get(0);
                MembersOrderDto mbdto = new MembersOrderDto();
                //设置时间段
                mbdto.setTimeSlot(query.getStartTime() + "-" + query.getEndTime());
                TotalPaymentAndMemberName(map, mb, mbdto);
                arrayList.add(mbdto);

            } else {

                for (int i = 0; i < membersOrderList.size(); i++) {
                    MembersOrder mb = membersOrderList.get(i);
                    String period = mb.getPeriod();
                    if (StringUtils.isBlank(period)) {
                        continue;
                    }
                    MembersOrderDto mbdto = new MembersOrderDto();
                    String[] periods = mb.getPeriod().split("-");
                    String startDay = null;
                    String endDay = null;
                    if (OrderInquiryType.WEEK.getCode().equals(query.getType())) {
                        startDay = OrderDateUtils.getEndDayOfWeekNo(Integer.parseInt(periods[0]), Integer.parseInt(periods[1]));
                        endDay = OrderDateUtils.getStartDayOfWeekNo(Integer.parseInt(periods[0]), Integer.parseInt(periods[1]));
                    }
                    if (OrderInquiryType.MONTH.getCode().equals(query.getType())) {
                        startDay = OrderDateUtils.getFirstDayOfMonth(Integer.parseInt(periods[0]), Integer.parseInt(periods[1]));
                        endDay = OrderDateUtils.getLastDayOfMonth(Integer.parseInt(periods[0]), Integer.parseInt(periods[1]));
                    }

                    if (i == 0) {

                        startDay = timeStampConversionToString(query.getStartTime());
                    }
                    if (i == (membersOrderList.size() - 1)) {
                        endDay = timeStampConversionToString(query.getEndTime());
                    }
                    if (StringUtils.isNotBlank(startDay) && StringUtils.isNotBlank(endDay)) {
                        mbdto.setTimeSlot(startDay + "-" + endDay);
                    } else {
                        mbdto.setTimeSlot("");
                    }
                    arrayList.add(mbdto);
                }
            }
        }
         //进行分页处理


        return  pagingProcessing(query,arrayList);

    }

    private PageResult pagingProcessing(OrderQuery query, ArrayList<MembersOrderDto> arrayList) {
        PageResult pageResult = (PageResult) arrayList;
        pageResult.setPage(query.getPage());
        pageResult.setPageSize(query.getLimit());
        return pageResult;
    }

    private String timeStampConversionToString(Long startTime) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date(startTime);
        return simpleDateFormat.format(date);
    }

    private void TotalPaymentAndMemberName(HashMap<Integer, String> map, MembersOrder mb, MembersOrderDto mbdto) {
        BigDecimal totalPayment = mbdto.getTotalPayment();
        List<Member> members = mb.getMembers();
        //设置时间段购买会员总金额和不同的会员名称
        if (CollectionUtil.isNotEmpty(members)) {
            mbdto.setMembers(members);
            for (Member member : members) {
                member.setMemberName(map.get(member.getLevel()));
                totalPayment = totalPayment.add(member.getAmount());
            }
        }
    }
}
