package jnpf.parameter.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import jnpf.model.warningnotice.enums.CertificateTypeEnum;
import jnpf.model.warningnotice.po.FtbParamEntity;
import jnpf.parameter.service.ParamService;
import jnpf.storecertificatephoto.mapper.BaseParamMapper;
import jnpf.util.RandomUtil;
import jnpf.util.ServiceException;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 基础参数服务实现
 */
@Service
@RequiredArgsConstructor
public class ParamServiceImpl implements ParamService {

    private static final String CONFIG_KEY_PREFIX = "ftbWarningNotice_";
    private final BaseParamMapper baseParamMapper;

    @Override
    public void saveOrUpdateParam(FtbParamEntity entity) {
        ServiceException.notNull(entity, "基础参数不能为空");
        String key = entity.getKey();

        int updateCount;
        try {
            updateCount = baseParamMapper.updateByKey(key, entity);
        } catch (DuplicateKeyException e) {
            throw new ServiceException("该证照类型的预警配置已存在");
        }
        if (updateCount > 0) {
            return;
        }

        try {
            baseParamMapper.insertParam(entity);
        } catch (DuplicateKeyException e) {
            int retryCount = baseParamMapper.updateByKey(key, entity);
            ServiceException.isTrue(retryCount > 0, "保存预警配置失败");
        }
    }

    /**
     * 根据key递增参数值并返回最新值。
     * 处理流程：
     * 1. 先执行 value = value + number；
     * 2. 若更新条数为0，则插入一条 value=1 的记录；
     * 3. 若更新成功，则查询并返回最新 value。
     *
     * @param key 参数key
     * @param number 递增参数（兼容调用方传参）
     * @return 最新数值
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long increment(String key, String type, Long number) {
        String trimKey = StrUtil.trim(key);
        ServiceException.isTrue(StrUtil.isNotBlank(trimKey), "参数key不能为空");
        ServiceException.notNull(number, "参数number不能为空");

        int updateCount = baseParamMapper.incrementValueByKey(trimKey, number);
        if (updateCount == 0) {
            FtbParamEntity entity = new FtbParamEntity();
            entity.setId(RandomUtil.uuId());
            entity.setKey(trimKey);
            entity.setType(type);
            entity.setValue("1");
            entity.setSort(number);

            try {
                baseParamMapper.insertParam(entity);
                return 1L;
            } catch (DuplicateKeyException e) {
                int retryCount = baseParamMapper.incrementValueByKey(trimKey, number);
                ServiceException.isTrue(retryCount > 0, "递增失败");
            }
        }

        FtbParamEntity dbEntity = baseParamMapper.selectByKey(trimKey);
        ServiceException.notNull(dbEntity, "基础参数不存在");
        ServiceException.isTrue(StrUtil.isNotBlank(dbEntity.getValue()), "基础参数值不能为空");
        try {
            return Long.parseLong(StrUtil.trim(dbEntity.getValue()));
        } catch (NumberFormatException e) {
            throw new ServiceException("基础参数值不是数字");
        }
    }

    /**
     * 根据证照类型构建配置key
     *
     * @param certificateType 证照类型
     * @return 配置key
     */
    private String buildConfigKey(CertificateTypeEnum certificateType) {
        return CONFIG_KEY_PREFIX + DigestUtil.md5Hex(certificateType.getType());
    }
}
