package com.foreverwin.mesnac.dispatch.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foreverwin.mesnac.dispatch.dto.ProductionCalendarDTO;
import com.foreverwin.mesnac.dispatch.dto.WorkCenterWorkTimeDTO;
import com.foreverwin.mesnac.dispatch.mapper.ProductionCalendarMapper;
import com.foreverwin.mesnac.dispatch.model.ProductionCalendar;
import com.foreverwin.mesnac.dispatch.service.ProductionCalendarService;
import com.foreverwin.modular.core.util.FrontPage;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * <p>
 * 生产日历  服务实现类
 * </p>
 *
 * @author syngna
 * @since 2020-08-18
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ProductionCalendarServiceImpl extends ServiceImpl<ProductionCalendarMapper, ProductionCalendar> implements ProductionCalendarService {


    @Autowired
    private ProductionCalendarMapper productionCalendarMapper;

    @Override
    public IPage<ProductionCalendar> selectPage(FrontPage<ProductionCalendar> frontPage, ProductionCalendar productionCalendar) {
        QueryWrapper<ProductionCalendar> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(productionCalendar);
        return super.page(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public List<ProductionCalendar> selectList(ProductionCalendar productionCalendar) {
        QueryWrapper<ProductionCalendar> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(productionCalendar);
        return super.list(queryWrapper);
    }

    /**
     * 根据站点、工作中心、年、月检索工作日历数据实现
     * @param site
     * @param workCenter
     * @param year
     * @param month
     * @return
     */
    @Override
    public List<ProductionCalendarDTO> listByWorkCenterYearMonth(String site, String workCenter, String year, String month) {
        return productionCalendarMapper.listByWorkCenterYearMonth(site, workCenter, year, month);
    }

    /**
     * 批量保存或更新
     * @param productionCalendarList
     * @return
     */
    @Override
    public boolean saveOrUpdateBatch(List<ProductionCalendar> productionCalendarList, int batchSize) {
        LocalDateTime now = LocalDateTime.now();
        Class<?> cls = currentModelClass();
        TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
        Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
        String keyProperty = tableInfo.getKeyProperty();
        Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
        try (SqlSession batchSqlSession = sqlSessionBatch()) {
            int i = 0;
            for (ProductionCalendar entity : productionCalendarList) {
                Object idVal = ReflectionKit.getMethodValue(cls, entity, keyProperty);
                if (StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal))) {
                    entity.setCreatedDateTime(now);
                    entity.setModifiedDateTime(now);
                    batchSqlSession.insert(sqlStatement(SqlMethod.INSERT_ONE), entity);
                } else {
                    MapperMethod.ParamMap<ProductionCalendar> param = new MapperMethod.ParamMap<>();
                    param.put(Constants.ENTITY, entity);
                    entity.setCreator(null);
                    entity.setCreatedDateTime(null);
                    entity.setModifiedDateTime(now);
                    batchSqlSession.update(sqlStatement(SqlMethod.UPDATE_BY_ID), param);
                }
                // 不知道以后会不会有人说更新失败了还要执行插入 😂😂😂
                if (i >= 1 && i % batchSize == 0) {
                    batchSqlSession.flushStatements();
                }
                i++;
            }
            batchSqlSession.flushStatements();
        }
        return true;
    }

    /**
     * 根据工作中心时间区间查找工作时段
     * @param site
     * @param workCenter
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public List<WorkCenterWorkTimeDTO> listWorkCenterWorkTimeByDateRange(String site, String workCenter, String startDate, String endDate) {
        return productionCalendarMapper.listWorkCenterWorkTimeByDateRange(site, workCenter, startDate, endDate);
    }

    /**
     * 根据时间区间查找所有设定的工作日历
     * @param site
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public List<WorkCenterWorkTimeDTO> listWorkTimeByRange(String site, String startDate, String endDate) {
        return productionCalendarMapper.listWorkTimeByRange(site, startDate, endDate);
    }

    /**
     * 根据工作中心时间区间查找工作时段
     * @param site
     * @param workCenterList
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public List<WorkCenterWorkTimeDTO> listWorkTime(String site, Set<String> workCenterList, String startDate, String endDate) {
        return productionCalendarMapper.listWorkTime(site, workCenterList, startDate, endDate);
    }
}