package com.fjhx.service.v3.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.base.Condition;
import com.fjhx.constants.DetpIdConstant;
import com.fjhx.entity.v3.V3PlanStatistics;
import com.fjhx.mapper.v3.V3PlanStatisticsMapper;
import com.fjhx.params.v3.V3PlanStatisticsEx;
import com.fjhx.service.v3.V3PlanStatisticsService;
import com.fjhx.service.water.WaterBackService;
import com.fjhx.utils.BigDecimalUtil;
import com.fjhx.utils.HxBeanUtil;
import com.fjhx.utils.UserClientUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2022-10-31
 */
@Service
public class V3PlanStatisticsServiceImpl extends ServiceImpl<V3PlanStatisticsMapper, V3PlanStatistics> implements V3PlanStatisticsService {

    @Autowired
    private WaterBackService waterBackService;

    @Override
    public Map<String, JSONObject> userStatistics(Condition condition) {
        Date beginTime = condition.getBeginTime();
        Date endTime = condition.getEndTime();

        Map<String, JSONObject> userByAppointDept = waterBackService.getUserByAppointDept();

        List<V3PlanStatistics> planList = list(Wrappers.<V3PlanStatistics>lambdaQuery()
                .between(V3PlanStatistics::getPlanDate, beginTime, endTime));

        Map<Long, List<V3PlanStatistics>> collect = planList.stream().collect(Collectors.groupingBy(V3PlanStatistics::getUserId));

        for (JSONObject json : userByAppointDept.values()) {
            JSONArray list = json.getJSONArray("list");

            for (int i = 0; i < list.size(); i++) {
                JSONObject userItem = (JSONObject) list.get(i);

                List<V3PlanStatistics> v3PlanStatisticsList = collect.get(userItem.getLong("id"));
                if (list.size() > 0) {
                    BigDecimal planArea = BigDecimal.ZERO;
                    BigDecimal pickingArea = BigDecimal.ZERO;
                    BigDecimal backArea = BigDecimal.ZERO;

                    for (V3PlanStatistics item : v3PlanStatisticsList) {
                        planArea = planArea.add(item.getPlanArea());
                        pickingArea = pickingArea.add(item.getPickingArea()).add(item.getTransferInArea());
                        backArea = backArea.add(item.getBackArea()).add(item.getTransferOutArea());
                    }

                    // 赋值使用率
                    BigDecimal value = BigDecimalUtil.init(planArea).divideTry(pickingArea.subtract(backArea), 4)
                            .multiply(100).getValue();

                    userItem.put("useRate", value);

                } else {
                    userItem.put("useRate", BigDecimal.ZERO);
                }
            }
        }
        return userByAppointDept;
    }

    @Override
    public V3PlanStatisticsEx statisticsDetails(Condition condition) {

        V3PlanStatisticsEx result = new V3PlanStatisticsEx();

        QueryWrapper<V3PlanStatistics> wrapper = getWrapper(condition);
        List<V3PlanStatistics> list = list(wrapper);

        for (V3PlanStatistics item : list) {
            result.setPlanArea(result.getPlanArea().add(item.getPlanArea()));
            result.setPickingMoney(result.getPickingMoney().add(item.getPickingMoney()));
            result.setPickingNum(result.getPickingNum() + item.getPickingNum());
            result.setPickingMeters(result.getPickingMeters().add(item.getPickingMeters()));
            result.setPickingArea(result.getPickingArea().add(item.getPickingArea()));
            result.setBackMoney(result.getBackMoney().add(item.getBackMoney()));
            result.setBackNum(result.getBackNum() + item.getBackNum());
            result.setBackMeters(result.getBackMeters().add(item.getBackMeters()));
            result.setBackArea(result.getBackArea().add(item.getBackArea()));
            result.setTransferInArea(result.getTransferInArea().add(item.getTransferInArea()));
            result.setTransferOutArea(result.getTransferOutArea().add(item.getTransferOutArea()));
        }

        return result;
    }

    @Override
    public Page<V3PlanStatisticsEx> statisticsPage(Condition condition) {

        QueryWrapper<V3PlanStatistics> wrapper = getWrapper(condition);
        wrapper.lambda().groupBy(Arrays.asList(V3PlanStatistics::getUserId, V3PlanStatistics::getPlanMaterial));
        wrapper.select(
                "user_id",
                "plan_material",
                "sum(plan_area) planArea",
                "sum(picking_money) pickingMoney",
                "sum(picking_num) pickingNum",
                "sum(picking_meters) pickingMeters",
                "sum(picking_area) pickingArea",
                "sum(back_money) backMoney",
                "sum(back_num) backNum",
                "sum(back_meters) backMeters",
                "sum(back_area) backArea",
                "sum(transfer_in_area) transferInArea",
                "sum(transfer_out_area) transferOutArea"
        );

        Page<V3PlanStatistics> page = page(condition, wrapper);

        Page<V3PlanStatisticsEx> result = HxBeanUtil.copyPageEx(page, V3PlanStatisticsEx.class);
        List<V3PlanStatisticsEx> records = result.getRecords();
        if (records.size() == 0) {
            return result;
        }

        Map<Long, String> userNameMap = UserClientUtil.getUserNameMap(records, V3PlanStatistics::getUserId);
        for (V3PlanStatisticsEx record : records) {
            record.setUserName(userNameMap.get(record.getUserId()));
        }

        return result;
    }

    private QueryWrapper<V3PlanStatistics> getWrapper(Condition condition) {
        Date beginTime = condition.getBeginTime();
        Date endTime = condition.getEndTime();
        Long userId = condition.getUserId();
        QueryWrapper<V3PlanStatistics> query = Wrappers.query();

        query.lambda()
                .between(ObjectUtil.isAllNotEmpty(beginTime, endTime), V3PlanStatistics::getPlanDate, beginTime, endTime)
                .func(q -> {
                    if (ObjectUtil.isNotEmpty(userId)) {
                        q.eq(V3PlanStatistics::getUserId, userId);
                    } else {
                        List<Long> jobNoList = waterBackService.getUserIdByAppointDept(
                                DetpIdConstant.JET_PRINT, DetpIdConstant.TYPING, DetpIdConstant.TRANSFER);
                        q.in(V3PlanStatistics::getUserId, jobNoList);
                    }
                });

        return query;
    }

}
