package com.ruoyi.zdsz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.DynamicName;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.handler.MonthTableNameHandler;
import com.ruoyi.zdsz.domain.ZEngineeringNode;
import com.ruoyi.zdsz.domain.bo.ZEngineeringInfoBo;
import com.ruoyi.zdsz.domain.bo.ZEngineeringNodeBo;
import com.ruoyi.zdsz.domain.bo.ZEngineeringReviewBo;
import com.ruoyi.zdsz.domain.vo.ZEngineeringNodeVo;
import com.ruoyi.zdsz.mapper.ZEngineeringNodeMapper;
import com.ruoyi.zdsz.service.IZEngineeringInfoService;
import com.ruoyi.zdsz.service.IZEngineeringNodeService;
import com.ruoyi.zdsz.service.IZEngineeringReviewService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static cn.hutool.core.date.DateUtil.format;

/**
 * 工程节点Service业务层处理
 *
 * @author ruoyi
 * @date 2023-12-27
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class ZEngineeringNodeServiceImpl implements IZEngineeringNodeService {

    private final ZEngineeringNodeMapper baseMapper;
    @Resource
    private IZEngineeringInfoService izEngineeringInfoService;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Resource
    private IZEngineeringReviewService izEngineeringReviewService;

    /**
     * 查询工程节点
     */
    @Override
    public ZEngineeringNodeVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    @Override
    @DynamicName(spel = "#bo.createTime")
//    @Async("threadPoolTaskExecutor")
    public ZEngineeringNodeBo query(ZEngineeringNodeBo bo){
        LambdaQueryWrapper<ZEngineeringNode> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getCivliId()), ZEngineeringNode::getCivliId, bo.getCivliId());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), ZEngineeringNode::getType, bo.getType());
        lqw.eq(ZEngineeringNode::getCreateBy, LoginHelper.getLoginUser().getUsername());
        ZEngineeringNode zEngineeringNode=baseMapper.selectOne(lqw);
