package cn.iocoder.yudao.module.pms.service.iotdevicecategorytemplateattrs;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicecategorytemplateattrs.vo.IotDeviceCategoryTemplateAttrsPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicecategorytemplateattrs.vo.IotDeviceCategoryTemplateAttrsSaveReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicecategorytemplateattrs.IotDeviceCategoryTemplateAttrsDO;
import cn.iocoder.yudao.module.pms.dal.mysql.iotdevicecategorytemplateattrs.IotDeviceCategoryTemplateAttrsMapper;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.List;
import java.util.Random;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_DEVICE_CATEGORY_TEMPLATE_ATTRS_NOT_EXISTS;
import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_DEVICE_TEMPLATE_ATTRS_EXISTS;

/**
 * 设备分类公共模板属性 Service 实现类
 *
 * @author ruiqi
 */
@Service
@Validated
public class IotDeviceCategoryTemplateAttrsServiceImpl implements IotDeviceCategoryTemplateAttrsService {

    @Resource
    private IotDeviceCategoryTemplateAttrsMapper iotDeviceCategoryTemplateAttrsMapper;

    @Override
    public Long createIotDeviceCategoryTemplateAttrs(IotDeviceCategoryTemplateAttrsSaveReqVO createReqVO) {
        // 插入
        IotDeviceCategoryTemplateAttrsDO iotDeviceCategoryTemplateAttrs = BeanUtils.toBean(createReqVO, IotDeviceCategoryTemplateAttrsDO.class);
        // 后台生成标识符 确保唯一性
        // 动态生成code
        String generatedCode = generateDynamicCode(iotDeviceCategoryTemplateAttrs.getName());
        iotDeviceCategoryTemplateAttrs.setCode(generatedCode);
        iotDeviceCategoryTemplateAttrsMapper.insert(iotDeviceCategoryTemplateAttrs);
        // 返回
        return iotDeviceCategoryTemplateAttrs.getId();
    }

    @Override
    public void updateIotDeviceCategoryTemplateAttrs(IotDeviceCategoryTemplateAttrsSaveReqVO updateReqVO) {
        // 校验属性是否存在
        validateIotDeviceCategoryTemplateAttrsExists(updateReqVO.getId());
        // 校验是否修改了属性名称 如果修改了 也要重新生成标识符
        // 查验是否存在相同标识符的属性
        validateAttrCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
        // 更新
        IotDeviceCategoryTemplateAttrsDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceCategoryTemplateAttrsDO.class);
        iotDeviceCategoryTemplateAttrsMapper.updateById(updateObj);
    }

    private void validateAttrCodeUnique(Long id, String code) {
        IotDeviceCategoryTemplateAttrsPageReqVO reqVO = new IotDeviceCategoryTemplateAttrsPageReqVO();
        reqVO.setCode(code);
        List<IotDeviceCategoryTemplateAttrsDO> attrs = iotDeviceCategoryTemplateAttrsMapper.selectList(reqVO);
        if (CollUtil.isEmpty(attrs)) {
            return;
        }
        // 如果有相同的标识符，随机取一个
        IotDeviceCategoryTemplateAttrsDO attr = attrs.get(0);
        // 如果 id 为空，说明不用比较是否为相同 id 的岗位
        if (id == null) {
            throw exception(IOT_DEVICE_TEMPLATE_ATTRS_EXISTS);
        }
        if (!attr.getId().equals(id)) {
            throw exception(IOT_DEVICE_TEMPLATE_ATTRS_EXISTS);
        }
    }

    @Override
    public void deleteIotDeviceCategoryTemplateAttrs(Long id) {
        // 校验存在
        validateIotDeviceCategoryTemplateAttrsExists(id);
        // 删除
        iotDeviceCategoryTemplateAttrsMapper.deleteById(id);
    }

    private void validateIotDeviceCategoryTemplateAttrsExists(Long id) {
        if (iotDeviceCategoryTemplateAttrsMapper.selectById(id) == null) {
            throw exception(IOT_DEVICE_CATEGORY_TEMPLATE_ATTRS_NOT_EXISTS);
        }
    }

    @Override
    public IotDeviceCategoryTemplateAttrsDO getIotDeviceCategoryTemplateAttrs(Long id) {
        return iotDeviceCategoryTemplateAttrsMapper.selectById(id);
    }

    @Override
    public PageResult<IotDeviceCategoryTemplateAttrsDO> getIotDeviceCategoryTemplateAttrsPage(IotDeviceCategoryTemplateAttrsPageReqVO pageReqVO) {
        return iotDeviceCategoryTemplateAttrsMapper.selectPage(pageReqVO);
    }

    @Override
    public List<IotDeviceCategoryTemplateAttrsDO> getTemplateAttrsByDeviceCategoryId(Long deviceCategoryId) {
        return iotDeviceCategoryTemplateAttrsMapper.selectList(deviceCategoryId);
    }

    /**
     * 根据名称生成动态编码
     */
    private String generateDynamicCode(String name) {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();

        // 处理名称部分
        if (name != null && !name.trim().isEmpty()) {
            for (char c : name.toCharArray()) {
                if (isChinese(c)) {
                    // 中文转拼音首字母（大写）
                    sb.append(getFirstLetterPinyin(c));
                } else {
                    // 非中文直接保留
                    sb.append(c);
                }
            }
        }

        // 添加后缀：时间戳 + 3位随机数
        String timestamp = String.valueOf(System.currentTimeMillis());
        String randomSuffix = String.format("%03d", random.nextInt(1000));

        return sb.append("_")
                .append(timestamp)
                .append(randomSuffix)
                .toString();
    }

    /**
     * 判断字符是否为中文
     */
    private boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A;
    }

    /**
     * 获取汉字拼音首字母（大写）
     */
    private String getFirstLetterPinyin(char ch) {
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

        try {
            String[] pinyin = PinyinHelper.toHanyuPinyinStringArray(ch, format);
            if (pinyin != null && pinyin.length > 0) {
                return pinyin[0].substring(0, 1);
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            // 转换失败时返回原字符
        }
        return String.valueOf(ch);
    }
}