package com.shkj.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shkj.common.constant.UserConstants;
import com.shkj.common.core.domain.Result;
import com.shkj.wms.bo.BasRuleBo;
import com.shkj.wms.domain.BasRule;
import com.shkj.wms.domain.BasRuleDetail;
import com.shkj.wms.domain.BaseAutoCode;
import com.shkj.wms.mapper.BasRuleDetailMapper;
import com.shkj.wms.mapper.BasRuleMapper;
import com.shkj.wms.mapper.BaseAutoCodeMapper;
import com.shkj.wms.service.IBasRuleDetailService;
import com.shkj.wms.service.IBasRuleService;
import com.shkj.wms.vo.BasRuleVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 编码规则Service业务层处理
 *
 * @author j.liang
 * @date 2022-12-08
 */
@Slf4j
@Service
public class BasRuleServiceImpl extends ServiceImpl<BasRuleMapper, BasRule> implements IBasRuleService {
    public static ThreadLocal<Boolean> threadLocal = new ThreadLocal<>();


    @Autowired
    BasRuleMapper basRuleMapper;

    @Autowired
    IBasRuleDetailService iBasRuleDetailService;

    @Autowired
    BasRuleDetailMapper basRuleDetailMapper;

    @Autowired
    BaseAutoCodeMapper baseAutoCodeMapper;

    /**
     * 查询编码规则
     */
    @Override
    public BasRule queryById(Long ruleId) {
        return basRuleMapper.selectById(ruleId);
    }

    /**
     * 查询编码规则列表
     */
    @Override
    public List<BasRuleVo> queryPageList(BasRuleBo bo) {
        return basRuleMapper.selectRuleList(bo);
    }

    @Override
    public List<BasRuleVo> queryList(BasRuleBo bo) {
        return null;
    }


