package com.yiboshi.science.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiboshi.arch.exception.BusinessException;
import com.yiboshi.science.base.BaseServiceImpl;
import com.yiboshi.science.base.Pagination;
import com.yiboshi.science.config.bean.SystemProperties;
import com.yiboshi.science.config.security.SecurityUserHolder;
import com.yiboshi.science.dao.ComBatchDAO;
import com.yiboshi.science.entity.ComBatch;
import com.yiboshi.science.enumeration.CommonEnum;
import com.yiboshi.science.param.dto.ComBatchDTO;
import com.yiboshi.science.param.query.ComBatchQueryVO;
import com.yiboshi.science.service.ComBatchService;
import com.yiboshi.science.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 菜单权限表 Service 实现类
 *
 * @author lkl
 * @version 2021-08-26
 */
@Service
public class ComBatchServiceImpl extends BaseServiceImpl<ComBatchDAO, ComBatchQueryVO, ComBatchDTO, ComBatch> implements ComBatchService {

    @Autowired
    private ComBatchDAO comBatchDAO;

    private final SystemProperties properties;

    public ComBatchServiceImpl(SystemProperties properties) {
        this.properties = properties;
    }

    @Override
    protected void setCriteriaForQuery(ComBatchQueryVO vo, QueryWrapper<ComBatchQueryVO> criteria) {
        if (Objects.nonNull(vo.getYear())) {
            criteria.eq("year", vo.getYear());
        }
        if (Objects.nonNull(vo.getBatch())) {
            criteria.eq("batch", vo.getBatch());
        }
        if (Objects.nonNull(vo.getTimeType())) {
            criteria.eq("time_type", vo.getTimeType());
        }
        if (Objects.nonNull(vo.getProjType())) {
            criteria.eq("proj_type", vo.getProjType());
        }
        if (Objects.nonNull(vo.getReportStart())) {
            criteria.eq("report_start", vo.getReportStart());
        }
        if (Objects.nonNull(vo.getReportEnd())) {
            criteria.eq("report_end", vo.getReportEnd());
        }
        if (Objects.nonNull(vo.getExpertStart())) {
            criteria.eq("expert_start", vo.getReportStart());
        }
        if (Objects.nonNull(vo.getExpertEnd())) {
            criteria.eq("expert_end", vo.getExpertEnd());
        }
        if (Objects.nonNull(vo.getRemark())) {
            criteria.eq("remark", vo.getRemark());
        }
    }

