package com.wecloud.im.sdk.internal;

import okhttp3.Response;

import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;

import com.wecloud.im.sdk.common.ApiResult;
import com.wecloud.im.sdk.common.HttpClient;
import com.wecloud.im.sdk.common.HttpMethod;
import com.wecloud.im.sdk.common.RequestMessage;
import com.wecloud.im.sdk.common.auth.Credentials;
import com.wecloud.im.sdk.exception.WecloudException;

import static com.wecloud.im.sdk.utils.HttpHeaders.CONTENT_TYPE;

/**
 *
 * @Author luozh
 * @Date 2022年04月13日 13:47
 * @Version 1.0
 */
public abstract class WecloudImOperation {

    protected URL apiDomain;

    protected String appKey;

    protected String appSecret;

    public WecloudImOperation(URL apiDomain, String appKey, String appSecret) {
        this.apiDomain = apiDomain;
        this.appKey = appKey;
        this.appSecret = appSecret;
    }

    protected <T> ApiResult<T> doOperation(RequestMessage request, ResponseParser<T> responseParser) {
        ApiResult<T> result = send(request, responseParser);
        return result;
    }

    @SuppressWarnings("unchecked")
    private <T> ApiResult<T> send(RequestMessage request, ResponseParser<T> responseParser) {
        try {
            // 组装请求
            Map<String, Object> parameters = BeanUtil.beanToMap(request.getOriginalRequest(), false, true);
            Map<String, String> finalParameters = new HashMap<>();
            parameters.forEach((k, v) -> {
                finalParameters.put(k, v.toString());
            });

            Credentials credentials = new Credentials(appKey, appSecret);
            // 请求日期
            String date = DateUtil.formatHttpDate(new Date());
            request.addHeader(ImHeaders.DATE, date);
            request.addHeader(CONTENT_TYPE, "application/json; charset=utf-8");
            // 添加签名请求头
            RequestSigner signer = new RequestSigner(request.getMethod().name(), request.getEndpoint(), credentials);
            signer.sign(request);
            URL endpoint = new URL(apiDomain, request.getEndpoint());
            HttpClient httpClient =
                    HttpClient.builder().url(endpoint).addHeaders(request.getHeaders()).addParams(request.getParameters()).addParams(finalParameters);

            if (HttpMethod.POST.equals(request.getMethod())) {
                httpClient.post(true);
            } else {
                httpClient.get();
            }
            Response response = httpClient.sync();

            if (!Integer.valueOf(200).equals(response.code())) {
                throw new RuntimeException("请求报错: " + response.code());
            }

            assert response.body() != null;
            String responseBody = response.body().string();
            return responseParser.parse(responseBody);

        } catch (Exception e) {
            throw new WecloudException("发送请求报错: " + e.getMessage());
        }
    }

    private static RequestSigner createSigner(HttpMethod method, String bucketName, String key, Credentials creds) {
        String resourcePath = "/" + ((bucketName != null) ? bucketName + "/" : "") + ((key != null ? key : ""));

        return new RequestSigner(method.toString(), resourcePath, creds);
    }


}
