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.xrtygis.custom.entity.dto.CostbgIndexDto;
import com.tofly.xrtygis.custom.mapper.PlanManagementMapper;
import com.tofly.xrtygis.custom.service.CustomIndexPlanService;
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 CustomIndexPlanServiceImpl implements CustomIndexPlanService {

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

    private final PlanManagementMapper planManagementMapper;


    /**
     * 添加计划
     *
     * @param year 年
     * @return true
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertPlan(String year) {
        int size = costbgindexyearService.list(Wrappers.<Costbgindexyear>lambdaQuery().eq(Costbgindexyear::getYear, year)).size();

        if (size > 0) {
            throw new ToflyDeniedException("该年份计划已存在");
        }

        Costbgindexyear costbgindexyear = new Costbgindexyear();
        costbgindexyear.setYear(year);
        costbgindexyear.setState("0");

        return costbgindexyearService.save(costbgindexyear);
    }

    /**
     * 添加计划详情
     *
     * @param vo vo
     * @return true
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertPlanInfo(CostbgIndexDto vo) {
        List<Costbgindex> costbgindices = vo.getCostbgindices();
        if (costbgindices.isEmpty()) {
            throw new ToflyDeniedException("预算指标记录信息不能为空");
        }
        //预算水量记录信息id
        List<Costbgwateryear> waterYear = costbgwateryearService.list(Wrappers.<Costbgwateryear>lambdaQuery()
                .select(Costbgwateryear::getId)
                .eq(Costbgwateryear::getYear, vo.getYear()));

        //预算指标单耗记录信息id
        List<Costbgunityear> unitYear = costbgunityearService.list(Wrappers.<Costbgunityear>lambdaQuery()
                .select(Costbgunityear::getId)
                .eq(Costbgunityear::getYear, vo.getYear()));

        Costbgfixedyear fixedYear = costbgfixedyearService.getOne(Wrappers.<Costbgfixedyear>lambdaQuery()
                .eq(Costbgfixedyear::getYear, vo.getYear()));

        List<Costbgprice> costbgpriceList = costbgpriceService.list(Wrappers.<Costbgprice>lambdaQuery()
                .eq(Costbgprice::getYear, vo.getYear()).orderByDesc(Costbgprice::getCreateTime));


        Double jbdlOne = null;
        Double jbdlTwo = null;
        if (fixedYear != null && null != costbgpriceList && costbgpriceList.size() > 0) {
            Costbgprice price = costbgpriceList.get(0);
            Costbgfixed fixed = costbgfixedService.getOne(Wrappers.<Costbgfixed>lambdaQuery()
                    .select(Costbgfixed::getJbdfOne, Costbgfixed::getJbdfTwo)
                    .eq(Costbgfixed::getYearId, fixedYear.getId()).eq(Costbgfixed::getMouth, vo.getYear() + "-01"));
            if (fixed != null) {
                jbdlOne = CommonMethod.divide(CommonMethod.multiply(fixed.getJbdfOne(), 10000D), price.getJbdldjOne());
                jbdlTwo = CommonMethod.divide(CommonMethod.multiply(fixed.getJbdfTwo(), 10000D), price.getJbdldjTwo());
            }
        }
        //预算指标记录信息id
        Long indexId = costbgindexyearService.getOne(Wrappers.<Costbgindexyear>lambdaQuery()
                .select(Costbgindexyear::getId)
                .eq(Costbgindexyear::getYear, vo.getYear())).getId();

        for (Costbgindex index : costbgindices) {
            Costbgindex result = new Costbgindex();
            if (!waterYear.isEmpty() && unitYear != null && unitYear.size() > 0) {
                //预算水量填报信息
                Costbgwater water = costbgwaterService.getOne(Wrappers.<Costbgwater>lambdaQuery()
                        .eq(Costbgwater::getYearId, waterYear.get(0).getId())
                        .eq(Costbgwater::getMonth, index.getMonth()));
                if (water != null) {
                    //预算指标单耗填报信息
                    Costbgunit unit = costbgunitService.getOne(Wrappers.<Costbgunit>lambdaQuery()
                            .eq(Costbgunit::getYearId, unitYear.get(0).getId())
                            .eq(Costbgunit::getMonth, index.getMonth()));
                    result = CommonMethod.newCalIndexPlan(water, unit);
                }
            }

            result.setJbdlOne(jbdlOne);
            result.setJbdlTwo(jbdlTwo);
            result.setJbdlTotal((null == jbdlOne ? 0 : jbdlOne) + (null == jbdlTwo ? 0 : jbdlTwo));

            result.setMonth(index.getMonth());
            result.setBcs(index.getBcs());
            result.setCn(index.getCn());
            result.setFt(index.getFt());
            result.setGmsjfhy(index.getGmsjfhy());
            result.setOther(index.getOther());
            result.setPam(index.getPam());
            result.setPamWn(index.getPamWn());
            result.setWnzl(index.getWnzl());
            result.setYearId(indexId);
            costbgindexService.save(result);
        }
        //修改记录表值
        costbgindexyearService.update(Wrappers.<Costbgindexyear>lambdaUpdate()
                .eq(Costbgindexyear::getId, indexId)
                .set(Costbgindexyear::getState, "1")
                .set(Costbgindexyear::getOverTime, new Date()));
        return true;
    }

    /**
     * 查看计划
     *
     * @param page  page
     * @param year  year
     * @param state state
     * @return page
     */
    @Override
    public Page selectPlan(Page page, String year, String state) {
        return costbgindexyearService.page(page, Wrappers.<Costbgindexyear>lambdaQuery()
                .eq(year != null, Costbgindexyear::getYear, year)
                .eq(state != null, Costbgindexyear::getState, state)
                .orderByAsc(Costbgindexyear::getYear));
    }

    /**
     * 查看计划详情
     *
     * @param id id
     * @return page
     */
    @Override
    public Map<String, Object> selectPlanInfo(Long id) {
        Map<String, Object> result = new HashMap<>(2);
        result.put("info", planManagementMapper.getIndexInfo(id));
        result.put("sum", planManagementMapper.getIndexSum(id));
        return result;
    }

    /**
     * 删除计划
     *
     * @param id 年份
     * @return Boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletePlan(String id) {

        List<String> list = Arrays.asList(id.split(","));
        for (String s : list) {

            Costbgindexyear costbgindexyear = costbgindexyearService.getById(s);

            Costbgprice price = costbgpriceService.getOne(Wrappers.<Costbgprice>lambdaQuery()
                    .eq(Costbgprice::getYear, costbgindexyear.getYear()));
            if (Integer.parseInt(costbgindexyear.getYear()) < Date8Util.getYear() || null != price) {
                throw new ToflyDeniedException(costbgindexyear.getYear() + "年份计划不允许删除");
            }

            Costbgfixedyear fixedYear = costbgfixedyearService.getOne(Wrappers.<Costbgfixedyear>lambdaQuery()
                    .eq(Costbgfixedyear::getYear, costbgindexyear.getYear()));

            if (null != fixedYear) {
                if (!"0".equals(fixedYear.getState())) {
                    costbgfixedService.remove(Wrappers.<Costbgfixed>lambdaQuery().eq(Costbgfixed::getYearId, fixedYear.getId()));
                }
                costbgfixedyearService.removeById(fixedYear.getId());
            }

            if (!"0".equals(costbgindexyear.getState())) {
                costbgindexService.remove(Wrappers.<Costbgindex>lambdaQuery().eq(Costbgindex::getYearId, s));
            }
        }

        return costbgindexyearService.removeByIds(list);
    }

    /**
     * 修改指标信息
     *
     * @param costbgIndexDto vo
     * @return true or false
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePlanInfo(CostbgIndexDto costbgIndexDto) {
        List<Costbgindex> costbgindices = costbgIndexDto.getCostbgindices();
        if (costbgindices == null) {
            throw new ToflyDeniedException("指标信息不能为空");
        }

        for (Costbgindex info : costbgindices) {
            if (info != null) {
                //指标信息
                Costbgindex index = costbgindexService.getById(info.getId());
                if (index != null) {
                    //年份
                    String year = costbgindexyearService.getOne(Wrappers.<Costbgindexyear>lambdaQuery()
                            .eq(Costbgindexyear::getId, index.getYearId())).getYear();
                    //水量年份信息
                    Costbgwateryear waterYear = costbgwateryearService.getOne(Wrappers.<Costbgwateryear>lambdaQuery()
                            .eq(Costbgwateryear::getYear, year).ne(Costbgwateryear::getState, "0"));
                    //单变年份信息
                    Costbgfixedyear fixedYear = costbgfixedyearService.getOne(Wrappers.<Costbgfixedyear>lambdaQuery()
                            .eq(Costbgfixedyear::getYear, year).ne(Costbgfixedyear::getState, "0"));
                    //年份信息不为空，查询单价与单变信息
                    if (fixedYear != null) {
                        Costbgfixed fixed = costbgfixedService.getOne(Wrappers.<Costbgfixed>lambdaQuery()
                                .eq(Costbgfixed::getYearId, fixedYear.getId()).eq(Costbgfixed::getMouth, index.getMonth()));

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

                        //有该年份单价时，计算基本电量
                        if (price != null && !price.isEmpty()) {
                            Costbgprice pri = price.get(0);
                            Double jbdlOne = null;
                            Double jbdlTwo = null;
                            if (pri.getJbdldjOne() != null && fixed.getJbdfOne() != null) {
                                jbdlOne = CommonMethod.divide(CommonMethod.multiply(fixed.getJbdfOne(),10000D), pri.getJbdldjOne());
                                info.setJbdlOne(jbdlOne);
                            }
                            if (pri.getJbdldjTwo() != null && fixed.getJbdfTwo() != null) {
                                jbdlTwo = CommonMethod.divide(CommonMethod.multiply(fixed.getJbdfTwo(),10000D), pri.getJbdldjTwo());
                                info.setJbdlTwo(jbdlTwo);
                            }
                            if (jbdlOne != null || jbdlTwo != null) {
                                info.setJbdlTotal(CommonMethod.add(null == jbdlOne ? 0 : jbdlOne, null == jbdlTwo ? 0 : jbdlTwo));
                            }
                        }

                        if (null != waterYear) {
                            Costbgwater water = costbgwaterService.getOne(Wrappers.<Costbgwater>lambdaQuery()
                                    .eq(Costbgwater::getYearId, waterYear.getId()).eq(Costbgwater::getMonth, index.getMonth()));
                            if (price != null && !price.isEmpty()) {
                                Costbgfixed costbgfixed = CommonMethod.calFixedPlan(fixed, index, price.get(0), water);
                                costbgfixedService.updateById(costbgfixed);
                            }

                        }

                    }

                }

            }
            costbgindexService.updateById(info);
        }
        return true;
    }
}
