package com.suixingpay.android_tpp_sdk;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.suixingpay.serialsdk.api.SerialPort;
import com.suixingpay.serialsdk.listener.SerialListener;
import com.suixingpay.serialsdk.service.SerialSDKService;
import com.suixingpay.serialsdk.utils.ToastUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.UUID;

public class MainActivity extends AppCompatActivity implements SerialListener {
    private final String TAG = "MainActivity";

    // 开串口 关串口
    private Button btn_open, btn_close;
    // 签到 查询POS状态
    private Button btn_sign, btn_device_status;

    // PF 八达通消费、消费、消费撤销
    private Button btn_pf_octopus, btn_fp_sale, btn_fp_sale_revoke;
    // PF 预授权、预授权撤销
    private Button btn_pf_auth, btn_pf_auth_revoke;

    private Button btn_tpp_sale;
    private Button btn_tpp_auth;
    private Button btn_tpp_auth_capture,btn_tpp_auth_incremental,btn_tpp_auth_revoke;

    // 完成交易 取消交易
    private Button btn_finish_transaction, btn_cancel_transaction;
    private Button btn_query_transaction;
    private Button btn_start_biz, btn_stop_biz, btn_query_business_status;
    private Button btn_clear_message;

    // 输入框
    private EditText et_amount, et_transaction_no, et_serial_port;

    // 消息
    private TextView message_text_view;

    SerialSDKService serialService;

