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

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tofly.common.core.util.Date8Util;
import com.tofly.common.core.util.DateUtil;
import com.tofly.common.oauth.exception.ToflyDeniedException;
import com.tofly.xrtygis.custom.mapper.CosTprStationMapper;
import com.tofly.xrtygis.custom.mapper.FixedMapper;
import com.tofly.xrtygis.custom.mapper.WaterCostMapper;
import com.tofly.xrtygis.custom.service.CustomFixedService;
import com.tofly.xrtygis.custom.service.CustomWaterService;
import com.tofly.xrtygis.custom.util.CommonMethod;
import com.tofly.xrtygis.entity.*;
import com.tofly.xrtygis.entity.vo.FinanceIsAllowedVo;
import com.tofly.xrtygis.service.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author 20126
 */
@Service
@AllArgsConstructor
public class CustomFixedServiceImpl implements CustomFixedService {

    private final static String TABLE_NAME = "TF_YWPN_COSTRLFIXED_W";

    private final FixedMapper fixedMapper;
    private final WaterCostMapper waterCostMapper;
    private final CosTprStationMapper cosTprStationMapper;
    private final CostrlfixedService costrlfixedService;
    private final CostrlpriceService costrlpriceService;
    private final CustomWaterService customWaterService;
    private final CostcalcconfigService costcalcconfigService;
    private final CostrlwaterService costrlwaterService;
    private final CostrlunitService costrlunitService;


    /**
     * 填报制水单变
     *
     * @param fixed 实际制水单变填报信息
     * @return true of false
     */
    @Override
    public boolean insertFixed(Costrlfixed fixed) {

        if (null == fixed) {
            throw new ToflyDeniedException("制水单变填报信息不允许为空");
        }
        if ("1".equals(fixed.getMark())) {
            Long finance = cosTprStationMapper.isFinance(DateUtil.getDateFormat(fixed.getUpDate(), "yyyy-MM"), TABLE_NAME, null);

            if (null != finance) {
                throw new ToflyDeniedException("本月已进行财务填报");
            }
        } else {
            Long infoByDay = waterCostMapper.getInfoByDay(TABLE_NAME, DateUtil.getDateFormat(fixed.getUpDate(), "yyyy-MM-dd"), "0");
            if (null != infoByDay) {
                throw new ToflyDeniedException("该天已进行非财务填报");
            }
        }

        Costrlwater water = fixedMapper.selectWaterInfo(DateUtil.getDateFormat(fixed.getUpDate(), "yyyy-MM-dd"), fixed.getMark());

        Costrlprice price = costrlpriceService.getOne(Wrappers.<Costrlprice>lambdaQuery()
                .eq(Costrlprice::getYear, Date8Util.getYear())
                .eq(Costrlprice::getIsnew, "1"));

        return costrlfixedService.save(CommonMethod.countFixed(fixed, price, water));
    }

    /**
     * 删除制水单变
     *
     * @param ids id
     * @return true of false
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteFixed(String ids) {
        List<String> split = Arrays.asList(ids.split(","));
        for (String id : split) {
            Costrlfixed fixed = costrlfixedService.getById(id);
            if (fixed != null) {
                Integer waterId = fixedMapper.getWaterInfoId(fixed.getMark(), fixed.getUpDate());
                if (waterId != null) {
                    customWaterService.deleteWater(waterId.toString());
                }
            }
        }
        return costrlfixedService.removeByIds(split);
    }

    /**
     * 修改制水单变
     *
     * @param fixed 实际制水单变填报信息
     * @return true of false
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateFixed(Costrlfixed fixed) {
        Costrlfixed fixedById = costrlfixedService.getById(fixed.getId());

        Costrlwater water = fixedMapper.selectWaterInfo(DateUtil.getDateFormat(fixedById.getCreateTime(), "yyyy-MM-dd"), fixedById.getMark());
        if (null == water) {
            throw new ToflyDeniedException("未查询到制水指标对应信息");
        }

        Costrlprice price = costrlpriceService.getOne(Wrappers.<Costrlprice>lambdaQuery()
                .eq(Costrlprice::getYear, DateUtil.getDateFormat(fixedById.getCreateTime(), "yyyy"))
                .eq(Costrlprice::getIsnew, "1"));
        if (null == price) {
            throw new ToflyDeniedException("未查询到单价相关信息");
        }

        return costrlfixedService.updateById(CommonMethod.countFixed(fixed, price, water));
    }

    /**
     * 查看制水单变
     *
     * @param month 月份
     * @return map
     */
    @Override
    public Map<String, Object> selectFixed(String month) {
        Map<String, Object> map = new HashMap<>(4);
        Costcalcconfig config = costcalcconfigService.getById(1);

        Date yeatMonth = DateUtil.formatDate(month, "yyyy-MM");
        DateTime dateTime = cn.hutool.core.date.DateUtil.offsetMonth(yeatMonth, -1);
        String format = cn.hutool.core.date.DateUtil.format(dateTime, "yyyy-MM");

        String start = format + "-" + config.getStartDate();
        String end = month + "-" + config.getEndDate();
        //查询预算值
        map.put("fixedPlan", fixedMapper.viewFixedPlan(month));
        //查询财务填报
        map.put("finance", fixedMapper.viewFinance(month));

        map.put("sumFixed", fixedMapper.viewSumFixed(start, end));

        map.put("fixed", fixedMapper.viewFixed(start, end));

        return map;
    }