    @Override
    public Pagination<ComBatchDTO> getListByPage(ComBatchQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        Page<ComBatchQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComBatchDTO> dtoList = comBatchDAO.getListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public List<ComBatchDTO> getBatchList(ComBatch entity) {
        return this.dtoList(entity);
    }

    public ComBatchDTO getBatchById(String id) {
        return this.dtoById(id);
    }

    public String addBatch(ComBatchDTO dto) {
        ComBatch batch = new ComBatch();
        batch.setYear(dto.getYear());
        batch.setBatch(dto.getBatch());
        batch.setProjType(dto.getProjType());
        batch.setTimeType(dto.getTimeType());
        batch = this.getEntity(batch);
        if (null != batch)
            throw new BusinessException("年度批次已存在！");
        ComBatch e = convert2Entity(dto);
        return this.insert(e);
    }

    public String updateBatch(ComBatchDTO dto) {
        ComBatch batch = this.getById(dto.getId());
        if (null == batch)
            throw new BusinessException("批次不存在或已删除！");
        if (!dto.getYear().equals(batch.getYear()) || !dto.getBatch().equals(batch.getBatch())) {
            ComBatch comBatch = new ComBatch();
            batch.setYear(dto.getYear());
            batch.setBatch(dto.getBatch());
            batch.setProjType(dto.getProjType());
            batch.setTimeType(dto.getTimeType());
            comBatch = this.getEntity(comBatch);
            if (null != comBatch)
                throw new BusinessException("年度批次已存在！");
        }
        ComBatch vo = convert2Entity(dto);
        return this.update(vo);
    }

    public String deleteBatch(String id) {
        ComBatchDTO dto = this.dtoById(id);
        String msg = "";
        if (dto == null)
            return "年度批次不存在！";
        Integer batchCount = 0;
        if (batchCount == 0) {
            ComBatch vo = convert2Entity(dto);
            if (delete(vo))
                msg = "年度批次删除成功！";
            else
                msg = "年度批次删除失败，请稍后再试！";
        } else {
            msg = "该年度批次存在项目，不能删除！";
        }
        return msg;
    }

    /**
     * 获取当前申报或审核时间
     *
     * @param type     1:项目申报时间 2:州市级及以下单位上报时间 3:州市级行政单位审核时间 4:省直单位上报时间 5:专家评审时间
     * @param projType 1.科研项目申报  2.重点项目申报
     * @return
     */
    public ComBatchDTO getCurrentYearBatch(int type, Integer projType, Integer timeType) {
        ComBatchDTO comBatch = this.getCurrentBatch(projType, timeType);
        Date date = new Date();// 获取当前时间
        boolean flag = false;
        if (null != comBatch) {
            switch (type) {
                case 1://项目申报时间(所有申报人项目上报单位时间)
                    comBatch.setDisabled(judgementDateTimeDisabled(date, comBatch.getReportStart(), comBatch.getReportEnd()));
                    comBatch.setDescription(judgementDateTimeStr(date, comBatch.getReportStart(), comBatch.getReportEnd(), comBatch.getBatch(), comBatch.getYear()));
                    break;
                case 2:// 审核时间
                    flag = judgementDateTimeDisabled(date, comBatch.getAuditStart(), comBatch.getAuditEnd());
                    comBatch.setDisabled(flag);
                    comBatch.setDescription(judgementDateTimeStr(date, comBatch.getAuditStart(), comBatch.getAuditEnd(), comBatch.getBatch(), comBatch.getYear()));
                    break;
                case 5://专家评审时间
                    comBatch.setDisabled(judgementDateTimeDisabled(date, comBatch.getExpertStart(), comBatch.getExpertEnd()));
                    comBatch.setDescription(judgementDateTimeStr(date, comBatch.getExpertStart(), comBatch.getExpertEnd(), comBatch.getBatch(), comBatch.getYear()));
                    break;
            }
        } else {
            comBatch = new ComBatchDTO();
            comBatch.setDisabled(false);
            comBatch.setDescription(type == 1 ? "未设置填报时间！" : "未设置审核时间！");
        }
        if (SecurityUserHolder.getUnitCode().length() == properties.getDefaultCodeLength()
                && !SecurityUserHolder.getRoles().contains(CommonEnum.systemRole.expert.getCode().toString())) {
            comBatch.setDisabled(true);
            comBatch.setDescription("");
        }
        return comBatch;
    }

    public Integer getReportYear(Integer projType) {
        ComBatchDTO comBatch = this.getCurrentBatch(projType, null);
        if (null != comBatch)
            return comBatch.getYear();
        else
            return 0;
    }

    public ComBatchDTO getCurrentBatch(Integer projType, Integer timeType) {
        if (Objects.isNull(timeType))
            timeType = 1;
        return comBatchDAO.getCurrentBatch(projType, timeType);
    }

    private String judgementDateTimeStr(Date currentDate, Date startDate, Date endDate, int Batch, Integer year) {
        String result = "";
        SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd");
        String start = time.format(startDate);
        String end = time.format(endDate);
        if (currentDate.before(startDate)) {
            result = start + "--" + end + "（" + year + "年,第" + Batch + "批次）,时间未到";
        } else if (currentDate.after(endDate)) {
            result = start + "--" + end + "（" + year + "年,第" + Batch + "批次）,已过期";
        } else {
            result = start + "--" + end + "（" + year + "年,第" + Batch + "批次）";
        }
        return result;
    }

    /**
     * 判断时间范围，在时间范围内:true,在时间范围外:false
     *
     * @param currentDate 当前时间
     * @param startDate   开始时间
     * @param endDate     结束时间
     * @return
     */
    private boolean judgementDateTimeDisabled(Date currentDate, Date startDate, Date endDate) {
        boolean flag = false;
        if (currentDate.before(startDate)) {
            flag = false;
        } else if (currentDate.after(endDate)) {
            flag = false;
        } else {
            flag = true;
        }
        return flag;
    }
}