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.CostbgWaterDto;
import com.tofly.xrtygis.custom.mapper.PlanManagementMapper;
import com.tofly.xrtygis.custom.service.CustomWaterPlanService;
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-17
 */
@Service
@AllArgsConstructor
public class CustomWaterPlanServiceImpl implements CustomWaterPlanService {

    private final CostbgwateryearService costbgwateryearService;
    private final CostbgwaterService costbgwaterService;
    private final CostbgunityearService costbgunityearService;
    private final CostbgunitService costbgunitService;
    private final CostbgindexService costbgindexService;
    private final CostbgindexyearService costbgindexyearService;
    private final CostbgpriceService costbgpriceService;
    private final CostbgfixedyearService costbgfixedyearService;
    private final CostbgfixedService costbgfixedService;
    private final WaterMakingPlanService waterMakingPlanService;
    private final PlanManagementMapper planManagementMapper;

    /**
     * 新建年份计划
     *
     * @param year 年份
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertPlan(String year) {
        int size = costbgwateryearService.list(Wrappers.<Costbgwateryear>lambdaQuery()
                .eq(Costbgwateryear::getYear, year)).size();
        //判断是否存在多个year相同的记录
        if (size > 0) {
            throw new ToflyDeniedException("该计划已存在，请先删除重复计划");
        }
        //设置值
        Costbgwateryear costbgwateryear = new Costbgwateryear();
        costbgwateryear.setYear(year);
        costbgwateryear.setCreateTime(new Date());
        costbgwateryear.setState("0");
        costbgwateryear.setCreateUser(SecurityUtils.getUserId());

        return costbgwateryearService.save(costbgwateryear);
    }

    /**
     * 制水预算计划详情
     *
     * @param costbgwaters 预算水量记录信息表
     * @return true or false
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean fillInTheBudget(CostbgWaterDto costbgwaters) {

        List<Costbgwater> list = costbgwaters.getCostbgwater();
        if (list.isEmpty()) {
            throw new ToflyDeniedException("预算水量记录信息不能为空");
        }

        //根据年份查出其id
        Costbgwateryear costbg = costbgwateryearService.getOne(Wrappers.<Costbgwateryear>lambdaQuery()
                .eq(Costbgwateryear::getYear, costbgwaters.getYear()));

        for (Costbgwater tbg : list) {
            Costbgwater costbgwater = CommonMethod.calWaterPlan(tbg);
            //设置值
            costbgwater.setYearId(costbg.getId());
            costbgwater.setCreateTime(new Date());
            costbgwater.setCreateUser(SecurityUtils.getUserId());

            //增加
            costbgwaterService.save(costbgwater);
        }

        //添加完成后查询一次，用于判断是否填报完善
        List<Costbgwater> waterList = costbgwaterService.list(Wrappers.<Costbgwater>lambdaQuery()
                .eq(Costbgwater::getYearId, costbg.getId())
                .select(Costbgwater::getId));

        //当计划填报完成修改预算水量记录信息表部分信息
        costbgwateryearService.update(Wrappers.<Costbgwateryear>lambdaUpdate()
                .eq(Costbgwateryear::getId, costbg.getId())
                .set(waterList.size() < 12, Costbgwateryear::getState, "2")
                .set(waterList.size() == 12, Costbgwateryear::getState, "1")
                .set(Costbgwateryear::getOverTime, new Date()));
        return waterMakingPlanService.calculateWaterPlan(costbgwaters.getYear());
    }

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

    /**
     * 查看预算计划详情
     *
     * @param id 计划id
     * @return list
     */
    @Override
    public Map<String, Object> selectPlanInfo(Long id) {
        Map<String, Object> result = new HashMap<>();

        result.put("info", planManagementMapper.getWaterInfo(id));
        result.put("sum", planManagementMapper.getWaterSum(id));
        return result;
    }

