package com.hys.app.service.base.plugin.sms;

import com.alibaba.fastjson.JSON;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hys.app.framework.exception.ServiceException;
import com.hys.app.model.base.message.SmsSendCallbackMsg;
import com.hys.app.model.base.rabbitmq.AmqpExchange;
import com.hys.app.model.base.vo.ConfigItem;
import com.hys.app.model.base.vo.SmsSendVO;
import com.hys.app.model.errorcode.SystemErrorCode;
import com.hys.app.model.system.dos.SmsSendRecord;
import com.hys.app.model.system.enums.AuditStatusEnum;
import com.hys.app.model.system.enums.EnableStatusEnum;
import com.hys.app.model.system.enums.SmsRecordStatusEnum;
import com.hys.app.service.base.service.AliSmsApiManager;
import com.hys.app.service.system.SmsSendRecordManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.hys.app.framework.rabbitmq.MessageSender;
import com.hys.app.framework.rabbitmq.MqMessage;
import com.hys.app.framework.util.DateUtil;
import com.hys.app.framework.util.StringUtil;
import com.hys.app.mapper.system.SmsTemplateMapper;
import com.hys.app.model.system.dos.SmsTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 阿里云短信插件
 *
 * @author zhangsong
 * @version v1.0
 * @since v7.3.0
 * 2021-01-27
 */
@Component
public class SmsAliPlugin implements SmsPlatform {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 阿里云接口返回成功的code值
     */
    private final String SUCCESS_CODE = "OK";

    @Autowired
    private AliSmsApiManager aliSmsApiManager;

    @Autowired
    private SmsTemplateMapper smsTemplateMapper;

    @Autowired
    private MessageSender messageSender;

    @Autowired
    private SmsSendRecordManager smsSendRecordManager;

