package cn.wise.sc.acquisition.business.service.impl;

import cn.wise.sc.acquisition.business.constant.Rcode;
import cn.wise.sc.acquisition.business.entity.TProcessesBlastdesignHole;
import cn.wise.sc.acquisition.business.entity.TProcessesDrilling;
import cn.wise.sc.acquisition.business.enumation.ProjectEnum;
import cn.wise.sc.acquisition.business.mapper.TProcessesDrillingMapper;
import cn.wise.sc.acquisition.business.model.query.*;
import cn.wise.sc.acquisition.business.model.vo.TProcessesBlastdesignHoleVo;
import cn.wise.sc.acquisition.business.model.vo.TProcessesDrillingVo;
import cn.wise.sc.acquisition.business.model.vo.TProcessesProductVo;
import cn.wise.sc.acquisition.business.service.*;
import cn.wise.sc.acquisition.business.util.BeanUtilsNewCopy;
import cn.wise.sc.acquisition.business.util.DateUtil;
import cn.wise.sc.acquisition.business.wrapper.page.Query;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Stack;

/**
 * <p>
 * 服务实现类 穿孔工序
 * </p>
 *
 * @author renchao
 * @since 2021-04-29
 */
@Service
@Slf4j
public class TProcessesDrillingServiceImpl extends ServiceImpl<TProcessesDrillingMapper, TProcessesDrilling> implements ITProcessesDrillingService {


    @Autowired
    private ITSysDictService itSysDictService;

    @Autowired
    private ITMineStopeService itMineStopeService;

    @Autowired
    private ITProcessesBlastdesignHoleService itProcessesBlastdesignHoleService;

    @Autowired
    private ITProcessesBlastdesignVolumeService itProcessesBlastdesignVolumeService;

    @Autowired
    private ITProcessesBlastService itProcessesBlastService;

    @Override
    public R getPage(TProcessesDrillingQuery tProcessesDrillingQuery, Query query) {
        log.info(JSON.toJSONString(tProcessesDrillingQuery));
        //参数校验
        //分页
        Page<TProcessesDrilling> page = new Page<>(query.getPageNum(), query.getPageSize());
        //条件封装
        QueryWrapper<TProcessesDrilling> queryWrapper = new QueryWrapper<>();
        StringBuffer drillingDate = new StringBuffer()
                .append(ProjectEnum.TableAlias.B.getLabel())
                .append(ProjectEnum.TProcessesDrilling.DRILLING_DATE.getLabel());
        //如果设计时间不为空 因为涉及到表连接，需要创建字段别名
        if (tProcessesDrillingQuery.getDrillingDate() != null) {
            //前端传来的时间可能为2021-04-05 17:37:33.000, 需要查询 2021-04-05 00:00:00 到 2021-04-05 23:59:59 的数据 故作处理
            queryWrapper
                    .ge(drillingDate.toString(), DateUtil.getBeginTimeStr(tProcessesDrillingQuery.getDrillingDate()))
                    .le(drillingDate.toString(), DateUtil.getEndTimeStr(tProcessesDrillingQuery.getDrillingDate()));
        }

        //查询分页数据
        Page<TProcessesDrillingVo> data = baseMapper.getPage(page, queryWrapper);
        StringBuffer depth = new StringBuffer()
                .append(ProjectEnum.TableAlias.A.getLabel())
                .append(ProjectEnum.TProcessesDrilling.DEPTH.getLabel());
        //查询，合计孔深
        Double depthSum = baseMapper.getSumByCondition(depth.toString(), queryWrapper);

        //查询，今日合计孔深
        //初始化QueryWrapper
        LocalDateTime now = LocalDateTime.now();
        queryWrapper = new QueryWrapper<>();
        queryWrapper
                .ge(drillingDate.toString(), DateUtil.getBeginTimeStr(now))
                .le(drillingDate.toString(), DateUtil.getEndTimeStr(now));

        Double todayDepthSum = baseMapper.getSumByCondition(depth.toString(), queryWrapper);


        //查询，本月合计孔深 上月26日到当前日期的实测孔深相加
        //初始化QueryWrapper
        queryWrapper = new QueryWrapper<>();
        queryWrapper
                .ge(drillingDate.toString(), DateUtil.getBeginTimeStr(LocalDateTime.now().minusMonths(1).withDayOfMonth(26)))
                .le(drillingDate.toString(), DateUtil.getEndTimeStr(LocalDateTime.now()));

        Double monthDepthSum = baseMapper.getSumByCondition(depth.toString(), queryWrapper);
        return R.ok(new TProcessesProductVo<>(data, depthSum, todayDepthSum, monthDepthSum));
    }