    private LambdaQueryWrapper<BasRule> buildQueryWrapper(BasRuleBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<BasRule> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getRuleName()), BasRule::getRuleName, bo.getRuleName()).or();
        lqw.like(StringUtils.isNotBlank(bo.getRuleName()), BasRule::getRuleNum, bo.getRuleName());
        lqw.eq(StringUtils.isNotBlank(bo.getDescription()), BasRule::getDescription, bo.getDescription());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), BasRule::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增编码规则
     */
    @Override
    public Result<Boolean> insertBasRuleByBo(BasRuleBo bo) {

        Boolean aBoolean = checkNameUnique(bo);
        if (aBoolean){
           return Result.err().msg("规则编码或名称已存在");
        }

        BasRule add = BeanUtil.toBean(bo, BasRule.class);

        boolean flag = baseMapper.insert(add) > 0;
        if (bo.getList() != null) {
            for (int i = 0; i < bo.getList().size(); i++) {
                bo.getList().get(i).setRuleId(add.getRuleId());
            }
            if (flag) {
                bo.setRuleId(add.getRuleId());
                iBasRuleDetailService.saveBatchRuleDetail(bo.getList());
            }
        }
        if (flag) {
            bo.setRuleId(add.getRuleId());
        }

        return Result.ok();
    }

    /**
     * 修改编码规则
     */
    @Override
    public Boolean updateByBo(BasRuleBo bo) {
        BasRule update = BeanUtil.toBean(bo, BasRule.class);

        boolean flag = baseMapper.updateById(update) > 0;
        for (int i = 0; i < bo.getList().toArray().length; i++) {
            bo.getList().get(i).setRuleId(update.getRuleId());
        }
        if (flag) {
            bo.setRuleId(update.getRuleId());
            flag = iBasRuleDetailService.saveOrUpdateBatch(bo.getList());
        }
        return flag;
    }


    /**
     * 删除编码规则
     */
    @Override
    public Boolean deleteWithValidById(Long id) {
        BasRuleDetail basRule = new BasRuleDetail();
        basRule.setRuleId(id);
        LambdaQueryWrapper<BasRuleDetail> lqw = selectBasRuleDetail(basRule);
        //查询字表有没有数据
        List<BasRuleDetail> details = basRuleDetailMapper.selectList(lqw);
        //如果有数据就删除字表数据，没有就跳过
        if (details.size() != 0) {
            basRuleDetailMapper.deleteBatchIds(details);
        }
        return baseMapper.deleteById(id) > 0;
    }

    private LambdaQueryWrapper<BasRuleDetail> selectBasRuleDetail(BasRuleDetail bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<BasRuleDetail> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getRuleId() != null, BasRuleDetail::getRuleId, bo.getRuleId());
        return lqw;
    }

    /**
     * 保存前的数据校验
     */
    @Override
    public Boolean checkNameUnique(BasRuleBo basRuleBo) {

        LambdaQueryWrapper<BasRule> wrapper = new LambdaQueryWrapper<BasRule>()
                .eq(BasRule::getRuleNum, basRuleBo.getRuleNum())
                .eq(BasRule::getRuleName, basRuleBo.getRuleName());
        BasRule one = getOne(wrapper);
        if (one !=null){
            return true;
        }

        return false;
    }

    /**
     * 校验删除编码规则信息
     */
    @Override
    public String checkNameStatus(Collection<Long> ids) {
        List<BasRule> basRules = baseMapper.selectBatchIds(ids);
        //判断客户是否停用
        for (int i = 0; i < basRules.size(); i++) {
            System.out.println(basRules.get(i).getStatus());
            while (basRules.get(i).getStatus().equals("1")) {
                return UserConstants.NOT_UNIQUE;
            }
        }
        return UserConstants.UNIQUE;

    }

    /**
     * 修改编码规则状态
     */
    @Override
    public Boolean updateStatus(BasRule basRule) {
        return baseMapper.updateById(basRule) > 0;
    }

    /**
     * 自动生成业务编号
     */
    synchronized
    public String genSerialCode(String ruleCode, String inputCharacter) {
        List<BasRuleVo> basRule = baseMapper.selectRuleOne(ruleCode);
        Assert.notNull(basRule, "未获取到指定类型:[{}]的业务编码生成规则", ruleCode);
        if (basRule.get(0).getRuleItem().equals("0")) {
            //自动生成固定值编码
            Long numLength = basRule.get(0).getRuleLength();
            String code = basRule.get(0).getRuleValue() + System.currentTimeMillis();
            return saveAutoCode(basRule.get(0).getRuledetailId(), code, inputCharacter, "0", 1L);
        } else if (basRule.get(0).getRuleItem().equals("1")) {
            //自动生成变量编码
            String code = inputCharacter + System.currentTimeMillis();
            saveAutoCode(basRule.get(0).getRuledetailId(), code, inputCharacter, "1", 1L);
            return code;
        } else if (basRule.get(0).getRuleItem().equals("2")) {
            //自动生成日期编码
            if (basRule.get(0).getRuleValue().equals("3")) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
                String code = sdf.format(System.currentTimeMillis());
                return code;
            } else if (basRule.get(0).getRuleValue().equals("4")) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
                String code = sdf.format(System.currentTimeMillis());
                return code;
            } else if (basRule.get(0).getRuleValue().equals("5")) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                String code = sdf.format(System.currentTimeMillis());
                return code;
            } else if (basRule.get(0).getRuleValue().equals("6")) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH");
                String code = sdf.format(System.currentTimeMillis());
                return code;
            } else if (basRule.get(0).getRuleValue().equals("7")) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
                String code = sdf.format(System.currentTimeMillis());
                return code;
            } else if (basRule.get(0).getRuleValue().equals("8")) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                String code = sdf.format(System.currentTimeMillis());
                return code;
            }
        } else if (basRule.get(0).getRuleItem().equals("3")) {
            //自动生成流水号
            if (basRule.get(0).getRuleValue().equals("9")) {
                Long numLength = basRule.get(0).getRuleLength();
                String code = StringUtils.leftPad("1", numLength.intValue(), "0");
                return saveAutoCode(basRule.get(0).getRuledetailId(), code, inputCharacter, "3", numLength);
            } else if (basRule.get(0).getRuleValue().equals("10")) {
                Long numLength = basRule.get(0).getRuleLength();
                String code = StringUtils.leftPad("10", numLength.intValue(), "0");
                return saveAutoCode(basRule.get(0).getRuledetailId(), code, inputCharacter, "3", numLength);
            }

        }
        return "没有找到对应的规则";
    }

    private String saveAutoCode(Long ruledetailId, String autoCode, String inputChar, String codeType, Long numLength) {
        Boolean flag = threadLocal.get(); //针对当前线程的判断 flag = true则数据库中没有当前规则的生成记录
        List<BaseAutoCode> list = baseAutoCodeMapper.selectAutoCodeListByName(ruledetailId, codeType);
        if (codeType.equals("3")) {
            if (list.size() == 0) {
                BaseAutoCode rs = new BaseAutoCode();
                rs.setAutoCode(autoCode);
                rs.setRuledetailId(ruledetailId);
                rs.setCodeType(codeType);
                baseAutoCodeMapper.insert(rs);
                return autoCode;
            } else if (codeType.equals("3")) {
                BaseAutoCode rs = new BaseAutoCode();
                String s = list.get(0).getAutoCode();
                BigDecimal bigDecimal = new BigDecimal(s);
                String code = StringUtils.leftPad(bigDecimal.add(new BigDecimal("1")).toString(), numLength.intValue(), "0");
                bigDecimal.add(new BigDecimal("1"));
                rs.setAutoCode(code);
                rs.setRuledetailId(ruledetailId);
                rs.setCodeType(codeType);
                baseAutoCodeMapper.insert(rs);
                return code;
            }
            return autoCode;
        } else {
            BaseAutoCode rs = new BaseAutoCode();
            rs.setAutoCode(autoCode);
            rs.setRuledetailId(ruledetailId);
            rs.setCodeType(codeType);
            baseAutoCodeMapper.insert(rs);
            return autoCode;
        }
    }
}
