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.CostbgFixedDto;
import com.tofly.xrtygis.custom.service.CustomFixedPlanService;
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.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 陈浩
 * @date 2021/3/22
 */
@Service
@AllArgsConstructor
public class CustomFixedPlanServiceImpl implements CustomFixedPlanService {

    private final CostbgfixedService costbgfixedService;

    private final CostbgfixedyearService costbgfixedyearService;

    private final CostbgwaterService costbgwaterService;

    private final CostbgwateryearService costbgwateryearService;

    private final CostbgpriceService costbgpriceService;

    private final CostbgindexyearService costbgindexyearService;

    private final CostbgindexService costbgindexService;

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

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

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

        return costbgfixedyearService.save(costbgfixedyear);
    }

    /**
     * 添加计划详情
     *
     * @param vo vo
     * @return true
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertPlanInfo(CostbgFixedDto vo) {
        List<Costbgfixed> costbgfixeds = vo.getCostbgfixeds();

        if (null == costbgfixeds) {
            throw new ToflyDeniedException("单变填报信息不能为空");
        }
        //获取各个记录表对应的id
        Long yearId = costbgfixedyearService.getOne(Wrappers.<Costbgfixedyear>lambdaQuery()
                .eq(Costbgfixedyear::getYear, vo.getYear())).getId();

        List<Costbgwateryear> waterList = costbgwateryearService.list(Wrappers.<Costbgwateryear>lambdaQuery()
                .eq(Costbgwateryear::getYear, vo.getYear())
                .ne(Costbgwateryear::getState, "0"))
                .stream()
                .filter(water -> water.getYear() != null)
                .collect(Collectors.toList());

        List<Costbgindexyear> indexList = costbgindexyearService.list(Wrappers.<Costbgindexyear>lambdaQuery()
                .eq(Costbgindexyear::getYear, vo.getYear())
                .ne(Costbgindexyear::getState, "0"))
                .stream()
                .filter(index -> index.getYear() != null).collect(Collectors.toList());

        for (Costbgfixed info : costbgfixeds) {
            if ((!waterList.isEmpty()) && !indexList.isEmpty()) {
                //获取相对应年份月份各个计划的值
                Costbgprice price = costbgpriceService.getOne(Wrappers.<Costbgprice>lambdaQuery()
                        .eq(Costbgprice::getYear, vo.getYear()));

                Costbgwater water = costbgwaterService.getOne(Wrappers.<Costbgwater>lambdaQuery()
                        .eq(Costbgwater::getYearId, waterList.get(0).getId()).eq(Costbgwater::getMonth, info.getMouth()));

                Costbgindex index = costbgindexService.getOne(Wrappers.<Costbgindex>lambdaQuery()
                        .eq(Costbgindex::getYearId, indexList.get(0).getId()).eq(Costbgindex::getMonth, info.getMouth()));

                //提取的公共方法计算单变
                Costbgfixed costbgfixed = CommonMethod.calFixedPlan(info, index, price, water);

                costbgfixed.setCreateTime(new Date());
                costbgfixed.setCreateUser(SecurityUtils.getUserId());
                costbgfixed.setYearId(yearId);

                costbgfixedService.save(costbgfixed);
            } else {
                info.setYearId(yearId);

                costbgfixedService.save(info);
            }
        }

        List<Costbgfixed> list = costbgfixedService.list(Wrappers.<Costbgfixed>lambdaQuery()
                .eq(Costbgfixed::getYearId, yearId)
                .select(Costbgfixed::getId));

        costbgfixedyearService.update(Wrappers.<Costbgfixedyear>lambdaUpdate()
                .eq(Costbgfixedyear::getId, yearId)
                .set(Costbgfixedyear::getOverTime, new Date())
                .set(list.size() < 12, Costbgfixedyear::getState, "2")
                .set(list.size() == 12, Costbgfixedyear::getState, "1"));

        return true;
    }

    /**
     * 删除计划
     *
     * @param id 计划id
     * @return true
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletePlan(String id) {
        List<String> idList = Arrays.asList(id.split(","));
        for (String s : idList) {
            Costbgfixedyear fixed = costbgfixedyearService.getById(s);

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

        return costbgfixedyearService.removeByIds(idList);
    }

    /**
     * 查看计划
     *
     * @param page  page
     * @param year  年份
     * @param state 状态
     * @return page
     */
    @Override
    public Page selectPlan(Page page, String year, String state) {
        return costbgfixedyearService.page(page, Wrappers.<Costbgfixedyear>lambdaQuery()
                .eq(year != null, Costbgfixedyear::getYear, year)
                .eq(state != null, Costbgfixedyear::getState, state)
                .orderByAsc(Costbgfixedyear::getYear));
    }
    /**
     * 修改计划
     *
     * @param costbgFixedDto vo
     * @return true of false
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePlanInfo(CostbgFixedDto costbgFixedDto) {
        List<Costbgfixed> costbgfixeds = costbgFixedDto.getCostbgfixeds();
        if (costbgfixeds.isEmpty()) {
            throw new ToflyDeniedException("预算制水单变填报信息不能为空");
        }

        for (Costbgfixed info : costbgfixeds) {
            costbgfixedService.updateById(info);

            Costbgfixed fixed = costbgfixedService.getById(info.getId());

            Costbgfixedyear fixedyear = costbgfixedyearService.getOne(Wrappers.<Costbgfixedyear>lambdaQuery()
                    .eq(Costbgfixedyear::getYear, fixed.getYearId()));

            if (fixedyear != null){
                Costbgwateryear waterYear = costbgwateryearService.getOne(Wrappers.<Costbgwateryear>lambdaQuery()
                        .eq(Costbgwateryear::getYear, fixedyear.getYear()));

                Costbgindexyear indexYear = costbgindexyearService.getOne(Wrappers.<Costbgindexyear>lambdaQuery()
                        .eq(Costbgindexyear::getYear, fixedyear.getYear()));
                if ( null != waterYear && null != indexYear) {
                    Costbgwater water = costbgwaterService.getOne(Wrappers.<Costbgwater>lambdaQuery()
                            .eq(Costbgwater::getYearId, waterYear.getId()).eq(Costbgwater::getMonth, fixed.getMouth()));

                    Costbgindex index = costbgindexService.getOne(Wrappers.<Costbgindex>lambdaQuery()
                            .eq(Costbgindex::getYearId, indexYear.getId()).eq(Costbgindex::getMonth, fixed.getMouth()));

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

                    if (null != water && null != index   && null != price) {
                        Costbgfixed costbgfixed = CommonMethod.calFixedPlan(fixed, index, price, water);

                        costbgfixedService.updateById(costbgfixed);
                    }
                }
            }
        }
        return true;
    }
}
