package cn.axzo.msg.center.notices.integration.client.impl;

import cn.axzo.msg.center.notices.common.enums.ReturnCodeEnum;
import cn.axzo.msg.center.notices.common.exception.BizException;
import cn.axzo.msg.center.notices.integration.client.SubMailClient;
import cn.axzo.msg.center.notices.integration.dto.request.SendSmsCommonRequest;
import cn.axzo.msg.center.notices.integration.dto.response.SubMailSingleSendSmsResponse;
import cn.axzo.msg.center.notices.integration.support.SubMailConfig;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.TreeMap;

/**
 * @description
 *   SUBMAIL短信发送client具体实现
 *
 * @author cold_blade
 * @date 2023/9/5
 * @version 1.0
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class SubMailClientImpl implements SubMailClient {

    private static final String SINGLE_SEND_URL = "https://api-v4.mysubmail.com/sms/xsend";

    private final SubMailConfig subMailConfig;

    @Override
    public SubMailSingleSendSmsResponse sendSingleTemplateSms(SendSmsCommonRequest request) {
        // 参数检测
        check(request);
        // 构造发送模板短信的入参
        TreeMap<String, String> requestParam = buildRequestParam(request);
        // post请求
        SubMailSingleSendSmsResponse response = doPost(requestParam);
        log.info("[mns <- submail] SubMailClientImpl.sendSingleTemplateSms result: {}", JSON.toJSONString(response));
        response.setRequestId(request.getRequestChannelNo());
        return response;
    }

    private void check(SendSmsCommonRequest request) {
        BizException.error(Objects.nonNull(request), ReturnCodeEnum.INVALID_PARAMETER, "request is required");
        BizException.error(StringUtils.isNotBlank(request.getRequestChannelNo()), ReturnCodeEnum.INVALID_PARAMETER,
                "requestChannelNo is required");
        BizException.error(StringUtils.isNotBlank(request.getPhoneNo()), ReturnCodeEnum.INVALID_PARAMETER,
                "phoneNo is required");
        BizException.error(StringUtils.isNotBlank(request.getTemplateCode()), ReturnCodeEnum.INVALID_PARAMETER,
                "templateCode is required");
    }

    private TreeMap<String, String> buildRequestParam(SendSmsCommonRequest request) {
        TreeMap<String, String> requestParam = new TreeMap<>();
        String appId = subMailConfig.getAppId();
        String appKey = subMailConfig.getAppKey();
        String to = request.getPhoneNo();

        //组合请求数据
        requestParam.put("appid", appId);
        requestParam.put("to", to);
        requestParam.put("signature", appKey);

        requestParam.put("project", request.getTemplateCode());
        if (Objects.nonNull(request.getTemplateMap()) && !request.getTemplateMap().isEmpty()) {
            requestParam.put("vars", JSON.toJSONString(request.getTemplateMap()));
        }
        requestParam.put("tag", request.getRequestChannelNo());
        return requestParam;
    }

    private SubMailSingleSendSmsResponse doPost(TreeMap<String, String> requestParam) {
        HttpPost httpPost = new HttpPost(SINGLE_SEND_URL);
        httpPost.setHeader("Accept", ContentType.APPLICATION_JSON.toString());
        httpPost.setHeader("Content-Type", ContentType.APPLICATION_JSON.toString());

        StringEntity entity = new StringEntity(JSONObject.toJSONString(requestParam), StandardCharsets.UTF_8);
        httpPost.setEntity(entity);

        try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            if (httpEntity != null) {
                String jsonStr = EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);
                return JSON.parseObject(jsonStr, SubMailSingleSendSmsResponse.class);
            }
            throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "invoke subMail fail");
        } catch (Exception e) {
            log.error("[mns <- subMail] SubMailClientImpl.sendSms is fail", e);
            throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "invoke subMail fail");
        }
    }
}
