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

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foreverwin.mesnac.dispatch.mapper.ProductionDayTypeMapper;
import com.foreverwin.mesnac.dispatch.model.ProductionDayType;
import com.foreverwin.mesnac.dispatch.model.WorkShift;
import com.foreverwin.mesnac.dispatch.service.ProductionDayTypeService;
import com.foreverwin.mesnac.dispatch.service.WorkShiftService;
import com.foreverwin.modular.core.exception.BusinessException;
import com.foreverwin.modular.core.util.FrontPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLIntegrityConstraintViolationException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author syngna
 * @since 2020-08-18
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ProductionDayTypeServiceImpl extends ServiceImpl<ProductionDayTypeMapper, ProductionDayType> implements ProductionDayTypeService {


    @Autowired
    private ProductionDayTypeMapper productionDayTypeMapper;

    @Autowired
    private WorkShiftService workShiftService;

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

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

    @Override
    public boolean save(ProductionDayType productionDayType) {
        if (StrUtil.isBlank(productionDayType.getProductionDayType())) {
            throw BusinessException.build("工作日类型不能为空");
        }
        Date now = new Date();
        int count;
        try {
            productionDayType.setCreatedDateTime(now);
            productionDayType.setModifiedDateTime(now);
            count = baseMapper.insert(productionDayType);
        } catch (Exception e) {
            if (e instanceof SQLIntegrityConstraintViolationException || e instanceof DuplicateKeyException) {
                throw BusinessException.build("工作日类型'" + productionDayType.getProductionDayType() + "'已存在");
            } else {
                throw e;
            }
        }
        List<WorkShift> workShiftList = productionDayType.getWorkShiftList();
        if (workShiftList != null && workShiftList.size() > 0) {
            for (WorkShift workShift : productionDayType.getWorkShiftList()) {
                workShift.setHandle(WorkShift.genHandle(productionDayType.getSite(), productionDayType.getHandle(), workShift.getStartTime()));
                workShift.setSite(productionDayType.getSite());
                workShift.setProductionDayTypeBo(productionDayType.getHandle());
                workShift.setCreatedDateTime(now);
                workShift.setModifiedDateTime(now);
                workShift.setCreator(productionDayType.getCreator());
                workShift.setUpdater(productionDayType.getUpdater());
            }
            workShiftService.validateCrossSetting(workShiftList);
            workShiftService.saveBatch(workShiftList);
        }
        return retBool(count);
    }

    @Override
    public boolean updateById(ProductionDayType productionDayType) {
        if (StrUtil.isBlank(productionDayType.getProductionDayType())) {
            throw BusinessException.build("工作日类型不能为空");
        }
        int count;
        Date now = new Date();
        productionDayType.setModifiedDateTime(now);
        count = baseMapper.updateById(productionDayType);

        List<WorkShift> workShiftList = productionDayType.getWorkShiftList();
        List<String> workShiftHandleList = new ArrayList<>();
        if (workShiftList != null && workShiftList.size() > 0) {
            for (WorkShift workShift : productionDayType.getWorkShiftList()) {
                workShift.setHandle(WorkShift.genHandle(workShift.getSite(), productionDayType.getHandle(), workShift.getStartTime()));
                workShiftHandleList.add(workShift.getHandle());
                workShift.setSite(productionDayType.getSite());
                workShift.setProductionDayTypeBo(productionDayType.getHandle());
            }
            workShiftService.validateCrossSetting(workShiftList);
            for (WorkShift workShift : productionDayType.getWorkShiftList()) {
                workShift.setProductionDayTypeBo(productionDayType.getHandle());
                workShift.setModifiedDateTime(now);
                workShift.setUpdater(productionDayType.getUpdater());
                if (!workShiftService.updateById(workShift)) {
                    workShift.setCreator(workShift.getUpdater());
                    workShift.setCreatedDateTime(workShift.getModifiedDateTime());
                    workShiftService.save(workShift);
                }
            }
        }
        if(workShiftHandleList != null && workShiftHandleList.size() > 0) {
            workShiftService.remove(Wrappers.<WorkShift>lambdaQuery().eq(WorkShift::getProductionDayTypeBo, productionDayType.getHandle()).notIn(WorkShift::getHandle, workShiftHandleList));
        }
        return retBool(count);
    }
}