    /**
     * 删除预算计划
     *
     * @param ids 计划id
     * @return true
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletePlan(String ids) {
        List<String> idsList = Arrays.asList(ids.split(","));
        for (String id : idsList) {
            Costbgwateryear costbgwateryear = costbgwateryearService.getById(id);

            List<Costbgprice> price = costbgpriceService.list(Wrappers.<Costbgprice>lambdaQuery()
                    .eq(Costbgprice::getYear, costbgwateryear.getYear()));

            if (Integer.parseInt(costbgwateryear.getYear()) < Date8Util.getYear() || !price.isEmpty()) {
                throw new ToflyDeniedException(costbgwateryear.getYear() + "年份计划不允许删除");
            }
            //已填报计划删除计划详情
            if (!"0".equals(costbgwateryear.getState())) {
                costbgwaterService.remove(Wrappers.<Costbgwater>lambdaQuery()
                        .eq(Costbgwater::getYearId, id));
            }
        }
        return costbgwateryearService.removeByIds(idsList);
    }

    /**
     * 修改预算计划详情
     *
     * @param costbgWaterDto vo
     * @return true
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePlanInfo(CostbgWaterDto costbgWaterDto) {

        if (null == costbgWaterDto) {
            throw new ToflyDeniedException("传入数据不能为空");
        }

        List<Costbgwater> list = costbgWaterDto.getCostbgwater();
        if (list.isEmpty()) {
            throw new ToflyDeniedException("预算水量记录信不能为空");
        }
        for (Costbgwater info : list) {
            //根据修改后的数据重新计算
            Costbgwater costbgwater = CommonMethod.calWaterPlan(info);
            //修改水量计划
            costbgwaterService.updateById(costbgwater);

            if (info.getGslOne() != null || info.getGslTwo() != null
                    || info.getZslOne() != null || info.getZslTwo() != null || info.getZslHqsk() != null) {
                //根据预算水量填报信息表id查出水量计划详细信息信息
                Costbgwater water = costbgwaterService.getById(info.getId());
                if (water == null) {
                    continue;
                }
                //查出年份id
                String year = costbgwateryearService.getById(water.getYearId()).getYear();
                //获取对应年份计划id
                Costbgunityear unitYear = costbgunityearService.getOne(Wrappers.<Costbgunityear>lambdaQuery()
                        .select(Costbgunityear::getId)
                        .eq(Costbgunityear::getYear, year));

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

                Costbgfixedyear fixedyear = costbgfixedyearService.getOne(Wrappers.<Costbgfixedyear>lambdaQuery()
                        .select(Costbgfixedyear::getId)
                        .eq(Costbgfixedyear::getYear, year));
                if (unitYear != null && indexyear != null) {
                    //对应年月计划内容
                    Costbgunit unit = costbgunitService.getOne(Wrappers.<Costbgunit>lambdaQuery()
                            .eq(Costbgunit::getYearId, unitYear.getId()).eq(Costbgunit::getMonth, water.getMonth()));
                    if (null == unit) {
                        continue;
                    }
                    //一厂指标
                    Double pacOne = CommonMethod.judge(CommonMethod.isNull(unit.getPacdhOne()) * CommonMethod.isNull(water.getZslOne()));
                    Double syOne = CommonMethod.judge(CommonMethod.isNull(unit.getSydhOne()) * CommonMethod.isNull(water.getZslOne()));
                    Double dldlOne = CommonMethod.judge(CommonMethod.isNull(unit.getDhOne()) * CommonMethod.isNull(water.getZslOne()));
                    //二厂指标
                    Double pacTwo = CommonMethod.judge(CommonMethod.isNull(unit.getPacdhTwo()) * CommonMethod.isNull(water.getGslTwo()));
                    Double yltwo = CommonMethod.judge(CommonMethod.isNull(unit.getYldhTwo()) * CommonMethod.isNull(water.getZslTwo()));
                    Double dldlTwo = CommonMethod.judge(CommonMethod.isNull(unit.getDhTwo()) * CommonMethod.isNull(water.getZslTwo()));
                    //总动力电量
                    Double dldlTotal = dldlOne + dldlTwo;
                    costbgindexService.update(Wrappers.<Costbgindex>lambdaUpdate()
                            .eq(Costbgindex::getYearId, indexyear.getId()).eq(Costbgindex::getMonth, water.getMonth())
                            .set(Costbgindex::getPacOne, pacOne).set(Costbgindex::getPacTwo, pacTwo)
                            .set(Costbgindex::getSyOne, syOne).set(Costbgindex::getYlTwo, yltwo)
                            .set(Costbgindex::getDldlOne, dldlOne).set(Costbgindex::getDldlTwo, dldlTwo)
                            .set(Costbgindex::getDldlTotal, dldlTotal));
                }

                if (indexyear != null && fixedyear != null) {
                    //更新后做一次查询
                    Costbgindex index = costbgindexService.getOne(Wrappers.<Costbgindex>lambdaQuery()
                            .eq(Costbgindex::getMonth, info.getMonth()).eq(Costbgindex::getYearId, indexyear.getId()));

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

                    Costbgfixed fixed = costbgfixedService.getOne(Wrappers.<Costbgfixed>lambdaQuery()
                            .eq(Costbgfixed::getMouth, water.getMonth()).eq(Costbgfixed::getYearId, indexyear.getId()));

                    Costbgfixed costbgfixed = CommonMethod.calFixedPlan(fixed, index, price, water);

                    costbgfixedService.updateById(costbgfixed);
                }
            }
        }
        return waterMakingPlanService.calculateWaterPlan(costbgWaterDto.getYear());
    }


}