    /**
     * 获取日填报的月用水总量
     *
     * @param month 月份
     * @return list
     */
    @Override
    public List<Map<String, Double>> sumWater(String month) {
        if (StringUtils.isEmpty(month)) {
            throw new ToflyDeniedException("月份不能为空");
        }
        //获取配置信息配置的起止算一个月
        Costcalcconfig config = costcalcconfigService.getById(1);
        Date yeatMonth = DateUtil.formatDate(month, "yyyy-MM");
        DateTime dateTime = cn.hutool.core.date.DateUtil.offsetMonth(yeatMonth, -1);
        String format = cn.hutool.core.date.DateUtil.format(dateTime, "yyyy-MM");

        String start = format + "-" + config.getStartDate();
        String end = month + "-" + config.getEndDate();

        return waterCostMapper.sumWaterCost(start, end);
    }

    /**
     * 财务填报
     */
    @Override
    public boolean financeIsAllowed(FinanceIsAllowedVo vo) {
        Costcalcconfig config = costcalcconfigService.getById(1);

        Date upDate = vo.getUpDate();

        DateTime start = cn.hutool.core.date.DateUtil.beginOfMonth(upDate);
        DateTime end = cn.hutool.core.date.DateUtil.endOfMonth(upDate);

        Long count = fixedMapper.existFinanceIsAllowed(upDate, config.getStartDate(), config.getEndDate());

        Costrlwater waterInfo = costrlwaterService.getOne(Wrappers.<Costrlwater>lambdaQuery()
                .between(Costrlwater::getUpDate, start, end).eq(Costrlwater::getMark, 1));

        Costrlunit unitInfo = costrlunitService.getOne(Wrappers.<Costrlunit>lambdaQuery()
                .between(Costrlunit::getUpDate, start, end).eq(Costrlunit::getMark, 1));

        Costrlfixed fixedInfo = costrlfixedService.getOne(Wrappers.<Costrlfixed>lambdaQuery()
                .between(Costrlfixed::getUpDate, start, end).eq(Costrlfixed::getMark, 1));

        Costrlwater costrlwater = JSONObject.parseObject(JSONObject.toJSONString(vo), Costrlwater.class);
        Costrlwater water = CommonMethod.calWater(costrlwater);
        if (waterInfo != null) {
            water.setId(waterInfo.getId());
            costrlwaterService.updateById(water);
        } else {
            if (count == 1) {
                throw new ToflyDeniedException("该月已进行财务填报");
            }
            //总量
            costrlwaterService.save(water);
        }

        //单耗
        Costrlunit unit = CommonMethod.newCalUnit(water);
        unit.setMark("1");
        if (unitInfo != null) {
            unit.setId(unitInfo.getId());
            costrlunitService.updateById(unit);
        } else {
            costrlunitService.save(unit);
        }

        Costrlfixed fixed = CommonMethod.newCalFixed(JSONObject.parseObject(JSONObject.toJSONString(vo), Costrlfixed.class), water);
        if (fixedInfo != null) {
            fixed.setId(fixedInfo.getId());
            costrlfixedService.updateById(fixed);
        } else {
            costrlfixedService.save(fixed);
        }
        return true;
    }

    @Override
    public List<Map> getFillInTheMessage(String month) {
        return fixedMapper.getFillInTheMessage(month);
    }


}
