package cn.axzo.msg.center.notices.manager;

import cn.axzo.basics.common.exception.ServiceException;
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
import cn.axzo.msg.center.notices.manager.api.SmsSendManager;
import cn.axzo.msg.center.notices.manager.api.dto.request.BatchMessageSendRequestDto;
import cn.axzo.msg.center.notices.manager.api.dto.request.MessageSendRequestDto;
import cn.axzo.msg.center.notices.manager.api.dto.response.BatchMessageSendResponseDto;
import cn.axzo.msg.center.notices.manager.api.dto.response.SendSmsCommonResponseDto;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.aliyun.oss.common.utils.HttpUtil;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.function.BiConsumer;

/**
 * 政务: 龙泉
 *
 * @author yanglin
 */
@Slf4j
@RefreshScope
@RequiredArgsConstructor
@Service("regulatoryLongquanManager")
public class RegulatoryLongquanManager implements SmsSendManager {

    private static final String URI = "http://182.151.56.200:9998/http/send";

    private final OkHttpClient client = new OkHttpClient();
    @Value("${regulatory.longquan.appId:xliKSXxnAj3Oge2pw5rlsEsKAsD1a2fk}")
    private String appId;
    @Value("${regulatory.longquan.appKey:OgAEa9bFPJJc2XNLlVJCXlGvL5jDHdZb}")
    private String appKey;
    @Value("${regulatory.longquan.signName:【龙泉驿区住建局】}")
    private String signName;

    @Override
    public SendSmsCommonResponseDto sendMessage(MessageSendRequestDto request) {
        try {
            log.info("[RegulatoryLongquanManager#sendMessage] -> 政务龙泉 - 发送sms {}", JSON.toJSONString(request));
            return sendImpl(request);
        } catch (Exception e) {
            log.warn("[RegulatoryLongquanManager#sendMessage] -> 政务龙泉 - 发送sms失败 {}", JSON.toJSONString(request), e);
            throw new RuntimeException(e);
        }
    }

    private SendSmsCommonResponseDto sendImpl(MessageSendRequestDto mnsRequest) throws Exception {
        String templateContent = mnsRequest.getTemplate().getTemplateContent();
        String content = PlaceholderResolver.getDefaultResolver().resolveByMap(
                templateContent, mnsRequest.getTemplateMap());
        String encodedMsg = HttpUtil.urlEncode(signName + content, "UTF-8");
        String md5Sign = DigestUtil.md5Hex(appId + mnsRequest.getPhoneNo() + encodedMsg + appKey);
        FormBody.Builder formBuilder = new FormBody.Builder();
        HashMap<String, Object> formParams = new HashMap<>();
        BiConsumer<String, String> formPopulator= (key, value) -> {
            formBuilder.add(key, value);
            formParams.put(key, value);
        };
        formPopulator.accept("appid", appId);
        formPopulator.accept("mobile", mnsRequest.getPhoneNo());
        formPopulator.accept("msg", encodedMsg);
        formPopulator.accept("sign", md5Sign);
        Request httpRequest = new Request.Builder()
                .url(URI)
                .post(formBuilder.build())
                .build();
        log.info("[RegulatoryLongquanManager#sendMessage] -> 政务龙泉 - 发送sms请求, formBody={}",
                JSON.toJSONString(formParams));
        LongquanResponse longquanResult = null;
        try (Response httpResponse = client.newCall(httpRequest).execute()) {
            ResponseBody body = httpResponse.body();
            if (body != null)
                longquanResult = JSON.parseObject(body.string(), LongquanResponse.class);
            log.info("[RegulatoryLongquanManager#sendMessage] -> 政务龙泉 - formBody: {}, 发送sms结果: {}",
                    JSON.toJSONString(formParams), longquanResult);
        }
        if (longquanResult != null && !longquanResult.isSuccess())
            throw new ServiceException(String.format("政务龙泉 - 发送sms失败 %s. mnsRequest=%s, formBody=%s",
                    longquanResult, JSON.toJSONString(mnsRequest), JSON.toJSONString(formParams)));
        SendSmsCommonResponseDto result = new SendSmsCommonResponseDto();
        if (longquanResult != null)
            result.setBizId(longquanResult.getTaskId());
        result.setRequestId(md5Sign);
        result.setMessage(longquanResult == null ? "" : longquanResult.getResultMsg());
        return result;
    }

    @Override
    public BatchMessageSendResponseDto sendBatchMessage(BatchMessageSendRequestDto requestDto) {
        throw new UnsupportedOperationException("sendBatchMessage");
    }

    @Setter
    @Getter
    private static class LongquanResponse {
        private int resultCode;
        private String resultMsg;
        @JSONField(name = "taskid")
        private String taskId;

        public boolean isSuccess() {
            return resultCode == 0;
        }

        @Override
        public String toString() {
            return JSON.toJSONString(this);
        }
    }
}