package com.sqx.modules.errand.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.exception.SqxException;
import com.sqx.common.sms.SmsConfigValueCache;
import com.sqx.common.sms.SmsSendResult;
import com.sqx.common.sms.SmsSendUtil;
import com.sqx.common.utils.Constant;
import com.sqx.common.utils.PageUtils;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.errand.dao.TbIndentSmsTemplateDao;
import com.sqx.modules.errand.dto.SmsTemplateDTO;
import com.sqx.modules.errand.dto.SmsTemplateQueryDTO;
import com.sqx.modules.errand.entity.TbIndentSmsTemplate;
import com.sqx.modules.errand.service.TbIndentSmsTemplateService;
import com.sqx.modules.errand.util.SmsTemplateValUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class TbIndentSmsTemplateServiceImpl extends ServiceImpl<TbIndentSmsTemplateDao, TbIndentSmsTemplate> implements TbIndentSmsTemplateService {

    private final CommonInfoService commonInfoService;
    private final SmsConfigValueCache smsConfigValueCache;

    @Override
    public void saveTemplate(SmsTemplateDTO template) {
        // 校验模板名称是否唯一
        checkTemplateUnique(template);

        // 检验模板是否符合规范
        checkTemplateContent(template);

        // 转换成po
        TbIndentSmsTemplate tbIndentSmsTemplate = new TbIndentSmsTemplate();
        BeanUtils.copyProperties(template, tbIndentSmsTemplate);

        // 填充默认属性
        tbIndentSmsTemplate.setDelFlag(Constant.NO);

        // 执行保存操作
        save(tbIndentSmsTemplate);
    }

    @Override
    public void updateTemplate(SmsTemplateDTO template) {
        // 校验模板名称是否唯一
        checkTemplateUnique(template);

        // 检验模板是否符合规范
        checkTemplateContent(template);

        // 转换成po
        TbIndentSmsTemplate tbIndentSmsTemplate = new TbIndentSmsTemplate();
        BeanUtils.copyProperties(template, tbIndentSmsTemplate);

        // 填充默认属性
        tbIndentSmsTemplate.setDelFlag(Constant.NO);

        // 执行保存操作
        updateById(tbIndentSmsTemplate);
    }

    @Override
    public PageUtils templatePage(SmsTemplateQueryDTO queryDTO) {
        Page<TbIndentSmsTemplate> pages = new Page<>(queryDTO.getPage(), queryDTO.getLimit());
        LambdaQueryWrapper<TbIndentSmsTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(queryDTO.getTemplateName()), TbIndentSmsTemplate::getTemplateName, queryDTO.getTemplateName());
        queryWrapper.eq(StrUtil.isNotBlank(queryDTO.getStatus()), TbIndentSmsTemplate::getStatus, queryDTO.getStatus());
        queryWrapper.eq(StrUtil.isNotBlank(queryDTO.getPlatformType()), TbIndentSmsTemplate::getPlatformType, queryDTO.getPlatformType());

        return new PageUtils(this.page(pages, queryWrapper));
    }

    @Override
    public SmsSendResult sendSms(Long smsTemplateId, UserEntity fromUser, String toPhone) {
        return sendSms(smsTemplateId, fromUser.getPhone(), fromUser.getUserName(), fromUser.getUserId(), toPhone);
    }

    @Override
    public SmsSendResult sendSms(Long smsTemplateId, String fromPhone, String fromUserName, Long fromUserId, String toPhone) {
        TbIndentSmsTemplate smsTemplate = getById(smsTemplateId);
        if (ObjectUtil.isNull(smsTemplate)) {
            throw new SqxException("无效的短信模板id");
        }

        String templateContent = smsTemplate.getTemplateContent();
        Map<String, String> templateVal = getTemplateVal(templateContent, fromPhone, fromUserName);
        String finalContent = SmsTemplateValUtil.replaceTemplateVal(templateContent, templateVal);

        SmsSendResult smsSendResult;

        // 1表示使用腾讯sms发送
        if ("1".equals(smsTemplate.getPlatformType())) {
            SmsSendUtil smsSendUtil = new SmsSendUtil(smsConfigValueCache.getTencentSmsConfig());

            smsSendResult = smsSendUtil.sendByTencent(toPhone, finalContent);
        } else {
            throw new SqxException("不支持的短信发送平台...");
        }

        // 填充smsSendResult其他属性
        smsSendResult.setTemplateId(smsTemplateId);
        smsSendResult.setSendFromId(fromUserId);

        return smsSendResult;
    }

    @Override
    public Double getPriceOfSms() {
        // 查询短信发送费用
        CommonInfo commonInfo = commonInfoService.findOne(421);
        return Double.valueOf(commonInfo.getValue());
    }

    /**
     * 获取模板动态参数
     * @param templateContent 模板
     * @param fromPhone 发送人手机号码
     * @param fromUsername 发送人名称
     * @return
     */
    private Map<String, String> getTemplateVal(String templateContent, String fromPhone, String fromUsername) {
        // 获取当前模板有哪些自定义参数
        List<String> templateValName = SmsTemplateValUtil.getTemplateValName(templateContent);
        Map<String, String> templateVal = new HashMap<>();
        templateValName.forEach(valName -> {
            String value;
            if (ObjectUtil.equal(valName, SmsTemplateValUtil.SUPPORT_VAL_NAME_LIST.get(0))) {
                value = fromPhone;
            } else {
                value = fromUsername;
            }

            templateVal.put(valName, value);
        });

        return templateVal;
    }

    private void checkTemplateUnique(SmsTemplateDTO template) {
        LambdaQueryWrapper<TbIndentSmsTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TbIndentSmsTemplate::getTemplateName, template.getTemplateName());
        queryWrapper.ne(template.getId() != null, TbIndentSmsTemplate::getId, template.getId());

        if (count(queryWrapper) > 0) {
            throw new SqxException("当前模板名称已经存在");
        }
    }

    private void checkTemplateContent(SmsTemplateDTO template) {
        if (!SmsTemplateValUtil.checkText(template.getTemplateContent())) {
            throw new SqxException("当前模板内容存在未定义变量");
        }
    }
}
