package rd.rpc;

import cn.hutool.core.net.url.UrlBuilder;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import rd.configure.RdConfigure;
import rd.data.Constants;
import rd.data.code.ServiceCode;
import rd.data.model.response.Response;
import rd.exception.ServiceException;
import rd.rpc.model.WusthelperStudentInfo;

import java.io.IOException;

@Service
public class WusthelperApi {

    private final OkHttpClient okHttpClient;
    private final ObjectMapper objectMapper;
    private final RdConfigure rdConfigure;

    public WusthelperApi(OkHttpClient okHttpClient,
                         @Qualifier("objectMapper") ObjectMapper objectMapper,
                         RdConfigure rdConfigure
    ) {
        this.okHttpClient = okHttpClient;
        this.objectMapper = objectMapper;
        this.rdConfigure = rdConfigure;
    }

    private static final TypeReference<Response<String>> StringResponseTypeReference = new TypeReference<>() {
    };

    public String wusthelperLogin(String stuNum, String pwd) throws IOException {
        var req = new Request.Builder()
                .url(UrlBuilder.of(rdConfigure.getWusthelperBaseUrl())
                        .addPath(Constants.Wusthelper.UndergradLogin)
                        .toURL()
                )
                .post(new FormBody.Builder()
                        .add("stuNum", stuNum)
                        .add("jwcPwd", pwd)
                        .build()
                )
                .build();

        return this.execReq(req, StringResponseTypeReference);
    }

    private static final TypeReference<Response<WusthelperStudentInfo>> StuInfoResponseTypeReference = new TypeReference<>() {
    };

    public WusthelperStudentInfo getStudentInfo(String token) throws IOException {
        var req = new Request.Builder()
                .url(UrlBuilder.of(rdConfigure.getWusthelperBaseUrl())
                        .addPath(Constants.Wusthelper.UndergradStuInfo)
                        .toURL()
                )
                .addHeader("token", token)
                .get()
                .build();

        return this.execReq(req, StuInfoResponseTypeReference);
    }

    private <T> T execReq(Request req, TypeReference<Response<T>> typeReference) throws IOException {
        try (var resp = okHttpClient.newCall(req).execute()) {
            var wusthelperResponse = objectMapper.readValue(resp.body().string(), typeReference);
            if (wusthelperResponse.code() != 10000) {
                throw ServiceException.error(ServiceCode.WusthelperApiRequestErr, wusthelperResponse.msg());
            }

            return wusthelperResponse.data();
        }
    }
}