    @Override
    public R insertTProcessesDrilling(TProcessesDrillingQuery query) {
        log.info(JSON.toJSONString(query));
        //参数校验
        Rcode.NOT_PARAM.assertNotNull(query);
        //tag不能添加
        if (StringUtils.isNotBlank(query.getTag())) {
            return R.failed("穿孔工序中->tag标注日期自动生成，不能添加");
        }
        //条件封装
        TProcessesDrilling tProcessesDrilling = new TProcessesDrilling();
        BeanUtils.copyProperties(query, tProcessesDrilling);
        //设置tag
        R r1 = itSysDictService.getTagDate(null);
        if (r1.getCode() != 0) {
            return R.failed(r1.getMsg());
        }
        tProcessesDrilling.setTag((String) r1.getData());
        //增加
        int insert = baseMapper.insert(tProcessesDrilling);
        if (insert > 0) {
            return R.ok("穿孔工序中->增加成功");
        } else {
            log.error("穿孔工序中->增加失败,{}", JSON.toJSONString(tProcessesDrilling));
            return R.failed("穿孔工序中->增加失败");
        }
    }


    @Override
    public R updateByUid(TProcessesDrillingQuery query) {
        log.info(JSON.toJSONString(query));
        //参数校验
        Rcode.NOT_PARAM.assertNotNull(query);
        Rcode.NOT_PARAM.assertNotNull(query.getUid());
        //判断数据是否存在
        TProcessesDrilling temp = baseMapper.selectById(query.getUid());
        if (temp == null) {
            return R.failed("穿孔工序中->数据不存在：uid: " + query.getUid());
        }
        //不能修改炮孔编号
        if (StringUtils.isNotBlank(query.getHoleID())) {
            return R.failed("穿孔工序中->不能修改炮孔编号");
        }
        //不能修改tag
        if (StringUtils.isNotBlank(query.getTag())) {
            return R.failed("穿孔工序中->tag标注日期自动生成，不能修改");
        }
        //条件封装
        BeanUtilsNewCopy.copyPropertiesIgnoreNull(query, temp);
        //判断是否需要修改关联的 矿山爆区表
        if (StringUtils.isNotBlank(query.getStepName())
                || StringUtils.isNotBlank(query.getBlastAreaName())
                || StringUtils.isNotBlank(query.getStopeName())) {
            return R.failed("穿孔工序中->请到炮孔设计中修改爆区名称，采区名称，平台名称");
            //判断矿山爆区表是否存在数据 不存在不能修改
            //query里不一定StopeName,StepName,BlastAreaName都有，需要从temp中拿query没有的，
            // 所以将query有的更新到temp中，再把temp中的复制到tMineStopeQuery
//            TMineStopeQuery tMineStopeQuery = new TMineStopeQuery();
//            BeanUtils.copyProperties(temp, tMineStopeQuery);
//            R volume = itMineStopeService.getByQuery(tMineStopeQuery);
//            if (volume.getData() == null) {
//                return R.failed("穿孔工序中->矿山爆区表数据不存在，StopeName,StepName,BlastAreaName");
//            }
        }
        //判断是否修改设计爆区爆破量  设计爆区爆破量(m3)  TAT
        if (query.getBlastVolume() != null) {
            return R.failed("穿孔工序中->请到炮孔设计中修改设计爆区爆破量");
//            TProcessesBlastdesignVolumeQuery tProcessesBlastdesignVolumeQuery = new TProcessesBlastdesignHoleQuery();
//            tProcessesBlastdesignVolumeQuery.setStopeName(temp.getStopeName());
//            tProcessesBlastdesignVolumeQuery.setStepName(temp.getStepName());
//            tProcessesBlastdesignVolumeQuery.setBlastAreaName(temp.getBlastAreaName());
//            tProcessesBlastdesignVolumeQuery.setBlastVolume(query.getBlastVolume());
//            R r = itProcessesBlastdesignVolumeService.updateByQuery(tProcessesBlastdesignVolumeQuery);
//            if (r.getCode() != 0) {
//                log.info("穿孔工序中->修改设计爆区爆破量失败:{}", JSON.toJSONString(tProcessesBlastdesignVolumeQuery));
//                return R.failed(r.getMsg());
//            }
        }
        //判断是否修改炮孔设计
        if (query.getDesignDepth() != null
                || query.getDesignRowSpace() != null
                || query.getDesignHoleSpace() != null
                || query.getDesignAzimuth() != null
                || query.getDesignInclination() != null
                || query.getDesignAperture() != null
                || query.getStepHeight() != null) {
            return R.failed("穿孔工序中->不能在穿孔工序中修改炮孔设计字段信息：DesignDepth，DesignRowSpace，DesignHoleSpace，DesignAzimuth，DesignInclination，DesignAperture，StepHeight");
//            TProcessesBlastdesignHoleQuery holeQuery = new TProcessesBlastdesignHoleQuery();
//            holeQuery.setBlastHoleID(temp.getHoleID());
//            holeQuery.setDepth(query.getDesignDepth());
//            holeQuery.setRowSpace(query.getDesignRowSpace());
//            holeQuery.setHoleSpace(query.getDesignHoleSpace());
//            holeQuery.setAzimuth(query.getAzimuth());
//            holeQuery.setInclination(query.getDesignInclination());
//            holeQuery.setAperture(query.getDesignAperture());
//            holeQuery.setStepHeight(query.getStepHeight());
//            R r = itProcessesBlastdesignHoleService.updateByBlastHoleID(holeQuery);
//            if (r.getCode() != 0) {
//                log.error("修改炮孔设计失败：{}", JSON.toJSONString(holeQuery));
//                return R.failed(r.getMsg());
//            }

        }

        //判断是否需要重新计算爆破量
        if (query.getHoleSpace() != null || query.getRowSpace() != null) {
            //计算单孔爆破量
            //先获取炮孔设计数据台阶高度
            TProcessesBlastdesignHoleQuery holeQuery = new TProcessesBlastdesignHoleQuery();
            holeQuery.setUid(temp.getUid());
            R r = itProcessesBlastdesignHoleService.getByUid(holeQuery);
            //不为空计算单孔爆破量
            if (r.getData() != null) {
                TProcessesBlastdesignHoleVo data = (TProcessesBlastdesignHoleVo) r.getData();
                Double volume = calculateHoleBlastVolume(temp.getHoleSpace(), temp.getRowSpace(), data.getStepHeight());
                temp.setHoleBlastVolume(volume);
            } else {
                log.info("穿孔工序中->计算单孔爆破量时，获取炮孔设计为空，炮孔编号：{}", temp.getUid());
            }
        }

        QueryWrapper<TProcessesDrilling> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(query.getUid()), ProjectEnum.TProcessesDrilling.UID.getLabel(), query.getUid());
        //修改
        int update = baseMapper.update(temp, queryWrapper);
        if (update > 0) {
            return R.ok("穿孔工序中->修改成功");
        } else {
            log.error("穿孔工序中->修改失败:{}", JSON.toJSONString(temp));
            return R.failed("穿孔工序中->修改失败");
        }
    }


    @Override
    public R updateHoleBlastVolume(TProcessesDrillingQuery query) {
        log.info(JSON.toJSONString(query));
        //参数校验
        Rcode.NOT_PARAM.assertNotNull(query);
        Rcode.NOT_PARAM.assertNotNull(query.getUid());
        Rcode.NOT_PARAM.assertNotNull(query.getStepHeight());
        //判断数据是否存在
        QueryWrapper<TProcessesDrilling> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ProjectEnum.TProcessesBlast.UID.getLabel(), query.getUid());
        TProcessesDrilling temp = baseMapper.selectOne(queryWrapper);
        if (temp == null) {
            return R.failed("穿孔工序中->数据不存在：HOLE_ID: " + query.getHoleID());
        }
        //计算设计区爆破量
        Double volume = calculateHoleBlastVolume(temp.getHoleSpace(), temp.getRowSpace(), query.getStepHeight());
        temp.setHoleBlastVolume(volume);
        int update = baseMapper.updateById(temp);
        if (update > 0) {
            return R.ok("穿孔工序中->修改成功");
        } else {
            log.error("穿孔工序中->修改失败:{}", JSON.toJSONString(temp));
            return R.failed("穿孔工序中->修改失败");
        }
    }

    @Override
    public R getByUid(TProcessesDrillingQuery query) {
        log.info(JSON.toJSONString(query));
        //参数校验
        Rcode.NOT_PARAM.assertNotNull(query);
        Rcode.NOT_PARAM.assertNotEmpty(query.getUid());
        //查询并且返回
        QueryWrapper<TProcessesDrilling> queryWrapper = new QueryWrapper<>();
        StringBuilder uid = new StringBuilder();
        uid.append(ProjectEnum.TableAlias.A.getLabel()).append(ProjectEnum.TProcessesDrilling.UID.getLabel());
        queryWrapper.eq(uid.toString(), query.getUid());
        //查询并且返回
        return R.ok(baseMapper.getByQuery(queryWrapper));
    }


    @Override
    public R updateAllBlastDate(TProcessesDrillingQuery query) {
        log.info(JSON.toJSONString(query));
        //参数校验
        Rcode.NOT_PARAM.assertNotNull(query);
        Rcode.NOT_PARAM.assertNotNull(query.getBlastDate());
        //封装条件
        QueryWrapper<TProcessesDrilling> queryWrapper = new QueryWrapper<>();
        //封装实体
        TProcessesDrilling tProcessesDrilling = new TProcessesDrilling();
        tProcessesDrilling.setBlastDate(query.getBlastDate());
        int update = baseMapper.update(tProcessesDrilling, queryWrapper);
        if (update > 0) {
            return R.ok("穿孔工序中->修改爆破日期成功");
        } else {
            log.error("穿孔工序中->修改爆破日期失败:{}", JSON.toJSONString(tProcessesDrilling));
            return R.failed("穿孔工序中->修改爆破日期失败");
        }
    }

    /**
     * 计算并设值 单孔爆破量(m3)=孔距*排距*台阶高度
     */
    private Double calculateHoleBlastVolume(Double HoleSpace, Double RowSpace, Double StepHeight) {
        return HoleSpace * RowSpace * StepHeight;
    }

}
