package com.xxfc.platform.order.biz;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.db.PageResult;
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.google.common.collect.Maps;
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.collections.CollectionUtils;
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.ParseException;
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()).add(vehicle.getTotalReturnGmv())));
                setTotalOutstandingDeposit(vehicle.getTotalSecurityDeposit()
                        .subtract(vehicle.getTotalRefundSecurityDeposit())
                        .subtract(getAdditionalIndemnity()));
            }};
            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 List<MembersOrderDto> getMemberOrderStatistics(List<BaseUserMemberLevel> memberLevels, OrderQuery query) throws ParseException {

        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 {
            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;
                Integer time = null;
                if (OrderInquiryType.WEEK.getCode().equals(query.getType())) {
                    startDay = OrderDateUtils.getStartDayOfWeekNo(Integer.parseInt(periods[0]), Integer.parseInt(periods[1]));
                    endDay = OrderDateUtils.getEndDayOfWeekNo(Integer.parseInt(periods[0]), Integer.parseInt(periods[1]));
                    //获取今天是今年的第几周
                    time = OrderDateUtils.getTodayOfWeek();
                }
                Integer thisYear = OrderDateUtils.getThisYear();
                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]));
                    //获取今天是今年的第几个月
                    time = OrderDateUtils.getTodayOfMonth();
                }

                if (i == 0 && query.getStartTime() != null) {
                    startDay = OrderDateUtils.timeStampConversionToString(query.getStartTime());
                }
                //获取当前的年.周(年.月)小数
                double today = Double.parseDouble(thisYear + "." + time);

                if (i == (membersOrderList.size() - 1)) {
                    //查询到的最后一条数据年.周(年.月)小数
                    double date = Double.parseDouble(Integer.parseInt(periods[0]) + "." + Integer.parseInt(periods[1]));
                    if (date == today) {
                        endDay = OrderDateUtils.timeStampConversionToString(System.currentTimeMillis());
                    } else if (date < today) {
                        //获取最后一条数据,周末日期
                        Long end = OrderDateUtils.ConvertingStringsToTimestamps(endDay);
                        //查询的结束日期
                        Long endTime = query.getEndTime();
                        if (endTime != null && end > endTime) {
                            endDay = OrderDateUtils.timeStampConversionToString(query.getEndTime());
                        }
                    }
                }
                if (StringUtils.isNotBlank(startDay) && StringUtils.isNotBlank(endDay)) {
                    mbdto.setTimeSlot(startDay + "~" + endDay);
                } else {
                    mbdto.setTimeSlot("");
                }
                TotalPaymentAndMemberName(map, mb, mbdto);
                arrayList.add(mbdto);
            }
        }

        //进行分页处理

        return arrayList;

//        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 void TotalPaymentAndMemberName(HashMap<Integer, String> map, MembersOrder mb, MembersOrderDto mbdto) {

        BigDecimal totalPayment = BigDecimal.ZERO;
        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() == null ? BigDecimal.ZERO : member.getAmount());
            }
        }
        mbdto.setTotalPayment(totalPayment);
    }

    public Object downloadExcel() {


        return null;
    }

    public List<HashMap<Object, Object>> getRows(List<MembersOrderDto> list, List<BaseUserMemberLevel> memberLevels) {
        ArrayList<HashMap<Object, Object>> rows = Lists.newArrayList();
        for (MembersOrderDto membersOrderDto : list) {
            if (CollectionUtils.isEmpty(membersOrderDto.getMembers())) {
                continue;
            }
            HashMap<Object, Object> map = Maps.newLinkedHashMap();
            map.put("时间", membersOrderDto.getTimeSlot());
            for (BaseUserMemberLevel memberLevel : memberLevels) {
                setMap(membersOrderDto, map, memberLevel);
            }
            map.put("总支付金额", membersOrderDto.getTotalPayment());
            rows.add(map);
        }


        return rows;
    }

    private void setMap(MembersOrderDto membersOrderDto, HashMap<Object, Object> map, BaseUserMemberLevel memberLevel) {

        List<Member> collect = membersOrderDto.getMembers().parallelStream().filter(el -> el.getLevel().equals(memberLevel.getLevel())).collect(Collectors.toList());
        int number = 0;
        BigDecimal amount = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(collect)) {
            number = collect.get(0).getNumber();
            amount = collect.get(0).getAmount();
        }
        map.put(memberLevel.getName() + "购买量", number);
        map.put("支付金额(" + memberLevel.getName() + ")",amount);
    }
}
