package com.fjhx.applet.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.applet.mapper.InkStatisticsMapper;
import com.fjhx.applet.service.InkStatisticsService;
import com.fjhx.base.BaseEntity;
import com.fjhx.entity.stock.StockInoutbill;
import com.fjhx.utils.Assert;
import org.springblade.core.log.exception.ServiceException;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class InkStatisticsServiceImpl extends ServiceImpl<InkStatisticsMapper, BaseEntity> implements InkStatisticsService {

    @Override
    public Map<String, Object> selectInkStatistics() {
        //查询明细
        List<Map<String, Object>> maps = baseMapper.selectInkStatistics();

        Map<String, Object> detailsMap = new HashMap<>();
        if (maps.size() > 0) {
            //计算合计件数
            int total = maps.stream().mapToInt(map -> Integer.parseInt(map.get("count").toString())).sum();

            //计算合计数量
            BigDecimal amountQuantity = maps.stream().map(map -> new BigDecimal(map.get("quantity").toString())).reduce(BigDecimal.ZERO, BigDecimal::add);

            //计算合计金额
            BigDecimal amountTotal = maps.stream().map(map -> new BigDecimal(map.get("amount").toString())).reduce(BigDecimal.ZERO, BigDecimal::add);
            detailsMap.put("total", total);
            detailsMap.put("amountQuantity", amountQuantity);
            detailsMap.put("amountTotal", amountTotal);
        } else {
            detailsMap.put("total", 0);
            detailsMap.put("amountQuantity", 0);
            detailsMap.put("amountTotal", 0);
        }
        detailsMap.put("details", maps);
        return detailsMap;
    }

    @Override
    public Map<String, Object> selectInkW(Map<String, Object> condition) {
        Object ewType = condition.get("EWType");
        Assert.notEmpty(ewType, "出入库参数：EWType不能为null");

        QueryWrapper<Object> wrapper = getDateWrapper(condition);

        if (Integer.parseInt(ewType.toString()) == 1) {
            wrapper.in("swd.StockChangeType", 20, 23);
        } else if (Integer.parseInt(ewType.toString()) == 2) {
            wrapper.in("swd.StockChangeType", 10, 13);
        } else {
            throw new ServiceException("检查参数EWType：只能传1或者2");
        }

        wrapper.eq("m.TechnologyType", 3);
        wrapper.groupBy("sh.`Name`");
        List<Map<String, Object>> maps = baseMapper.selectInkW(wrapper);

        return encapsulationResult(maps);
    }

    @Override
    public Map<String, Object> selectInkEWDetails(Map<String, Object> condition) {
        QueryWrapper<Object> wrapper = getDateWrapper(condition);
        wrapper.eq("m.TechnologyType", 3);
        wrapper.groupBy("u.RealName");
        wrapper.orderByDesc("changeNum");
        List<Map<String, Object>> maps = baseMapper.selectInkEWDetails(wrapper);
        return encapsulationResult(maps);
    }

    private Map<String, Object> encapsulationResult(List<Map<String, Object>> maps) {
        Map<String, Object> detailsMap = new HashMap<>();
        if (maps.size() > 0) {
            //计算合计件数
            int total = maps.stream().mapToInt(map -> Integer.parseInt(map.get("count").toString())).sum();

            //计算合计数量
            BigDecimal amountQuantity = maps.stream().map(map -> new BigDecimal(map.get("changeNum").toString())).reduce(BigDecimal.ZERO, BigDecimal::add);

            //计算合计金额
            BigDecimal amountTotal = maps.stream().map(map -> new BigDecimal(map.get("amount").toString())).reduce(BigDecimal.ZERO, BigDecimal::add);
            detailsMap.put("total", total);
            detailsMap.put("amountQuantity", amountQuantity);
            detailsMap.put("amountTotal", amountTotal);
        } else {
            detailsMap.put("total", 0);
            detailsMap.put("amountQuantity", 0);
            detailsMap.put("amountTotal", 0);
        }
        detailsMap.put("details", maps);
        return detailsMap;
    }

    /**
     * 获取时间段查询
     *
     * @param condition 条件
     * @return
     */
    private static QueryWrapper<Object> getDateWrapper(Map<String, ?> condition) {
        if (ObjectUtil.isAllEmpty(condition.get("type"), condition.get("beginTime"), condition.get("endTime"))) {
            throw new ServiceException("日期不能为空");
        }
        int type = Integer.parseInt(condition.get("type").toString());
        Date date = new Date();
        Date beginDate;
        Date endDate;

        switch (type) {
            case 0: // 本日
                beginDate = DateUtil.beginOfDay(date);
                endDate = DateUtil.endOfDay(date);
                break;
            case 1: // 昨日
                beginDate = DateUtil.beginOfDay(DateUtil.offsetDay(date, -1));
                endDate = DateUtil.endOfDay(DateUtil.offsetDay(date, -1));
                break;
            case 2: // 本周
                beginDate = DateUtil.beginOfWeek(date);
                endDate = DateUtil.endOfWeek(date);
                break;
            case 3:  // 上周
                beginDate = DateUtil.beginOfWeek(DateUtil.offsetWeek(date, -1));
                endDate = DateUtil.endOfWeek(DateUtil.offsetWeek(date, -1));
                break;
            case 4: // 本月
                beginDate = DateUtil.beginOfMonth(date);
                endDate = DateUtil.endOfMonth(date);
                break;
            case 5: // 上月
                beginDate = DateUtil.beginOfMonth(DateUtil.offsetMonth(date, -1));
                endDate = DateUtil.endOfMonth(DateUtil.offsetMonth(date, -1));
                break;
            default: // 自定义
                beginDate = DateUtil.parse(condition.get("beginTime").toString());
                endDate = DateUtil.parse(condition.get("endTime").toString());
        }

        return Wrappers.query().between("swd.CreatedTime", beginDate, endDate);
    }

}
