package com.hys.app.service.erp.impl;

import com.hys.app.converter.erp.NoGenerateRuleConverter;
import com.hys.app.framework.database.WebPage;
import com.hys.app.framework.exception.ServiceException;
import com.hys.app.framework.database.mybatisplus.base.BaseServiceImpl;
import com.hys.app.mapper.erp.NoGenerateRuleMapper;
import com.hys.app.model.erp.dos.NoGenerateRuleDO;
import com.hys.app.model.erp.dto.NoGenerateRuleDTO;
import com.hys.app.model.erp.dto.NoGenerateRuleItem;
import com.hys.app.model.erp.dto.NoGenerateRuleQueryParams;
import com.hys.app.model.erp.enums.NoBusinessTypeEnum;
import com.hys.app.model.erp.enums.NoGenerateItemTypeEnum;
import com.hys.app.model.erp.vo.NoGenerateRuleVO;
import com.hys.app.service.erp.NoGenerateRuleManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 编号生成规则业务层实现
 *
 * @author 张崧
 * 2023-12-01 11:37:56
 */
@Service
public class NoGenerateRuleManagerImpl extends BaseServiceImpl<NoGenerateRuleMapper, NoGenerateRuleDO> implements NoGenerateRuleManager {

    @Autowired
    private NoGenerateRuleConverter converter;

    @Override
    public WebPage<NoGenerateRuleVO> list(NoGenerateRuleQueryParams queryParams) {
        WebPage<NoGenerateRuleDO> webPage = baseMapper.selectPage(queryParams);
        return converter.convert(webPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(NoGenerateRuleDTO noGenerateRuleDTO) {
        check(noGenerateRuleDTO);

        // 将该业务类型的其他规则关闭
        if (noGenerateRuleDTO.getOpenFlag()) {
            baseMapper.updateCloseByType(noGenerateRuleDTO.getType());
        }

        NoGenerateRuleDO generateRuleDO = converter.convert(noGenerateRuleDTO);
        // 初始化当前顺序号
        generateRuleDO.setCurrSeqNumber(generateRuleDO.getSeqBeginNumber());
        generateRuleDO.setSeqLastGenerateTime(new Date());

        save(generateRuleDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(NoGenerateRuleDTO noGenerateRuleDTO) {
        check(noGenerateRuleDTO);

        // 将该业务类型的其他规则关闭
        if (noGenerateRuleDTO.getOpenFlag()) {
            baseMapper.updateCloseByType(noGenerateRuleDTO.getType());
        }

        updateById(converter.convert(noGenerateRuleDTO));
    }

    @Override
    public NoGenerateRuleVO getDetail(Long id) {
        return converter.convert(getById(id));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> ids) {
        removeByIds(ids);
    }

    @Override
    public NoGenerateRuleDO getOpenRule(NoBusinessTypeEnum noBusinessTypeEnum) {
        return baseMapper.selectOpenRule(noBusinessTypeEnum);
    }

    @Override
    public Long getSeq(Long id, String formatDate) {
        return baseMapper.getSeq(id, formatDate, new Date());
    }

    private void check(NoGenerateRuleDTO noGenerateRuleDTO) {
        List<NoGenerateRuleItem> itemList = noGenerateRuleDTO.getItemList();

        if(itemList.stream().noneMatch(noGenerateRuleItem -> noGenerateRuleItem.getType() == NoGenerateItemTypeEnum.Const)){
            throw new ServiceException("必须包含常量规则");
        }

        List<NoGenerateItemTypeEnum> dateRule = Arrays.asList(NoGenerateItemTypeEnum.Year, NoGenerateItemTypeEnum.YearMonth, NoGenerateItemTypeEnum.YearMonthDay);
        if(itemList.stream().noneMatch(noGenerateRuleItem -> dateRule.contains(noGenerateRuleItem.getType()))){
            throw new ServiceException("必须包含日期规则的其中一种");
        }

        if(itemList.stream().noneMatch(noGenerateRuleItem -> noGenerateRuleItem.getType() == NoGenerateItemTypeEnum.Seq)){
            throw new ServiceException("必须包含顺序号规则");
        }
    }

}

