package com.tofly.xrtygis.custom.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.common.core.util.Date8Util;
import com.tofly.common.oauth.exception.ToflyDeniedException;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.xrtygis.custom.entity.dto.CostbgUnitDto;
import com.tofly.xrtygis.custom.mapper.PlanManagementMapper;
import com.tofly.xrtygis.custom.service.CustomUnitPlanService;
import com.tofly.xrtygis.custom.service.WaterMakingPlanService;
import com.tofly.xrtygis.custom.util.CommonMethod;
import com.tofly.xrtygis.entity.*;
import com.tofly.xrtygis.service.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 制水单耗计划
 *
 * @author 陈浩
 * @date 2021/3/18
 */
@Service
@AllArgsConstructor
public class CustomUnitPlanServiceImpl implements CustomUnitPlanService {

    private final CostbgunityearService costbgunityearService;

    private final CostbgunitService costbgunitService;

    private final CostbgindexService costbgindexService;

    private final CostbgindexyearService costbgindexyearService;

    private final CostbgwaterService costbgwaterService;

    private final CostbgpriceService costbgpriceService;

    private final CostbgwateryearService costbgwateryearService;

    private final PlanManagementMapper planManagementMapper;

    private final WaterMakingPlanService waterMakingPlanService;

    /**
     * 添加制水单耗计划
     *
     * @param year 年份
     * @return true
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertPlan(String year) {

        int size = costbgunityearService.list(Wrappers.<Costbgunityear>lambdaQuery()
                .eq(Costbgunityear::getYear, year)).size();

        if (size > 0) {
            throw new ToflyDeniedException("该计划已存在，如需重新创建，请删除" + year + "年计划");
        }

        Costbgunityear unityear = new Costbgunityear();
        unityear.setCreateTime(new Date());
        unityear.setCreateUser(SecurityUtils.getUserId());
        unityear.setState("0");
        unityear.setYear(year);

        return costbgunityearService.save(unityear);
    }

    /**
     * 添加制水单耗计划详情
     *
     * @param vo vo
     * @return true
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertPlanInfo(CostbgUnitDto vo) {
        List<Costbgunit> costbgunits = vo.getCostbgunits();

        if (costbgunits == null) {
            throw new ToflyDeniedException("单耗信息不能为空");
        }

        //获取计划表的id
        Costbgunityear unitYear = costbgunityearService.getOne(Wrappers.<Costbgunityear>lambdaQuery()
                .eq(Costbgunityear::getYear, vo.getYear()));

        Costbgwateryear waterYear = costbgwateryearService.getOne(Wrappers.<Costbgwateryear>lambdaQuery()
                .eq(Costbgwateryear::getYear, vo.getYear()));

        Costbgindexyear indexYear = costbgindexyearService.getOne(Wrappers.<Costbgindexyear>lambdaQuery()
                .eq(Costbgindexyear::getYear, vo.getYear()));

        if (null == unitYear) {
            throw new ToflyDeniedException(vo.getYear() + "年计划不存在");
        }
        costbgunits.forEach(units -> {
            //设置值
            units.setYearId(unitYear.getId());
            if (waterYear != null && "1".equals(waterYear.getState())) {
                Costbgwater water = costbgwaterService.getOne(Wrappers.<Costbgwater>lambdaQuery()
                        .select(Costbgwater::getZslOne, Costbgwater::getZslTwo, Costbgwater::getZslTotal)
                        .eq(Costbgwater::getYearId, waterYear.getId())
                        .eq(Costbgwater::getMonth, units.getMonth()));

                //总用电量
                if (water != null) {
                    units.setDhTotal(CommonMethod.newCalUnitPlan(units, water));
                    if (null != indexYear && "1".equals(indexYear.getState())) {

                        Costbgindex costbgindex = costbgindexService.getOne(Wrappers.<Costbgindex>lambdaQuery()
                                .eq(Costbgindex::getYearId, indexYear.getId())
                                .eq(Costbgindex::getMonth, units.getMonth()));
                        if (null != costbgindex) {
                            Costbgindex index = CommonMethod.newCalIndexPlan(water, units);
                            index.setId(costbgindex.getId());
                            costbgindexService.updateById(index);
                            units.setOtherOneDh(CommonMethod.divide(index.getOtherOne(), CommonMethod.multiply(water.getZslOne(), 10D)));
                            units.setOtherTwoDh(CommonMethod.divide(index.getOtherTwo(), CommonMethod.multiply(water.getZslTwo(), 10D)));
                        }
                    }
                }
            }
            costbgunitService.save(units);
        });

        costbgunityearService.update(Wrappers.<Costbgunityear>lambdaUpdate()
                .eq(Costbgunityear::getId, unitYear.getId())
                .set(Costbgunityear::getState, "1")
                .set(Costbgunityear::getOverTime, new Date()));
        return waterMakingPlanService.calculateWaterPlan(vo.getYear());
    }

    /**
     * 查看用户创建计划
     *
     * @param page  page
     * @param year  年份
     * @param state 状态
     * @return page
     */
    @Override
    public Page pagePlan(Page page, String year, String state) {
        return costbgunityearService.page(page, Wrappers.<Costbgunityear>lambdaQuery()
                .eq(year != null, Costbgunityear::getYear, year)
                .eq(state != null, Costbgunityear::getState, state)
                .orderByAsc(Costbgunityear::getYear));
    }

