package cn.nahco3awa.naouc.network.ouc.request;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

import cn.nahco3awa.naouc.network.ouc.OUCRequestSender;
import cn.nahco3awa.naouc.util.QrCodeSign;
import cn.nahco3awa.naouc.util.RSASign;
import cn.nahco3awa.naouc.util.SignUtils;
import okhttp3.FormBody;
import okhttp3.Request;

public class GetBarCodePayOUCRequest implements OUCRequest {
    public static final String URL = "https://vcard.ouc.edu.cn:20085/PhonePay/MobilePayCommon";
    private final String account;
    private final String cardId;
    private final String imei;
    private final String sourceType;

    public GetBarCodePayOUCRequest(String account, String cardId, String imei, String sourceType) {
        this.account = account;
        this.cardId = cardId;
        this.imei = imei;
        this.sourceType = sourceType;
    }


    /*
        method
        timestamp
        v
        registerid
        request
        sign
        // md5string
        clientType
        versionName
        versionCode
        sourcetype
        imei
        MD5string
     */
    public static final String UTF_8 = "UTF-8";
    @Override
    public Request makeRequest(OUCRequestSender sender) {
        HashMap<String, String> map = new HashMap<>();

        JsonObject jsonObject = new JsonObject();
        JsonObject jsonObject2 = new JsonObject();

        jsonObject.addProperty("account", account);
        jsonObject.addProperty("acctype", "001");
        jsonObject.addProperty("sourcetype", sourceType);
        jsonObject.addProperty("flag", "00");
        jsonObject.addProperty("cardid", cardId);
        jsonObject2.add("synjones.pay.getbarcode", jsonObject);

        JsonArray jsonArray = new JsonArray();
        jsonArray.add(jsonObject2);

        String request;
        map.put("method", "synjones.pay.getbarcode");
        String timestamp;
        timestamp = URLEncoder.encode(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis())), StandardCharsets.UTF_8);
        map.put("timestamp", timestamp);
        map.put("v", "1.0");
        map.put("registerid", "mobileby");
        request = new SignUtils().sign(jsonArray.get(0).toString(), "qJzGEh6hESZDVJeCnFPGuxzaiB7NLQM5", "DESede");
        String nr = URLEncoder.encode(request, StandardCharsets.UTF_8);
        map.put("request", nr);
        String sign = URLEncoder.encode(RSASign.sign(map), StandardCharsets.UTF_8);
        map.put("sign", sign);

        String signStatus = QrCodeSign.getSign(map);

        if (signStatus != null) {
            if (signStatus.equals("sign_error")) {
                throw new RuntimeException("验证签名失败！");
            }

            map.put("clientType", "1");
            map.put("versionName", "1.5.5");
            map.put("versionCode", "10505");
            map.put("sourcetype", sourceType);
            map.put("imei", imei);

            signStatus = QrCodeSign.getSign(map);
            String md5 = QrCodeSign.getBase64(signStatus).toLowerCase();

            FormBody formBody = new FormBody.Builder()
                    .add("method", "synjones.pay.getbarcode")
                    .add("timestamp", timestamp)
                    .add("v", "1.0")
                    .add("registerid", "mobileby")
                    .add("request", nr)
                    .add("sign", sign)
                    .add("md5string", md5)
                    .add("clientType", "1")
                    .add("versionName", "1.5.5")
                    .add("versionCode", "10505")
                    .add("sourcetype", sourceType)
                    .add("imei", imei)
                    .build();

            return sender.setAspHeaders(new Request.Builder()
                    .url(URL)
                    .post(formBody)).build();
        }
        throw new RuntimeException("签名为空！");
    }
}