//        ZEngineeringNode zEngineeringNodeVo=baseMapper.selectById(bo.getId());
        if (zEngineeringNode==null)
        {
             return  null;
        }
        ZEngineeringNodeBo zEngineeringNodeBo= BeanUtil.toBean(zEngineeringNode, ZEngineeringNodeBo.class);
        List<ZEngineeringInfoBo> zEngineeringInfoBo= izEngineeringInfoService.query(zEngineeringNodeBo);
        zEngineeringNodeBo.setzEngineeringInfoBoList(zEngineeringInfoBo);
        return zEngineeringNodeBo;
    }

    @Override
    @DynamicName(spel = "#bo.createTime")
    public List<ZEngineeringNodeBo> queryListDetails(ZEngineeringNodeBo bo) {
        LambdaQueryWrapper<ZEngineeringNode> lqw = buildQueryWrapper(bo);
        List<ZEngineeringNode> zEngineeringNode=baseMapper.selectList(lqw);
        List<ZEngineeringNodeBo> zEngineeringNodeBoList=new ArrayList<>();
        zEngineeringNode.stream().forEach(item->{
            ZEngineeringNodeBo zEngineeringNodeBo = BeanUtil.toBean(item, ZEngineeringNodeBo.class);
           List<ZEngineeringInfoBo> zEngineeringInfoBo= izEngineeringInfoService.query(zEngineeringNodeBo);
            zEngineeringNodeBo.setzEngineeringInfoBoList(zEngineeringInfoBo);
            zEngineeringNodeBoList.add(zEngineeringNodeBo);
        });
        return zEngineeringNodeBoList;
    }


    /**
     * 查询工程节点列表
     */
    @Override
    public TableDataInfo<ZEngineeringNodeVo> queryPageList(ZEngineeringNodeBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ZEngineeringNode> lqw = buildQueryWrapper(bo);
        Page<ZEngineeringNodeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询工程节点列表
     */
    @Override
//    @DynamicName(spel = "#bo.createTime")
    public List<ZEngineeringNodeVo> queryList(ZEngineeringNodeBo bo) {
        LambdaQueryWrapper<ZEngineeringNode> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ZEngineeringNode> buildQueryWrapper(ZEngineeringNodeBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ZEngineeringNode> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getCivliId()), ZEngineeringNode::getCivliId, bo.getCivliId());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), ZEngineeringNode::getType, bo.getType());
        return lqw;
    }
    @Override

    public String ZEngineeringReview(ZEngineeringNodeBo bo) {
        String userId=LoginHelper.getLoginUser().getUsername().toString();
        SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date(System.currentTimeMillis());
        List<String>dateList= getMonthBetweenDates("2021-12",formatter.format(date));
        dateList.stream().forEach(item->{
            Runnable runnable=new Runnable() {
                @Override
                public void run( ) {
                    try {
                        getZEngineeringNodeList(item,userId,bo);
                        Thread.sleep(30000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }

                }
            };
            threadPoolTaskExecutor.execute(runnable);
        });
        return null;
    }
    public  List getZEngineeringNodeList(String date,String UserId,ZEngineeringNodeBo bo)
    {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        List<ZEngineeringNodeVo> list= new ArrayList<>();
        try {
            Date startdate = format.parse(date);
            ZEngineeringNodeBo zEngineeringNodeBo=new ZEngineeringNodeBo();
            zEngineeringNodeBo.setCreateTime(startdate);
            zEngineeringNodeBo.setType(bo.getType());
            SimpleDateFormat format2 = new SimpleDateFormat("yyyy_MM");
            MonthTableNameHandler.setData(format2.format(startdate));
            try {
                list  =queryList(zEngineeringNodeBo);
            }catch (Exception e)
            {
                log.info("没有{}该表",format2.format(startdate));

                return null ;
            }
            List zEngineeringReviewList=new ArrayList<>();
            list.stream().forEach(item->{
                ZEngineeringReviewBo zEngineeringReview =new ZEngineeringReviewBo();
                zEngineeringReview.setReviewTime( new Date());
                zEngineeringReview.setReviewContent("批量审核");
                zEngineeringReview.setReviewStatus("1");
                zEngineeringReview.setReviewUser(UserId);
                zEngineeringReview.setEngInfoId(item.getId());
                zEngineeringReviewList.add(zEngineeringReview);

            });
            izEngineeringReviewService.insertBacth(zEngineeringReviewList);
            MonthTableNameHandler.removeData();
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        return list;

    }

    /**
     * 新增工程节点
     */
    @Override
    public Boolean insertByBo(ZEngineeringNodeBo bo) {
        ZEngineeringNode add = BeanUtil.toBean(bo, ZEngineeringNode.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }
    /**
     * 新增工程节点
     * @param bo
     * @return ZEngineeringNode
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    @DynamicName(spel = "#bo.createTime")
    public ZEngineeringNode insert(ZEngineeringNodeBo bo) {
        ZEngineeringNode add = BeanUtil.toBean(bo, ZEngineeringNode.class);
        validEntityBeforeSave(add);
        if (StringUtils.isEmpty(bo.getId())){
            boolean flag = baseMapper.insert(add) > 0;
            if (flag) {
                bo.setId(add.getId());
            }
        }
        bo.setUpdateTime(new Date());
        bo.getzEngineeringInfoBo().setEngInfoId(add.getId());
        bo.getzEngineeringInfoBo().setCreateTime(bo.getCreateTime());
        bo.getzEngineeringInfoBo().setUpdateTime(bo.getUpdateTime());
        izEngineeringInfoService.insert(bo.getzEngineeringInfoBo());
        return add;
    }



    /**
     * 修改工程节点
     */
    @Override
    public Boolean updateByBo(ZEngineeringNodeBo bo) {
        ZEngineeringNode update = BeanUtil.toBean(bo, ZEngineeringNode.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    @Override
    @DynamicName(spel = "#bo.createTime")
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(ZEngineeringNodeBo bo) {
        ZEngineeringNode update = BeanUtil.toBean(bo, ZEngineeringNode.class);
        validEntityBeforeSave(update);
        bo.getzEngineeringInfoBo().setCreateTime(bo.getCreateTime());
        izEngineeringInfoService.update(bo.getzEngineeringInfoBo());
        return baseMapper.updateById(update) > 0;
    }

    @Override
    @DynamicName(spel = "#bo.createTime")
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(ZEngineeringNodeBo bo) {
        LambdaQueryWrapper<ZEngineeringNode> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getId()), ZEngineeringNode::getId,bo.getId());
        ZEngineeringNode zEngineeringNode=baseMapper.selectOne(lqw);
        ZEngineeringNodeBo zEngineeringNodeBo = BeanUtil.toBean(zEngineeringNode, ZEngineeringNodeBo.class);
        izEngineeringInfoService.delete(zEngineeringNodeBo);
        return baseMapper.deleteById(bo.getId()) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ZEngineeringNode entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除工程节点
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }


    /**
     * 获取某个时间段内所有月份
     * @param minDate
     * @param maxDate
     * @return
     * @throws ParseException
     */
    public  List<String> getMonthBetweenDates(String minDate, String maxDate){
        ArrayList<String> result = new ArrayList<String>();
        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();
        min.setTime(parse(minDate,"yyyy-MM"));
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
        max.setTime(parse(maxDate,"yyyy-MM"));
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
        Calendar curr = min;
        while (curr.before(max)) {
            result.add(format(curr.getTime(),"yyyy-MM"));
            curr.add(Calendar.MONTH, 1);
        }
        return result;
    }
    public  Date parse(String date, String pattern) {
        try {
            return new SimpleDateFormat(pattern).parse(date);
        } catch (Exception e) {
        }
        return null;
    }
}