    @Override
    public boolean onSend(SmsSendVO smsSendVO, Map param) {
        String phone = smsSendVO.getMobile();
        String templateCode = smsSendVO.getTemplateCode();
        String templateParam = smsSendVO.getTemplateParam();
        String signName = String.valueOf(param.get("sign_name"));
        try {
            if (StringUtil.isEmpty(phone) || StringUtil.isEmpty(signName) || StringUtil.isEmpty(templateCode) || StringUtil.isEmpty(param)) {
                logger.error("发送短信参数异常,请检查phone={}, signName={}, templateCode={}, param={} ", phone, signName, templateCode, param);
                return false;
            }

            Client client = createClient(param);
            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    .setPhoneNumbers(phone)
                    .setSignName(signName)
                    .setTemplateCode(templateCode)
                    .setTemplateParam(templateParam);
            SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);

            SendSmsResponseBody body = sendSmsResponse.getBody();
            smsSendVO.setBizId(body.getBizId());
            logger.debug("发送短信结果：" + body.toMap());
            if (SUCCESS_CODE.equals(body.getCode())) {
                return true;
            } else {
                logger.error("发送短信失败：" + body.toMap());
            }
        } catch (Exception e) {
            logger.error("发送短信异常", e);
        }
        return false;
    }

    @Override
    public String getPluginId() {
        return "smsAliPlugin";
    }


    @Override
    public String getPluginName() {
        return "阿里云短信网关";
    }


    @Override
    public List<ConfigItem> definitionConfigItem() {
        List<ConfigItem> list = new ArrayList();

        ConfigItem signName = new ConfigItem();
        signName.setType("text");
        signName.setName("sign_name");
        signName.setText("签名");

        ConfigItem accessKeyId = new ConfigItem();
        accessKeyId.setType("text");
        accessKeyId.setName("access_key_id");
        accessKeyId.setText("密钥id(AccessKey ID)");

        ConfigItem accessKeySecret = new ConfigItem();
        accessKeySecret.setType("text");
        accessKeySecret.setName("access_key_secret");
        accessKeySecret.setText("密钥(AccessKey Secret)");

        list.add(signName);
        list.add(accessKeyId);
        list.add(accessKeySecret);

        return list;
    }


    @Override
    public Integer getIsOpen() {
        return 0;
    }

    @Override
    public void templateUpdateCheck(SmsTemplate oldModel) {
        if (AuditStatusEnum.AUDITING.value().equals(oldModel.getAuditStatus())) {
            throw new ServiceException(SystemErrorCode.E931.code(), "正在审核中，无法修改");
        }
    }

    @Override
    public void updateTemplate(SmsTemplate oldModel, SmsTemplate newModel) {
        //由于阿里云短信模板审核通过后，模板不支持修改，所以需要先删除原来的模板
        if (StringUtil.notEmpty(oldModel.getTemplateCode())) {
            aliSmsApiManager.deleteSmsTemplate(oldModel.getTemplateCode());
            newModel.setTemplateCode(null);
        }

        newModel.setEnableStatus(EnableStatusEnum.CLOSE.value());
        newModel.setAuditStatus(AuditStatusEnum.WAITING.value());
    }


    @Override
    public boolean isNeedAudit() {
        return true;
    }


    @Override
    public void templateSubmitAudit(SmsTemplate model) {
        aliSmsApiManager.addSmsTemplate(model);
    }

    @Override
    public Map templateAuditCallback(String json) {

        logger.info("阿里模板回调");
        try {
            List<Map> maps = JSON.parseArray(json, Map.class);
            for (Map map : maps) {
                SmsTemplate model = smsTemplateMapper.selectOne(new QueryWrapper<SmsTemplate>().eq("template_code", map.get("template_code")));
                if (Objects.isNull(model)) {
                    logger.error("未找到编号：" + map.get("template_code") + "的模板");
                    continue;
                }
                //审核结果
                String auditStatus = map.get("template_status").toString();
                //判断审核通过还是未通过
                if (AuditStatusEnum.ALI_PASS.description().equals(auditStatus)) {
                    model.setAuditStatus(AuditStatusEnum.PASS.value());
                } else if (AuditStatusEnum.ALI_NOT_PASS.description().equals(auditStatus)) {
                    model.setAuditStatus(AuditStatusEnum.NOT_PASS.value());
                    model.setFailReason(map.get("reason").toString());
                }
                //设置工单id
                model.setOrderId(map.get("order_id") + "");
                smsTemplateMapper.updateById(model);
            }
        } catch (Exception e) {
            logger.error("阿里回调模板信息出错");
            e.printStackTrace();
        }
        HashMap<String, Object> hashMap = new HashMap<>(1);
        hashMap.put("code", 0);
        hashMap.put("msg", "接收成功");
        return hashMap;
    }

    @Override
    public Map smsSendCallback(String json) {

        try {
            List<Map> list = JSON.parseArray(json, Map.class);
            for (Map<String, Object> map : list) {
                //短信回执id
                String bizId = map.get("biz_id").toString();
                //用户接收是否成功
                String isSuccess = map.get("success").toString();
                SmsSendCallbackMsg smsSendCallbackMsg = new SmsSendCallbackMsg();
                smsSendCallbackMsg.setBizId(bizId);
                smsSendCallbackMsg.setIsSuccess(isSuccess);
                this.messageSender.send(new MqMessage(AmqpExchange.SMS_SEND_CALLBACK, AmqpExchange.SMS_SEND_CALLBACK + "_ROUTING", smsSendCallbackMsg));
            }
        } catch (Exception e) {
            //短信发送失败
            e.printStackTrace();
        }

        //必须要应答的数据，否则阿里云后台保存回调地址会失败
        Map map = new HashMap(1);
        map.put("code", 0);
        return map;
    }

    @Override
    public void insertRecord(SmsSendVO smsSendVO, Map config) {
        SmsSendRecord smsSendRecord = new SmsSendRecord();
        smsSendRecord.setBizId(smsSendVO.getBizId());
        smsSendRecord.setPhone(smsSendVO.getMobile());
        smsSendRecord.setSendContent(smsSendVO.getContent());
        smsSendRecord.setSendStatus(SmsRecordStatusEnum.WAIT_RECEIPT.value());
        smsSendRecord.setSendTime(DateUtil.getDateline());
        smsSendRecord.setServiceType(smsSendVO.getServiceType());
        smsSendRecord.setSignName(String.valueOf(config.get("sign_name")));
        smsSendRecord.setTemplateId(smsSendVO.getTemplateId());
        smsSendRecordManager.add(smsSendRecord);

    }

    /**
     * 创建阿里云请求客户端
     *
     * @param configMap 配置参数
     * @return
     */
    private Client createClient(Map<String, String> configMap) throws Exception {

        //获取配置参数
        String accessKeyId = configMap.get("access_key_id");
        String accessKeySecret = configMap.get("access_key_secret");

        Config config = new Config();
        config.accessKeyId = accessKeyId;
        config.accessKeySecret = accessKeySecret;
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new Client(config);
    }
}