    @Override
    protected void onDestroy() {
        super.onDestroy();
        serialService.close();
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Context context = this;
        ToastUtil.init(this);
        // 打开串口
        btn_open = findViewById(R.id.btn_open);
        // 关闭串口
        btn_close = findViewById(R.id.btn_close);
        // 签到
        btn_sign = findViewById(R.id.btn_sign);
        // 查询设备状态
        btn_device_status = findViewById(R.id.btn_device_status);

        // PF-八达通消费
        btn_pf_octopus = findViewById(R.id.btn_pf_octopus);
        // PF-消费
        btn_fp_sale = findViewById(R.id.btn_fp_sale);
        // PF-消费撤销
        btn_fp_sale_revoke = findViewById(R.id.btn_fp_sale_revoke);

        // PF -预授权
        btn_pf_auth = findViewById(R.id.btn_pf_auth);
        // PF -预授权撤销
        btn_pf_auth_revoke = findViewById(R.id.btn_pf_auth_revoke);

        // TPP-模式-消费
        btn_tpp_sale = findViewById(R.id.btn_tpp_sale);
        // TPP - 预授权
        btn_tpp_auth = findViewById(R.id.btn_tpp_auth);
        // TPP - 预授权完成
        btn_tpp_auth_capture =  findViewById(R.id.btn_tpp_auth_capture);
        // TPP - 预授权追加
        btn_tpp_auth_incremental = findViewById(R.id.btn_tpp_auth_incremental);
        // TPP - 预授权撤销
        btn_tpp_auth_revoke = findViewById(R.id.btn_tpp_auth_revoke);

        // 设置营业
        btn_start_biz = findViewById(R.id.btn_start_biz);
        // 设置营业
        btn_stop_biz = findViewById(R.id.btn_stop_biz);
        // 查询营业
        btn_query_business_status = findViewById(R.id.btn_query_business_status);
        // 查询交易
        btn_query_transaction = findViewById(R.id.btn_query_transaction);

        // 清除消息
        btn_clear_message = findViewById(R.id.btn_clear_message);

        // 金额输入
        et_amount = findViewById(R.id.et_amount);
        et_amount.setText("10.00");
        // 交易流水号
        et_transaction_no = findViewById(R.id.et_transaction_no);
        // 串口名称
        et_serial_port = findViewById(R.id.et_serial_port);
        et_serial_port.setText(SerialSDKService.getInstance(this).getUsbDevicesPath());
        // 消息面板
        message_text_view = findViewById(R.id.message_text_view);

        // 完成交易
        btn_finish_transaction = findViewById(R.id.btn_finish_transaction);
        // 取消交易
        btn_cancel_transaction = findViewById(R.id.btn_cancel_transaction);

        /*
         * 打开串口
         */
        openSerialPort(context);
        btn_open.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //打开串口
                openSerialPort(context);
                logMessage("串口打开");
            }
        });
        /*
         * 关闭串口
         */
        btn_close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                serialService.close();
                logMessage("串口关闭");
            }
        });
        /*
         * 签到
         */
        btn_sign.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String amount = et_amount.getText().toString().trim();
                if (amount.isEmpty()) {
                    ToastUtil.showToast("请输入金额");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/sign");
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        /*
         * 查询POS状态
         */
        btn_device_status.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/query/device/status");
                    jsonObject.put("requestId", UUID.randomUUID());
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        /*
         * PF - 八达通消费
         */
        btn_pf_octopus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String amount = et_amount.getText().toString().trim();
                if (amount.isEmpty()) {
                    ToastUtil.showToast("请输入金额");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/sale");
                    jsonObject.put("orderAmount", amount); // 小费金额
                    jsonObject.put("merchantOrderNo", UUID.randomUUID()); // 商户订单号
                    jsonObject.put("paymentType", "06"); //
                    jsonObject.put("paymentSubType", "12");
                    jsonObject.put("externalAdditionalData", "external data");
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        /*
         * PF - 消费
         */
        btn_fp_sale.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String amount = et_amount.getText().toString().trim();
                if (amount.isEmpty()) {
                    ToastUtil.showToast("请输入金额");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/sale");
                    jsonObject.put("orderAmount", amount);
                    jsonObject.put("paymentType", "01");
                    jsonObject.put("merchantSerialNo", UUID.randomUUID());
                    jsonObject.put("externalAdditionalData", "external data");
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        /*
         * PF - 消费撤销
         */
        btn_fp_sale_revoke.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String transactionNo = et_transaction_no.getText().toString().trim();
                if (transactionNo.isEmpty()) {
                    ToastUtil.showToast("请输入原交易单号");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/sale/revoke");
                    jsonObject.put("merchantSerialNo", UUID.randomUUID()); // 商户订单号
                    jsonObject.put("originalTransactionNo", transactionNo);
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        /*
         * PF - 预授权
         */
        btn_pf_auth.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String amount = et_amount.getText().toString().trim();
                if (amount.isEmpty()) {
                    ToastUtil.showToast("请输入金额");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/auth");
                    jsonObject.put("merchantSerialNo", UUID.randomUUID());
                    jsonObject.put("orderAmount", amount);
                    jsonObject.put("externalAdditionalData", "external data");
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }

            }
        });
        /*
         * PF - 预授权撤销
         */
        btn_pf_auth_revoke.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String transactionNo = et_transaction_no.getText().toString().trim();
                if (transactionNo.isEmpty()) {
                    ToastUtil.showToast("请输入原交易单号");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/auth/revoke");
                    jsonObject.put("merchantSerialNo", UUID.randomUUID());
                    jsonObject.put("originalTransactionNo", transactionNo);
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }

            }
        });
        /*
         * TPP 消费
         */
        btn_tpp_sale.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String amount = et_amount.getText().toString().trim();
                if (amount.isEmpty()) {
                    ToastUtil.showToast("请输入金额");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/sale");
                    jsonObject.put("orderAmount", amount);
                    jsonObject.put("merchantSerialNo", UUID.randomUUID());
                    jsonObject.put("orderTitle", "Sale");
                    JSONArray detailsArray = new JSONArray();
                    detailsArray.put("coke * 2");
                    detailsArray.put("chip * 5");
                    jsonObject.put("orderDetails", detailsArray);
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });


        /*
         * TPP-预授权
         */
        btn_tpp_auth.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String amount = et_amount.getText().toString().trim();
                if (amount.isEmpty()) {
                    ToastUtil.showToast("请输入金额");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/auth");
                    jsonObject.put("orderAmount", amount);
                    jsonObject.put("merchantSerialNo", UUID.randomUUID());
                    jsonObject.put("orderTitle", "Auth");
                    JSONArray detailsArray = new JSONArray();
                    detailsArray.put("coke * 2");
                    detailsArray.put("chip * 5");
                    jsonObject.put("orderDetails", detailsArray);
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        /*
         * TPP-预授权完成
         */
        btn_tpp_auth_capture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String transactionNo = et_transaction_no.getText().toString().trim();
                String amount = et_amount.getText().toString().trim();
                if (amount.isEmpty()) {
                    ToastUtil.showToast("请输入金额");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/auth/capture");
                    jsonObject.put("orderAmount", amount);
                    jsonObject.put("merchantSerialNo", transactionNo);
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        /*
         * TPP-预授权完成
         */
        btn_tpp_auth_incremental.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String transactionNo = et_transaction_no.getText().toString().trim();
                String amount = et_amount.getText().toString().trim();
                if (amount.isEmpty()) {
                    ToastUtil.showToast("请输入金额");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/auth/incremental");
                    jsonObject.put("orderAmount", amount);
                    jsonObject.put("merchantSerialNo", transactionNo);
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        /*
         * TPP-预授权撤销
         */
        btn_tpp_auth_revoke.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String transactionNo = et_transaction_no.getText().toString().trim();
                if (transactionNo.isEmpty()) {
                    ToastUtil.showToast("请输入原交易流水号");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/auth/revoke");
                    jsonObject.put("merchantSerialNo", transactionNo);
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        /*
         * 查询交易
         */
        btn_query_transaction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String transactionNo = et_transaction_no.getText().toString().trim();
                if (transactionNo.isEmpty()) {
                    ToastUtil.showToast("请输入原交易单号");
                    return;
                }
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/query/transaction");
                    jsonObject.put("originalTransactionNo", transactionNo);
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }

            }
        });
        /*
         * 完成交易 -- 交易成功完成
         */
        btn_finish_transaction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/finish/transaction");
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }

            }
        });

        /*
         * 取消交易 刷卡前
         */
        btn_cancel_transaction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/cancel/transaction");
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        /*
         * 设置营业
         */
        btn_start_biz.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/open/business");
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        /*
         * 设置停业
         */
        btn_stop_biz.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/stop/business");
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        /*
         * 查询营业状态
         */
        btn_query_business_status.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("api", "/query/business/status");
                    String jsonString = jsonObject.toString();
                    serialService.sendText(jsonString);
                    logMessage(jsonString);
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }

            }
        });




        /*
         * 清理消息
         */
        btn_clear_message.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                message_text_view.setText("");
            }
        });

    }

    private void logMessage(String message) {
        message_text_view.append(message+"\r\n");

        // 滚动到底部
        int scrollAmount = message_text_view.getLayout().getLineTop(message_text_view.getLineCount()) - message_text_view.getHeight();
        if (scrollAmount > 0)
            message_text_view.scrollTo(0, scrollAmount);
        else
            message_text_view.scrollTo(0, 0);

    }

    /**
     * 打开串口
     */
    private void openSerialPort(Context context) {
        // 开的串口
        String port = et_serial_port.getText().toString();
        // 波特率
        int baudRate = SerialPort.BAUDRATE.B57600.getBaudrate();
        // 获取实例
        serialService = SerialSDKService.getInstance(context);
        // 设置数据回调
        serialService.setListener(this);
        // 创建串口
        serialService.create(port, baudRate);
        // 打开串口
        serialService.open();
    }

    /**
     * 收到数据
     */
    @Override
    public void onDataReceived(String jsonString) {
        try {
            logMessage(jsonString);

            Log.i(TAG, "onDataReceived result: " + new JSONObject(jsonString));
            JSONObject jsonObject = new JSONObject(jsonString);
            String code = jsonObject.optString("code");
            String msg = jsonObject.optString("msg");
            if(code.equals("00")) {
                JSONObject data = jsonObject.optJSONObject("data");
                if (data != null) {
                    String api = data.optString("api");
                    String requestId = data.optString("requestId");
                    String sn = data.optString("sn");
                    String transactionNo = data.optString("transactionNo");
                    String merchantSerialNo = data.optString("merchantSerialNo");
                    String orderNo = data.optString("orderNo");
                    String transactionStatus = data.optString("transactionStatus");
                    String currency = data.optString("currency");
                    String orderAmount = data.optString("orderAmount");
                    String transactionTime = data.optString("transactionTime");

                    Log.d("JSON", "api = " + api);
                    // 预授权
                    if(api.equals("/auth")) {
                        et_transaction_no.setText(transactionNo);
                        et_amount.setText(orderAmount);
                        Log.i(TAG, "onDataReceived: 处理预授权返回数据");
                    }else if (api.equals("/sale")) {
                        Log.i(TAG, "onDataReceived: 处理销售返回数据");
                        et_transaction_no.setText(transactionNo);
                        et_amount.setText(orderAmount);
                    }
                }
            }else {
                Log.e(TAG, "onDataReceived: " + msg );
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 数据错误
     */
    @Override
    public void onError(int errorCode, String errorMessage) {
        Log.i(TAG, "onError: " + errorCode + " errorMessage:" + errorMessage);
    }
}