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 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.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.getUnitStart())) {
            criteria.eq("unit_start", vo.getUnitStart());
        }
        if (Objects.nonNull(vo.getUnitEnd())) {
            criteria.eq("unit_end", vo.getUnitEnd());
        }
        if (Objects.nonNull(vo.getPrefectureStart())) {
            criteria.eq("prefecture_start", vo.getPrefectureStart());
        }
        if (Objects.nonNull(vo.getPrefectureEnd())) {
            criteria.eq("prefecture_end", vo.getPrefectureEnd());
        }
        if (Objects.nonNull(vo.getProvinceStart())) {
            criteria.eq("province_start", vo.getProvinceStart());
        }
        if (Objects.nonNull(vo.getProvinceEnd())) {
            criteria.eq("province_end", vo.getProvinceEnd());
        }

        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 = 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();
            comBatch.setYear(dto.getYear());
            comBatch.setBatch(dto.getBatch());
            comBatch = this.getEntity(comBatch);
            if (null != comBatch)
                throw new BusinessException("年度批次已存在！");
        }
        ComBatch vo = convert2Entity(dto);
        return this.update(vo);
    }

    public Integer getMaxBatch(int year, Integer projType) {
        return comBatchDAO.getMaxBatch(year, projType);
    }

    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) {
        ComBatchDTO comBatch = this.getCurrentYearBatchByType(projType);
        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.getUnitStart(), comBatch.getUnitEnd());
                    comBatch.setDisabled(flag);
                    comBatch.setDescription(judgementDateTimeStr(date, comBatch.getUnitStart(), comBatch.getUnitEnd(), comBatch.getBatch(), comBatch.getYear()));
                    comBatch.setBtnPassed(!flag);
                    comBatch.setBtnReturn(!flag);
                    comBatch.setBtnUnpassed(false);
                    break;
                case 3://州市级行政单位审核时间(州市级行政单位项目上报省卫健委时间)
                    flag = judgementDateTimeDisabled(date, comBatch.getPrefectureStart(), comBatch.getPrefectureEnd());
                    comBatch.setDisabled(flag);
                    comBatch.setDescription(judgementDateTimeStr(date, comBatch.getPrefectureStart(), comBatch.getPrefectureEnd(), comBatch.getBatch(), comBatch.getYear()));
                    comBatch.setBtnPassed(!flag);
                    comBatch.setBtnReturn(true);
                    comBatch.setBtnUnpassed(false);
                    break;
                case 4://省直单位上报时间(省直单位项目上报省卫健委时间)
                    flag = judgementDateTimeDisabled(date, comBatch.getProvinceStart(), comBatch.getProvinceEnd());
                    comBatch.setDisabled(flag);
                    comBatch.setDescription(judgementDateTimeStr(date, comBatch.getProvinceStart(), comBatch.getProvinceEnd(), comBatch.getBatch(), comBatch.getYear()));
                    comBatch.setBtnPassed(!flag);
                    comBatch.setBtnReturn(!flag);
                    comBatch.setBtnUnpassed(false);
                    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.getCurrentYearBatchByType(projType);
        if (null != comBatch)
            return comBatch.getYear();
        else
            return 0;
    }

    public ComBatchDTO getCurrentYearBatchByType(Integer projType) {
        if (Objects.nonNull(projType))
            return comBatchDAO.getCurrentYearBatchByType(projType);
        else
            return comBatchDAO.getCurrentYearBatch();

    }

    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;
    }
}