    /**
     * 查看用户创建计划详情
     *
     * @param id   计划id
     * @return page
     */
    @Override
    public Map<String, Object> pagePlanInfo(Long id) {
        Map<String, Object> result = new HashMap<>();
        Costbgunityear unitYear = costbgunityearService.getById(id);
        if (unitYear != null){
            result.put("info",planManagementMapper.getUnit(id));
            result.put("sum", planManagementMapper.getUnitSum(unitYear.getYear()));
        }
        return result;
    }

    /**
     * 删除计划
     *
     * @param id 计划id
     * @return true
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletePlan(String id) {
        List<String> strings = Arrays.asList(id.split(","));

        for (String string : strings) {
            Costbgunityear byId = costbgunityearService.getById(string);

            if (null == byId) {
                return false;
            }

            Costbgprice price = costbgpriceService.getOne(Wrappers.<Costbgprice>lambdaQuery()
                    .eq(Costbgprice::getYear, byId.getYear()));

            if (Integer.parseInt(byId.getYear()) < Date8Util.getYear() || null != price) {
                throw new ToflyDeniedException(byId.getYear() + "年份计划不允许删除");
            }

            if (!"0".equals(byId.getState())) {
                costbgunitService.remove(Wrappers.<Costbgunit>lambdaQuery()
                        .eq(Costbgunit::getYearId, string));
            }
        }

        return costbgunityearService.removeByIds(strings);
    }

    /**
     * 修改计划详情
     *
     * @param dto dto
     * @return true
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(CostbgUnitDto dto) {

        if (null == dto || dto.getCostbgunits() == null || dto.getCostbgunits().size() == 0) {
            throw new ToflyDeniedException("预算指标单耗填报信息不能为空");
        } else if (dto.getYear() == null) {
            throw new ToflyDeniedException("年份不能为空");
        }

        Costbgunityear unitYear = costbgunityearService.getOne(Wrappers.<Costbgunityear>lambdaQuery()
                .eq(Costbgunityear::getYear, dto.getYear()));
        if (null == unitYear) {
            throw new ToflyDeniedException(dto.getYear() + "年计划不存在");
        }

        List<Costbgunit> costbgunits = dto.getCostbgunits();

        Costbgwateryear waterYear = costbgwateryearService.getOne(Wrappers.<Costbgwateryear>lambdaQuery()
                .eq(Costbgwateryear::getYear, dto.getYear()));

        for (Costbgunit info : costbgunits) {
            if (null != waterYear) {
                Costbgwater water = costbgwaterService.getOne(Wrappers.<Costbgwater>lambdaQuery().eq(Costbgwater::getMonth, info.getMonth())
                        .eq(Costbgwater::getYearId, waterYear.getId()).select(Costbgwater::getZslOne, Costbgwater::getZslTwo, Costbgwater::getZslTotal));
                //修改预算指标单耗填报信息
                info.setDhTotal(CommonMethod.newCalUnitPlan(info, water));
            } else {
                info.setDhTotal(null);
            }
            costbgunitService.updateById(info);
            //查当前月份数据
            Costbgunit unit = costbgunitService.getById(info.getId());

            //得到年份水量和指标年份id
            Costbgwateryear wateryear = costbgwateryearService.getOne(Wrappers.<Costbgwateryear>lambdaQuery()
                    .eq(Costbgwateryear::getYear, unitYear.getYear()));

            Costbgindexyear indexyear = costbgindexyearService.getOne(Wrappers.<Costbgindexyear>lambdaQuery()
                    .eq(Costbgindexyear::getYear, unitYear.getYear()));

            if (wateryear != null && indexyear != null) {
                //查询对应月份水量计划
                Costbgwater water = costbgwaterService.getOne(Wrappers.<Costbgwater>lambdaQuery()
                        .eq(Costbgwater::getYearId, wateryear.getId())
                        .eq(Costbgwater::getMonth, info.getMonth()));

                if (water != null) {
                    Costbgindex index = CommonMethod.newCalIndexPlan(water, unit);

                    Costbgindex costbgindex = costbgindexService.getOne(Wrappers.<Costbgindex>lambdaQuery()
                            .eq(Costbgindex::getYearId, indexyear.getId()).eq(Costbgindex::getMonth, water.getMonth()));
                    index.setId(costbgindex.getId());
                    unit.setOtherOneDh(CommonMethod.divide(index.getOtherOne(), CommonMethod.multiply(water.getZslOne(), 10D)));
                    unit.setOtherTwoDh(CommonMethod.divide(index.getOtherTwo(), CommonMethod.multiply(water.getZslTwo(), 10D)));
                    costbgunitService.updateById(unit);
                    //修改指标
                    costbgindexService.updateById(index);
                }
            }

        }
        return waterMakingPlanService.calculateWaterPlan(dto.getYear());
    }
}
