package com.unibuy.smartdevice.external;

import android.content.Context;
import android.util.Log;
import android.widget.ProgressBar;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

import com.bumptech.glide.load.Key;
import com.unibuy.smartdevice.MainActivity;
import com.unibuy.smartdevice.MyApp;
import com.unibuy.smartdevice.controller.DevXinYuanController;
import com.unibuy.smartdevice.database.SettingsDao;
import com.unibuy.smartdevice.database.SlotsDao;
import com.unibuy.smartdevice.devices.SlotField;
import com.unibuy.smartdevice.exception.ErrorCode;
import com.unibuy.smartdevice.exception.Logs;
import com.unibuy.smartdevice.exception.LogsEmptyException;
import com.unibuy.smartdevice.exception.LogsFileNullException;
import com.unibuy.smartdevice.exception.LogsIOException;
import com.unibuy.smartdevice.exception.LogsMalformedURLException;
import com.unibuy.smartdevice.exception.LogsParseException;
import com.unibuy.smartdevice.exception.LogsSettingEmptyException;
import com.unibuy.smartdevice.exception.LogsUnsupportedOperationException;
import com.unibuy.smartdevice.structure.AccessCodeStructure;
import com.unibuy.smartdevice.structure.BuyStructure;
import com.unibuy.smartdevice.structure.FreeGiftStructure;
import com.unibuy.smartdevice.structure.InvoiceItemStructure;
import com.unibuy.smartdevice.structure.InvoiceStructure;
import com.unibuy.smartdevice.structure.MemberVerificationStructure;
import com.unibuy.smartdevice.structure.PostInvoiceByGreenStructure;
import com.unibuy.smartdevice.structure.ProductStructure;
import com.unibuy.smartdevice.database.ProductsDao;
import com.unibuy.smartdevice.structure.ReportAccessCodeStructure;
import com.unibuy.smartdevice.structure.ReportDispatchInfoStructure;
import com.unibuy.smartdevice.structure.ReportFlowInfoStructure;
import com.unibuy.smartdevice.structure.ReportFreeGiftCodeStructure;
import com.unibuy.smartdevice.structure.ReportInvoiceInfoStructure;
import com.unibuy.smartdevice.structure.ReportSlotListStructure;
import com.unibuy.smartdevice.structure.SettingStructure;
import com.unibuy.smartdevice.structure.SlotStructure;
import com.unibuy.smartdevice.tools.AppUtils;
import com.unibuy.smartdevice.tools.FormPostMainScheduler;
import com.unibuy.smartdevice.tools.FormPutMainScheduler;
import com.unibuy.smartdevice.tools.HandlerMain;
import com.unibuy.smartdevice.tools.HttpConnect;
import com.unibuy.smartdevice.tools.ToastHandlerMain;
import com.unibuy.smartdevice.tools.Tools;
import com.unibuy.smartdevice.ui.FontendActivity;
import com.unibuy.smartdevice.ui.RestartHostActivity;
import com.unibuy.smartdevice.ui.SettingActivity;
import com.unibuy.smartdevice.ui.devs.electric.ElectricFragment;
import com.unibuy.smartdevice.ui.dialog.CheckoutAccessCodeDialog;
import com.unibuy.smartdevice.ui.dialog.CheckoutFreeGiftCodeDialog;
import com.unibuy.smartdevice.ui.dialog.FontendPickupCodeDialog;
import com.unibuy.smartdevice.ui.tools.StringRefactoring;
import com.unibuy.smartdevice.ui.tools.VideoEoxPlayer;

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

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class HttpAPI {
    public enum SrcOption {
        TOAST(0),
        CHANGE_DISPATCH(6),
        CHANGE_BUY(7),
        REPORT_FLOW(8),
        ;

        private int option;

        public int getOption() {
            return option;
        }

        SrcOption(int option) {
            this.option = option;
        }
    }

    public enum Option {
        TOAST(0),
        DOWNLOAD_SETTING_RESPONSE(1),
        DOWNLOAD_PRODUCT_RESPONSE(2),
        DOWNLOAD_AD_RESPONSE(3),
        TRANSACTION_SUCCESSFUL(4),
        TRANSACTION_FAILED(5),
        REPORT_FLOW_RESPONSE(6),
        GREEN_INVOICE_RESPONSE(7),
        REPORT_INVOICE_RESPONSE(8),
        REPORT_DISPATCH_RESPONSE(9),
        ;

        private int option;

        public int getOption() {
            return option;
        }

        Option(int option) {
            this.option = option;
        }
    }

    public static final Map<Integer, Option> optionMap = new HashMap<>();

    static {
        for (Option option : Option.values()) {
            optionMap.put(option.getOption(), option);
        }
    }

    private Logs logs;
    private static String domainName = "https://demo-cloud.setdomains.work/";
    private String domainNameByUnibuy = domainName + "api/v1/app/";
    // private String domainNameByUnibuy = domainName + "Unibuy/api/app/";
    private String domainNameByAAT = domainName + "AAT/api/app/";
    // private String domainNameByAAT = domainName + "chi-hai-API/api/app/";
    private String esunpayApi = "https://mpayment.esuntrade.com/mPay/GatewayV2/API/V2/xTrade.ashx";
    private HandlerMain handlerMain;
    private HandlerMain srcHandlerMain;

    private boolean isReloadApi;

    public void setIsReloadApi(boolean isReloadApi) {
        this.isReloadApi = isReloadApi;
    }

    public boolean isReloadApi() {
        return isReloadApi;
    }

    public Logs getLogs() {
        return logs;
    }

    public HandlerMain getHandlerMain() {
        return handlerMain;
    }

    public HandlerMain getSrcHandlerMain() {
        return srcHandlerMain;
    }

    public HttpAPI(HandlerMain srcHandlerMain) {
        this.logs = new Logs(this.getClass());
        this.srcHandlerMain = srcHandlerMain;

        isReloadApi = false;

        handlerMain = new ToastHandlerMain(srcHandlerMain.getContext(), getLogs()) {
            @Override
            protected void execute(Context context, int commandCode, String message) {
                Option option = optionMap.get(commandCode);

                switch (option) {
                    case TOAST:
                        super.execute(context, commandCode, message);
                        break;
                    case DOWNLOAD_SETTING_RESPONSE:
                        if (isReloadApi()) {
                            getLogs().info("Reload Api download setting data");
                            try {
                                // uploadProductInfo();
                                downloadProductInfo();
                                getLogs().info("DOWNLOAD_SETTING_RESPONSE1");
                            } catch (LogsSettingEmptyException | LogsParseException e) {
                                // exception(context, e.getErrorCode(), e.getLocalizedMessage());
                                getLogs().warning(e);
                            }
                        } else {
                            super.execute(context, commandCode, message);
                            try {
                                downloadProductInfo();
                                getLogs().info("DOWNLOAD_SETTING_RESPONSE2");
                            } catch (LogsSettingEmptyException | LogsParseException e) {
                                // exception(context, e.getErrorCode(), e.getLocalizedMessage());
                                getLogs().warning(e);
                            }
                        }
                        break;
                    case DOWNLOAD_PRODUCT_RESPONSE:
                        if (isReloadApi()) {
                            getLogs().info("Reload Api download images data");
                            getSrcHandlerMain().start("HttpApi", RestartHostActivity.Option.IMAGE_RELOAD.getOption(),
                                    "image reload");
                        } else {
                            super.execute(context, commandCode, message);
                            try {
                                downloadAdvertisement();
                            } catch (LogsSettingEmptyException | LogsParseException e) {
                                // exception(context, e.getErrorCode(), e.getLocalizedMessage());
                                getLogs().warning(e);
                            }
                        }
                        break;
                    case DOWNLOAD_AD_RESPONSE:
                        if (isReloadApi()) {
                            super.execute(context, commandCode, message);
                            getLogs().info("Reload Api download ok");
                            getSrcHandlerMain().start("HttpApi", RestartHostActivity.Option.BACK_HOME.getOption(),
                                    "back home");
                        } else {
                            super.execute(context, commandCode, message);
                            getSrcHandlerMain().start(getClass().getSimpleName(),
                                    SettingActivity.Option.CHECK_AND_SAVE_STATUS.getOption(), "檢測中");
                        }
                        isReloadApi = false;
                        break;
                    case REPORT_FLOW_RESPONSE:
                        super.execute(context, commandCode, "回報成功");
                        MyApp.getInstance().getReportFlowInfoData().setReportFlowId(message);
                        MyApp.getInstance().getPostInvoiceByGreenData().setReportFlowId(message);
                        MyApp.getInstance().getReportInvoiceInfoData().setReportFlowId(message);
                        MyApp.getInstance().getReportFreeGiftCodeStructure().setReportFlowId(message);
                        getSrcHandlerMain().start(getSrcClassName(), SrcOption.REPORT_FLOW.getOption(), "report flow");
                        break;
                    case GREEN_INVOICE_RESPONSE:
                        try {
                            JSONObject jsonObject = new JSONObject(message);
                            String[] names = new String[] {
                                    "rtnCode", "rtnMsg", "invoiceNo", "invoiceDate", "randomNumber", "loveCode"
                            };

                            MyApp.getInstance().getReportInvoiceInfoData().setRtnCode(jsonObject.getString(names[0]));
                            MyApp.getInstance().getReportInvoiceInfoData().setRtnMsg(jsonObject.getString(names[1]));
                            MyApp.getInstance().getReportInvoiceInfoData().setInvoiceNo(jsonObject.getString(names[2]));
                            MyApp.getInstance().getReportInvoiceInfoData()
                                    .setInvoiceDate(jsonObject.getString(names[3]));
                            MyApp.getInstance().getReportInvoiceInfoData()
                                    .setRandomNumber(jsonObject.getString(names[4]));
                            MyApp.getInstance().getReportInvoiceInfoData().setLoveCode(jsonObject.getString(names[5]));

                            reportInvoiceInfo(MyApp.getInstance().getReportInvoiceInfoData());
                        } catch (JSONException e) {
                            getLogs().warning(e);
                        } catch (LogsSettingEmptyException | LogsParseException e) {
                            getLogs().warning(e);
                        }
                        break;
                    case REPORT_INVOICE_RESPONSE:
                        break;
                    case REPORT_DISPATCH_RESPONSE:
                        break;
                }
            }
        };
    }

    public void checkMachineInfo() throws LogsSettingEmptyException {
        if (MyApp.getInstance().getMachine().getApiKey().isEmpty() ||
                MyApp.getInstance().getMachine().getMachineID().isEmpty()) {
            throw new LogsSettingEmptyException(logs, "machine data empty");
        }
    }

    public void detectHost() throws LogsSettingEmptyException, LogsParseException {
        detectHost(new FormPostMainScheduler(getSrcHandlerMain()) {
            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        // {"message":"reboot","workID":"B010","status":"51"}
                        JSONObject receiveByJsonObject = new JSONObject(receive);
                        String workID = receiveByJsonObject.getString("workID");
                        int status = receiveByJsonObject.getInt("status");
                        String message = receiveByJsonObject.getString("message");

                        switch (status) {
                            case 49: // reload api
                                getSrcHandlerMain().start("HttpApi", FontendActivity.Option.RESET_SLOTNO.getOption(),
                                        "reset slot no.");
                                MyApp.getInstance().setDetectHost(false);
                                break;
                            case 51: // reboot
                                getSrcHandlerMain().start("HttpApi", FontendActivity.Option.RESTART_HOST.getOption(),
                                        "restart host");
                                break;
                            case 60: // reboot card machine
                                new MainActivity.ButtonNfcResetOnClick(handlerMain).start();
                                MyApp.getInstance().setDetectHost(false);
                                break;
                            case 61: // checkout
                                new MainActivity.ButtonNfcCheckoutOnClick(handlerMain).start();
                                MyApp.getInstance().setDetectHost(false);
                                break;
                            case 70: // unlock
                                MyApp.getInstance().setDetectHost(false);
                                break;
                            case 71: // lock
                                MyApp.getInstance().setDetectHost(false);
                                break;
                            default:
                                MyApp.getInstance().setDetectHost(false);
                        }
                    } catch (JSONException e) {
                        getLogs().warning(e);
                    }
                }
            }

            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }
        });
    }

    private void detectHost(FormPostMainScheduler formPostRunMain)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("key", MyApp.getInstance().getMachine().getApiKey());
            jsonObject.put("machine", MyApp.getInstance().getMachine().getMachineID());
            jsonObject.put("door", "2b");
            jsonObject.put("temperature", String.valueOf(DevXinYuanController.getTemperature()));
            jsonObject.put("M_Stus", "U4");
            jsonObject.put("M_Stus2", "1");
            jsonObject.put("M_Ver", DevXinYuanController.getVersion());

            formPostRunMain.start(domainNameByUnibuy + "machine/status/B010", jsonObject.toString(), null, null,
                    HttpConnect.ContentType.X_WWW_FORM_URLENCODEED);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void login(String account, String password) throws LogsSettingEmptyException, LogsParseException {
        MyApp.getInstance().setSuAccess(account);

        login(new FormPostMainScheduler(getHandlerMain()) {
            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        if (new JSONObject(receive).getString("message").equals("Success")) {
                            handlerMain.start(getClass().getSimpleName(), "@登入成功，請再次進入系統功能");
                        } else {
                            handlerMain.start(getClass().getSimpleName(), "@帳號或密碼錯誤");
                            MyApp.getInstance().setSuAccess("");
                        }
                    } catch (JSONException e) {
                        throw new RuntimeException(e);
                    }
                }
            }

            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }
        }, account, password);
    }

    private void login(FormPostMainScheduler formPostRunMain, String account, String password)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("machine", MyApp.getInstance().getMachine().getMachineID());
            jsonObject.put("Su_Account", account);
            jsonObject.put("Su_Password", password);
            jsonObject.put("ip", "192.168.1.100");
            jsonObject.put("type", "2");
            formPostRunMain.start(domainNameByUnibuy + "admin/login/B000", jsonObject.toString(), null, null,
                    HttpConnect.ContentType.X_WWW_FORM_URLENCODEED);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    // public void errorPost(int SlotID, String message, FormPostMainScheduler
    // formPostRunMain) throws LogsSettingEmptyException, LogsParseException {
    // checkMachineInfo();
    //
    // try {
    // JSONObject json = new JSONObject();
    // json.put("key", MyApp.getInstance().getMachine().getApiKey());
    // json.put("machine", MyApp.getInstance().getMachine().getMachineID());
    // json.put("tid", String.valueOf(SlotID));
    // json.put("type", message);
    // json.put("time", System.currentTimeMillis());
    // formPostRunMain.start(domainNameByUnibuy + "machine/error_msg/B013",
    // json.toString(), null, null, HttpConnect.ContentType.X_WWW_FORM_URLENCODEED);
    // } catch (JSONException e) {
    // throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
    // }
    // }

    public void errorPost(int slotId, String message) throws LogsSettingEmptyException, LogsParseException {
        errorPost(slotId, message, new FormPostMainScheduler(getSrcHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {

                if (responseCode == 200) {
                    try {
                        JSONObject response = new JSONObject(receive);
                        // 處理成功響應
                        Log.i("API", "Error post successful: " + response.toString());
                        // handlerMain.start(getClass().getSimpleName(), Option.TOAST.getOption(),
                        // "@B013 送出成功 code=" + responseCode);
                    } catch (JSONException e) {
                        Log.e("API", "Error parsing response", e);
                        handlerMain.start(getClass().getSimpleName(), Option.TOAST.getOption(), "@B013 回應解析錯誤");
                    }
                } else {
                    Log.e("API", "Error post failed with code: " + responseCode);
                    handlerMain.start(getClass().getSimpleName(), Option.TOAST.getOption(),
                            "@B013 送出失敗 code=" + responseCode);
                }
            }
        });
    }

    private void errorPost(int slotId, String message, FormPostMainScheduler formPostRunMain)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();
            json.put("key", MyApp.getInstance().getMachine().getApiKey());
            json.put("machine", MyApp.getInstance().getMachine().getMachineID());
            json.put("tid", String.valueOf(slotId));
            json.put("type", message);

            formPostRunMain.start(
                    domainNameByUnibuy + "machine/error_msg/B013",
                    json.toString(),
                    null,
                    null,
                    HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void downloadSetting() throws LogsParseException, LogsSettingEmptyException {
        downloadSetting(new FormPostMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        getLogs().info("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
                        MyApp.getInstance().getMachine().setMachineID("");

                        MyApp.getInstance().getEsunpay().setStoreID("");
                        MyApp.getInstance().getEsunpay().setTermID("");
                        MyApp.getInstance().getEsunpay().setHash("");

                        MyApp.getInstance().getGreenInvoice().setGreenMerchantID("");
                        MyApp.getInstance().getGreenInvoice().setGreenHashKey("");
                        MyApp.getInstance().getGreenInvoice().setGreenHashIV("");
                        MyApp.getInstance().getGreenInvoice().setGreenEmail("");

                        MyApp.getInstance().getGreenpaySetting().setAppId("");
                        MyApp.getInstance().getGreenpaySetting().setAppKey("");
                        MyApp.getInstance().getGreenpaySetting().setPartnerKey("");

                        MyApp.getInstance().getGreenpayMerchant().setLineMerchantId("");
                        MyApp.getInstance().getGreenpayMerchant().setPsMerchantId("");
                        MyApp.getInstance().getGreenpayMerchant().setEasyMerchantId("");
                        MyApp.getInstance().getGreenpayMerchant().setPiMerchantId("");
                        MyApp.getInstance().getGreenpayMerchant().setJkoMerchantId("");

                        JSONObject jsonObject = new JSONObject(receive).getJSONArray("data").getJSONObject(0);
                        if (!jsonObject.has("t050v01") && !jsonObject.getString("t050v01").isEmpty()) {
                            getLogs().error(ErrorCode.DATA_NOT_FOUND, "機器序號不存在");
                            return;
                        }

                        String machineId = jsonObject.getString("t050v01");
                        MyApp.getInstance().getMachine().setMachineID(machineId);

                        if (jsonObject.has("t050v41") && !jsonObject.getString("t050v41").isEmpty()) {
                            String qrStoreID = jsonObject.getString("t050v41");
                            MyApp.getInstance().getEsunpay().setStoreID(qrStoreID);
                            if (jsonObject.has("t050v42") && !jsonObject.getString("t050v42").isEmpty()) {
                                String qrTermID = jsonObject.getString("t050v42");
                                MyApp.getInstance().getEsunpay().setTermID(qrTermID);
                                if (jsonObject.has("t050v43") && !jsonObject.getString("t050v43").isEmpty()) {
                                    String qrHash = jsonObject.getString("t050v43");
                                    MyApp.getInstance().getEsunpay().setHash(qrHash);
                                }
                            }
                        }

                        if (jsonObject.has("t050v34") && !jsonObject.getString("t050v34").isEmpty()) {
                            String greenMerchantID = jsonObject.getString("t050v34");
                            MyApp.getInstance().getGreenInvoice().setGreenMerchantID(greenMerchantID);
                            if (jsonObject.has("t050v35") && !jsonObject.getString("t050v35").isEmpty()) {
                                String greenHashKey = jsonObject.getString("t050v35");
                                MyApp.getInstance().getGreenInvoice().setGreenHashKey(greenHashKey);
                                if (jsonObject.has("t050v36") && !jsonObject.getString("t050v36").isEmpty()) {
                                    String greenHashIV = jsonObject.getString("t050v36");
                                    MyApp.getInstance().getGreenInvoice().setGreenHashIV(greenHashIV);
                                    if (jsonObject.has("t050v38") && !jsonObject.getString("t050v38").isEmpty()) {
                                        String greenEmail = jsonObject.getString("t050v38");
                                        if (greenEmail.isEmpty()) {
                                            greenEmail = "@unibuy.com.tw";
                                        }
                                        MyApp.getInstance().getGreenInvoice().setGreenEmail(greenEmail);
                                    }
                                }
                            }
                        }

                        if (jsonObject.has("TP_APP_ID") && !jsonObject.getString("TP_APP_ID").isEmpty()
                                && jsonObject.has("TP_PARTNER_KEY")
                                && !jsonObject.getString("TP_PARTNER_KEY").isEmpty()) {
                            String tpAppId = jsonObject.getString("TP_APP_ID");
                            String tpAppKey = jsonObject.getString("TP_APP_KEY");
                            MyApp.getInstance().getGreenpaySetting().setAppId(tpAppId);
                            MyApp.getInstance().getGreenpaySetting().setAppKey(tpAppKey);

                            if (jsonObject.has("TP_PARTNER_KEY") && !jsonObject.getString("TP_PARTNER_KEY").isEmpty()) {
                                String tpPartnerkey = jsonObject.getString("TP_PARTNER_KEY");
                                MyApp.getInstance().getGreenpaySetting().setPartnerKey(tpPartnerkey);
                            }

                            if (jsonObject.has("TP_LINE_MERCHANT_ID")
                                    && !jsonObject.getString("TP_LINE_MERCHANT_ID").isEmpty()) {
                                String lineMerchantId = jsonObject.getString("TP_LINE_MERCHANT_ID");
                                MyApp.getInstance().getGreenpayMerchant().setLineMerchantId(lineMerchantId);
                            }

                            if (jsonObject.has("TP_PS_MERCHANT_ID")
                                    && !jsonObject.getString("TP_PS_MERCHANT_ID").isEmpty()) {
                                String psMerchantId = jsonObject.getString("TP_PS_MERCHANT_ID");
                                MyApp.getInstance().getGreenpayMerchant().setPsMerchantId(psMerchantId);
                            }

                            if (jsonObject.has("TP_EASY_MERCHANT_ID")
                                    && !jsonObject.getString("TP_EASY_MERCHANT_ID").isEmpty()) {
                                String easyMerchantId = jsonObject.getString("TP_EASY_MERCHANT_ID");
                                MyApp.getInstance().getGreenpayMerchant().setEasyMerchantId(easyMerchantId);
                            }

                            if (jsonObject.has("TP_PI_MERCHANT_ID")
                                    && !jsonObject.getString("TP_PI_MERCHANT_ID").isEmpty()) {
                                String piMerchantId = jsonObject.getString("TP_PI_MERCHANT_ID");
                                MyApp.getInstance().getGreenpayMerchant().setPiMerchantId(piMerchantId);
                            }

                            if (jsonObject.has("TP_JKO_MERCHANT_ID")
                                    && !jsonObject.getString("TP_JKO_MERCHANT_ID").isEmpty()) {
                                String jkoMerchantId = jsonObject.getString("TP_JKO_MERCHANT_ID");
                                MyApp.getInstance().getGreenpayMerchant().setJkoMerchantId(jkoMerchantId);
                            }
                        }

                        SettingsDao settingsDao = new SettingsDao(getSrcHandlerMain().getContext());
                        settingsDao.deleteAll();

                        settingsDao.insertOne(
                                new SettingStructure(MyApp.getInstance().getMachine().getClass().getSimpleName(),
                                        new String[] {
                                                MyApp.getInstance().getMachine().getApiKey(),
                                                MyApp.getInstance().getMachine().getMachineID()
                                        }));

                        settingsDao.insertOne(
                                new SettingStructure(MyApp.getInstance().getEsunpay().getClass().getSimpleName(),
                                        new String[] {
                                                MyApp.getInstance().getEsunpay().getStoreID(),
                                                MyApp.getInstance().getEsunpay().getTermID(),
                                                MyApp.getInstance().getEsunpay().getHash()
                                        }));

                        settingsDao.insertOne(
                                new SettingStructure(MyApp.getInstance().getGreenInvoice().getClass().getSimpleName(),
                                        new String[] {
                                                MyApp.getInstance().getGreenInvoice().getGreenMerchantID(),
                                                MyApp.getInstance().getGreenInvoice().getGreenHashKey(),
                                                MyApp.getInstance().getGreenInvoice().getGreenHashIV(),
                                                MyApp.getInstance().getGreenInvoice().getGreenEmail()
                                        }));

                        settingsDao.insertOne(new SettingStructure(
                                MyApp.getInstance().getGreenpaySetting().getClass().getSimpleName(),
                                new String[] {
                                        String.valueOf(MyApp.getInstance().getGreenpaySetting().getAppId()),
                                        MyApp.getInstance().getGreenpaySetting().getAppKey(),
                                        MyApp.getInstance().getGreenpaySetting().getPartnerKey(),
                                        MyApp.getInstance().getGreenpaySetting().getCtbcMerchantId(),
                                        MyApp.getInstance().getGreenpaySetting().getNcccMerchantId(),
                                        MyApp.getInstance().getGreenpaySetting().getTaishinMerchantId(),
                                        MyApp.getInstance().getGreenpaySetting().getEsunMerchantId(),
                                        MyApp.getInstance().getGreenpaySetting().getGpuseMerchantId()
                                }));

                        settingsDao.insertOne(new SettingStructure(
                                MyApp.getInstance().getGreenpayMerchant().getClass().getSimpleName(),
                                new String[] {
                                        MyApp.getInstance().getGreenpayMerchant().getLineMerchantId(),
                                        MyApp.getInstance().getGreenpayMerchant().getPsMerchantId(),
                                        MyApp.getInstance().getGreenpayMerchant().getEasyMerchantId(),
                                        MyApp.getInstance().getGreenpayMerchant().getPiMerchantId(),
                                        MyApp.getInstance().getGreenpayMerchant().getJkoMerchantId(),
                                        MyApp.getInstance().getGreenpayMerchant().getDirectMerchantId(),
                                        MyApp.getInstance().getGreenpayMerchant().getAppleMerchantId(),
                                        MyApp.getInstance().getGreenpayMerchant().getGoogleMerchantId(),
                                        MyApp.getInstance().getGreenpayMerchant().getSamsungMerchantId(),
                                        MyApp.getInstance().getGreenpayMerchant().getAtomeMerchantId()
                                }));

                        getLogs().info("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa0");
                        SettingActivity.updateProgressUI(10, "下載中...");
                        getLogs().info("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa10");
                        settingsDao.close();
                    } catch (JSONException e) {
                        getLogs().warning(e);
                    }

                    handlerMain.start(getClass().getSimpleName(), Option.DOWNLOAD_SETTING_RESPONSE.getOption(),
                            "儲存設定資料");
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "Response code error:" + responseCode);
                }
            }
        });
    }

    private void downloadSetting(FormPostMainScheduler formPostRunMain)
            throws LogsSettingEmptyException, LogsParseException {
        // checkMachineInfo();

        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("key", MyApp.getInstance().getMachine().getApiKey());
            jsonObject.put("machine", MyApp.getInstance().getMachine().getMachineID());
            formPostRunMain.start(domainNameByUnibuy + "machine/setting/B014", jsonObject.toString(), null, null,
                    HttpConnect.ContentType.X_WWW_FORM_URLENCODEED);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void downloadProductInfo() throws LogsSettingEmptyException, LogsParseException {
        downloadProductInfo(new FormPostMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        MyApp.getInstance().getProductList().clear();

                        JSONArray productItem = new JSONObject(receive).getJSONArray("data");
                        for (int i = 0; i < productItem.length(); i++) {
                            JSONObject productData = productItem.getJSONObject(i);

                            /*
                             * t060v09 售價
                             * t060v30 會員價
                             * t060v00 商品ID
                             * t060v11 貨道上限
                             * t063v03 機台的商品價格
                             * t060v01 "啵啵魚捲",
                             * t060v06 "https://unibuy.com.tw/Unibuy/dist/img/products/53317506.png",
                             */

                            getLogs().info("AAAAAAAAAAAAAAAAAAAAAAA" + productData);

                            if (productData.has("t060v00") &&
                                    productData.has("t060v06") &&
                                    productData.has("t060v01") &&
                                    productData.has("t063v03") &&
                                    productData.has("t060v09") &&
                                    productData.has("t060v30") &&
                                    productData.has("t060v11") &&
                                    productData.has("t060v40") &&
                                    productData.has("t060v41") &&
                                    productData.has("t060v01_en") &&
                                    productData.has("t060v01_jp")) {
                                String imageUrl = productData.getString("t060v06");
                                int machinePrice = Integer.parseInt(productData.getString("t063v03"));
                                int sellingPrice = Integer.parseInt(productData.getString("t060v09"));
                                int memberPrice = Integer.parseInt(productData.getString("t060v30"));
                                int slotUpperLimit = Integer.parseInt(productData.getString("t060v11"));
                                String marketingPlan = productData.getString("t060v40");
                                String materialCode = productData.getString("t060v41");
                                String productNameEn = productData.getString("t060v01_en");
                                String productNameJp = productData.getString("t060v01_jp");

                                MyApp.getInstance().getProductList().add(new ProductStructure(
                                        productData.getString("t060v00"),
                                        imageUrl,
                                        productData.getString("t060v01"),
                                        machinePrice,
                                        sellingPrice,
                                        memberPrice,
                                        slotUpperLimit,
                                        marketingPlan,
                                        materialCode,
                                        productNameEn,
                                        productNameJp));

                                try {
                                    MyApp.getInstance().getSlotDataByPid(productData.getString("t060v00"))
                                            .setProduct(new ProductStructure(
                                                    productData.getString("t060v00"),
                                                    imageUrl,
                                                    productData.getString("t060v01"),
                                                    machinePrice,
                                                    sellingPrice,
                                                    memberPrice,
                                                    slotUpperLimit,
                                                    marketingPlan,
                                                    materialCode,
                                                    productNameEn,
                                                    productNameJp));
                                } catch (LogsEmptyException e) {
                                    getLogs().ignore(e);
                                }
                            }
                        }

                        ProductsDao productsDao = new ProductsDao(getSrcHandlerMain().getContext());
                        productsDao.deleteAll();
                        logs.info("product delete size:" + productsDao.getAll().size());
                        productsDao.insertAll(MyApp.getInstance().getProductList());
                        productsDao.close();

                        SettingActivity.updateProgressUI(10, "下載中...");
                        getLogs().info("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa30");

                        handlerMain.start(getClass().getSimpleName(), Option.DOWNLOAD_PRODUCT_RESPONSE.getOption(),
                                "成功載入" + MyApp.getInstance().getProductList().size() + "筆商品資料");
                    } catch (JSONException e) {
                        getLogs().error(ErrorCode.JSON_FORMAT_ERROR, e.getLocalizedMessage());
                    }
                }
            }
        });
    }

    public void uploadProductInfo() throws LogsSettingEmptyException, LogsParseException {
        uploadProductInfo(new FormPostMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        JSONArray productItem = new JSONObject(receive).getJSONArray("data");
                        for (int i = 0; i < productItem.length(); i++) {
                            JSONObject productData = productItem.getJSONObject(i);

                            /*
                             * t060v09 售價
                             * t060v30 會員價
                             * t060v00 商品ID
                             * t060v11 貨道上限
                             * t063v03 機台的商品價格
                             * t060v01 "啵啵魚捲",
                             * t060v06 "https://unibuy.com.tw/Unibuy/dist/img/products/53317506.png",
                             */

                            if (productData.has("t060v00") &&
                                    productData.has("t060v06") &&
                                    productData.has("t060v01") &&
                                    productData.has("t063v03") &&
                                    productData.has("t060v09") &&
                                    productData.has("t060v30") &&
                                    productData.has("t060v11") &&
                                    productData.has("t060v40") &&
                                    productData.has("t060v41") &&
                                    productData.has("t060v01_en") &&
                                    productData.has("t060v01_jp")) {
                                String imageUrl = productData.getString("t060v06");
                                int machinePrice = Integer.parseInt(productData.getString("t063v03"));
                                int sellingPrice = Integer.parseInt(productData.getString("t060v09"));
                                int memberPrice = Integer.parseInt(productData.getString("t060v30"));
                                int slotUpperLimit = Integer.parseInt(productData.getString("t060v11"));
                                String marketingPlan = productData.getString("t060v40");
                                String materialCode = productData.getString("t060v41");
                                String productNameEn = productData.getString("t060v01_en");
                                String productNameJp = productData.getString("t060v01_jp");

                                Map<String, Integer> productIndexs = new HashMap<>();

                                for (int index = 0; index < MyApp.getInstance().getProductList().size(); index++) {
                                    ProductStructure product = MyApp.getInstance().getProductList().get(index);
                                    productIndexs.put(product.getProductID(), index);
                                }

                                int index = productIndexs.get(productData.getString("t060v00"));
                                MyApp.getInstance().getProductList().get(index)
                                        .setProductName(productData.getString("t060v01"));
                                MyApp.getInstance().getProductList().get(index).setProductImg(imageUrl);
                                MyApp.getInstance().getProductList().get(index).setMachinePrice(machinePrice);
                                MyApp.getInstance().getProductList().get(index).setSellingPrice(sellingPrice);
                                MyApp.getInstance().getProductList().get(index).setMemberPrice(memberPrice);
                                MyApp.getInstance().getProductList().get(index).setSlotUpperLimit(slotUpperLimit);
                                MyApp.getInstance().getProductList().get(index).setMarketingPlan(marketingPlan);
                                MyApp.getInstance().getProductList().get(index).setMaterialCode(materialCode);
                                MyApp.getInstance().getProductList().get(index).setProductNameEn(productNameEn);
                                MyApp.getInstance().getProductList().get(index).setProductNameJp(productNameJp);

                                MyApp.getInstance().getUploadProductList().add(new ProductStructure(
                                        productData.getString("t060v00"),
                                        imageUrl,
                                        productData.getString("t060v01"),
                                        machinePrice,
                                        sellingPrice,
                                        memberPrice,
                                        slotUpperLimit,
                                        marketingPlan,
                                        materialCode,
                                        productNameEn,
                                        productNameJp));
                            }
                        }

                        ProductsDao productsDao = new ProductsDao(getSrcHandlerMain().getContext());
                        productsDao.deleteAll();
                        logs.info("product delete size:" + productsDao.getAll().size());
                        productsDao.insertAll(MyApp.getInstance().getProductList());
                        productsDao.close();

                        handlerMain.start(getClass().getSimpleName(), Option.DOWNLOAD_PRODUCT_RESPONSE.getOption(),
                                "成功載入" + MyApp.getInstance().getProductList().size() + "筆商品資料");
                    } catch (JSONException e) {
                        getLogs().error(ErrorCode.JSON_FORMAT_ERROR, e.getLocalizedMessage());
                    }
                }
            }
        });
    }

    private void downloadProductInfo(FormPostMainScheduler formPostRunMain)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();
            json.put("key", MyApp.getInstance().getMachine().getApiKey());
            json.put("machine", MyApp.getInstance().getMachine().getMachineID());
            formPostRunMain.start(domainNameByUnibuy + "machine/do_sell_new/B012_new", json.toString(), null, null,
                    HttpConnect.ContentType.X_WWW_FORM_URLENCODEED);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    private void uploadProductInfo(FormPostMainScheduler formPostRunMain)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();
            json.put("key", MyApp.getInstance().getMachine().getApiKey());
            json.put("machine", MyApp.getInstance().getMachine().getMachineID());
            formPostRunMain.start(domainNameByUnibuy + "machine/do_sell_update/B012_update", json.toString(), null,
                    null, HttpConnect.ContentType.X_WWW_FORM_URLENCODEED);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void downloadAdvertisement() throws LogsSettingEmptyException, LogsParseException {
        downloadAdvertisement(new FormPostMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        MyApp.getInstance().getFontendAdUrlString().clear();

                        JSONArray adItem = new JSONObject(receive).getJSONArray("data");
                        SettingsDao settingsDao = new SettingsDao(getSrcHandlerMain().getContext());
                        settingsDao.deleteWhere(VideoEoxPlayer.class.getSimpleName());

                        SettingActivity.updateProgressUI(20, "下載中...");
                        int adnum = adItem.length();

                        for (int i = 0; i < adItem.length(); i++) {
                            JSONObject adData = adItem.getJSONObject(i);

                            String urlString = adData.getString("t070v04");
                            String flagString = adData.getString("t070v03");
                            MyApp.getInstance().getFontendAdUrlString().add(urlString);

                            /* 將下面跑迴圈的程式，移到這裡就直接 */
                            if (isReloadApi()) {
                                handlerMain.start(getClass().getSimpleName(), "下載一筆廣告中");
                                getLogs().info("下載一筆廣告中:" + urlString);
                            } else {
                                handlerMain.start(getClass().getSimpleName(), "下載一筆廣告中");
                            }

                            HttpConnect httpConnect = new HttpConnect();
                            File file = httpConnect.download(urlString, true);

                            // 記錄兩個欄位: url 及 flag
                            settingsDao.insertOne(new SettingStructure(
                                    VideoEoxPlayer.class.getSimpleName(),
                                    new String[] { urlString, flagString }));

                            int persent = 20 + (i * 80 / adnum);
                            SettingActivity.updateProgressUI(persent, "下載中...");
                        }

                        // 要下載廣告
                        // for (String urlString : MyApp.getInstance().getFontendAdUrlString()) {
                        // if (isReloadApi()) {
                        // handlerMain.start(getClass().getSimpleName(), "下載一筆廣告中");
                        // getLogs().info("下載一筆廣告中:" + urlString);
                        // } else {
                        // handlerMain.start(getClass().getSimpleName(), "下載一筆廣告中");
                        // }
                        //
                        // HttpConnect httpConnect = new HttpConnect();
                        // File file = httpConnect.download(urlString, true);
                        //
                        // settingsDao.insertOne(new SettingStructure(
                        // VideoEoxPlayer.class.getSimpleName(),
                        // new String[]{
                        // urlString
                        // }));
                        // }

                        handlerMain.start(getClass().getSimpleName(), "下載完成");
                        handlerMain.start(getClass().getSimpleName(), Option.DOWNLOAD_AD_RESPONSE.getOption(),
                                "共載入" + MyApp.getInstance().getFontendAdUrlString().size() + "筆廣告資料");

                        settingsDao.close();

                        // handlerMain.start(getClass().getSimpleName(),
                        // Option.DOWNLOAD_AD_RESPONSE.getOption(), "共載入" +
                        // MyApp.getInstance().getFontendAdUrlString().size() + "筆廣告資料");
                    } catch (JSONException e) {
                        getLogs().error(ErrorCode.JSON_FORMAT_ERROR, "video url path format error");
                    } catch (LogsFileNullException | LogsMalformedURLException | LogsEmptyException
                            | LogsIOException e) {
                        getLogs().warning(e);
                    }
                }
            }
        });
    }

    private void downloadAdvertisement(FormPostMainScheduler formPostRunMain)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();
            json.put("key", MyApp.getInstance().getMachine().getApiKey());
            json.put("machine", MyApp.getInstance().getMachine().getMachineID());
            formPostRunMain.start(domainNameByUnibuy + "machine/ad/B005", json.toString(), null, null,
                    HttpConnect.ContentType.X_WWW_FORM_URLENCODEED);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void reportFlowInfo(ReportFlowInfoStructure data) throws LogsSettingEmptyException, LogsParseException {
        reportFlowInfo(new FormPostMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    // 儲存回傳的 message 為 reportFlowId
                    try {
                        JSONObject receiveByJsonObject = new JSONObject(receive);
                        String workApi = receiveByJsonObject.getString("workApi");
                        int status = receiveByJsonObject.getInt("status");
                        getLogs().info("bbbbbbbbbbbbbbbbbbbbbb status" + status);
                        String message = receiveByJsonObject.getString("message");
                        getLogs().info("bbbbbbbbbbbbbbbbbbbbbb message" + message);

                        if (status == 0) {
                            handlerMain.start(getClass().getSimpleName(), Option.REPORT_FLOW_RESPONSE.getOption(),
                                    message);
                        } else {
                            getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "(555)" + message);
                        }
                    } catch (JSONException e) {
                        getLogs().warning(e);
                    }
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "reportFlowInfo responseCode:" + responseCode);
                }
            }
        },
                String.valueOf(data.getFlowType()),
                data.getFlowSendInfo(),
                data.getFlowRequestInfo(),
                data.getProductId(),
                String.valueOf(data.getTotalPrice()),
                data.getInvoiceInfo(),
                data.getOrderId(),
                data.getFlowBarCode(),
                String.valueOf(data.getFlowStatusType()),
                String.valueOf(data.getGiveChange()),
                String.valueOf(data.getUsePoints()),
                data.getShoppingCartInfoByJsonArray());
    }

    private void reportFlowInfo(FormPostMainScheduler formPostRunMain, String flowType, String flowSendInfo,
            String flowRequestInfo, String productId, String totalPrice, String invoiceInfo, String orderId,
            String flowBarCcde, String flowStatusType, String giveChange, String usePoints,
            JSONArray shoppingCartInfoByJsonArray) throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());

        try {
            JSONObject json = new JSONObject();
            json.put("req1", MyApp.getInstance().getMachine().getApiKey());
            json.put("req2", MyApp.getInstance().getMachine().getMachineID());
            json.put("req3", String.valueOf(flowType));
            json.put("req4", flowSendInfo);
            // json.put("req5", flowRequestInfo);
            json.put("req5", removeNonPrintable(flowRequestInfo));
            json.put("req6", productId);
            json.put("req7", totalPrice);
            json.put("req8", invoiceInfo);
            json.put("req9", orderId);
            json.put("req10", flowBarCcde);
            json.put("req11", sdf.format(new Date()));
            json.put("req12", flowStatusType);
            json.put("req13", giveChange);
            json.put("req14", usePoints);
            json.put("req15", ""); // 系統保留不使用
            json.put("req16", shoppingCartInfoByJsonArray);
            formPostRunMain.start(domainNameByAAT + "B600", json.toString(), null, null, HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public String removeNonPrintable(String input) {
        if (input == null)
            return null;
        return input.replaceAll("[^\\x20-\\x7E]", "");
    }

    public void reportInvoiceInfo(ReportInvoiceInfoStructure data)
            throws LogsSettingEmptyException, LogsParseException {
        getLogs().info("sendData:" + data.toString());

        reportInvoiceInfo(new FormPostMainScheduler(getHandlerMain()) {

            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    // 儲存回傳的 message 為 reportFlowId
                    try {
                        JSONObject receiveByJsonObject = new JSONObject(receive);
                        String workApi = receiveByJsonObject.getString("workApi");
                        int status = receiveByJsonObject.getInt("status");
                        String message = receiveByJsonObject.getString("message");

                        if (status == 0) {
                            handlerMain.start(getClass().getSimpleName(), Option.REPORT_INVOICE_RESPONSE.getOption(),
                                    message);
                        } else {
                            getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "(634)" + message);
                        }
                    } catch (JSONException e) {
                        getLogs().warning(e);
                    }
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "reportInvoiceInfo responseCode:" + responseCode);
                }
            }
        },
                data.getReportFlowId(),
                data.getRtnCode(),
                data.getRtnMsg(),
                data.getInvoiceNo(),
                data.getInvoiceDate(),
                data.getRandomNumber(),
                data.getLoveCode());
    }

    private void reportInvoiceInfo(FormPostMainScheduler formPostRunMain, String reportFlowId, String rtnCode,
            String rtnMsg, String invoiceNo, String invoiceDate, String randomNumber, String loveCode)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();
            json.put("req1", MyApp.getInstance().getMachine().getApiKey());
            json.put("req2", MyApp.getInstance().getMachine().getMachineID());
            json.put("req3", String.valueOf(reportFlowId));
            json.put("req4", rtnCode);
            json.put("req5", rtnMsg);
            json.put("req6", invoiceNo);
            json.put("req7", invoiceDate);
            json.put("req8", randomNumber);
            json.put("req9", loveCode);

            getLogs().info("sendData:" + json.toString());

            formPostRunMain.start(domainNameByAAT + "B601", json.toString(), null, null, HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void checkAccessCode(AccessCodeStructure data) throws LogsSettingEmptyException, LogsParseException {
        checkAccessCode(new FormPostMainScheduler(getSrcHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        // {"data":[{"res1":"46357"}],"message":"執行命令成功","workID":"B024","status":"00"}
                        // {"message":"passCode error","workID":"B024","status":"74"}
                        JSONObject receiveByJsonObject = new JSONObject(receive);
                        String workID = receiveByJsonObject.getString("workID");
                        String status = receiveByJsonObject.getString("status");
                        String message = receiveByJsonObject.getString("message");

                        if (status.equals("00")) {
                            JSONArray jsonArray = receiveByJsonObject.getJSONArray("data");
                            String res1 = jsonArray.getJSONObject(0).getString("res1");

                            MyApp.getInstance().getReportFlowInfoData().setReportFlowId(res1);
                            MyApp.getInstance().getReportFlowInfoData()
                                    .setFlowBarCode(MyApp.getInstance().getAccessCodeStructure().getPassCode());

                            MyApp.getInstance().getReportAccessCodeStructure().setAccessCodeId(res1);
                            MyApp.getInstance().getReportAccessCodeStructure()
                                    .setPassCode(MyApp.getInstance().getAccessCodeStructure().getPassCode());
                            handlerMain.start(handlerMain.getLogs().getClassName(),
                                    CheckoutAccessCodeDialog.Option.CHANGE_DISPATCH.getOption(), "change dispatch");
                        } else {
                            handlerMain.start(handlerMain.getLogs().getClassName(),
                                    CheckoutAccessCodeDialog.Option.SET_STATUS_TEXT.getOption(), message);
                        }
                    } catch (JSONException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "reportInvoiceInfo responseCode:" + responseCode);
                }
            }
        },
                data.getPassCode());
    }

    private void checkAccessCode(FormPostMainScheduler formPostRunMain, String passCode)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();

            json.put("key", MyApp.getInstance().getMachine().getApiKey());
            json.put("machine", MyApp.getInstance().getMachine().getMachineID());
            json.put("passCode", passCode);

            formPostRunMain.start(domainNameByUnibuy + "sell/PassCode/B024", json.toString(), null, null,
                    HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void freeGiftCode(FreeGiftStructure data) throws LogsSettingEmptyException, LogsParseException {
        freeGiftCode(new FormPostMainScheduler(getSrcHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        // {"data":[{"res1":"46357"}],"message":"執行命令成功","workID":"B024","status":"00"}
                        // {"message":"passCode error","workID":"B024","status":"74"}
                        JSONObject receiveByJsonObject = new JSONObject(receive);
                        String workID = receiveByJsonObject.getString("workID");
                        String status = receiveByJsonObject.getString("status");
                        String message = receiveByJsonObject.getString("message");

                        if (status.equals("00")) {
                            JSONArray jsonArray = receiveByJsonObject.getJSONArray("data");
                            String res1 = jsonArray.getJSONObject(0).getString("res1"); // put id
                            String res2 = jsonArray.getJSONObject(0).getString("res2"); // mode
                            String res3 = jsonArray.getJSONObject(0).getString("res3"); // 出貨商品代碼
                            String res4 = jsonArray.getJSONObject(0).getString("res4"); // 折扣金額
                            String res5 = jsonArray.getJSONObject(0).getString("res5"); // 折扣折數

                            MyApp.getInstance().getReportFlowInfoData().setReportFlowId(res1);
                            MyApp.getInstance().getReportFlowInfoData()
                                    .setFlowBarCode(MyApp.getInstance().getFreeGiftStructure().getPassCode());

                            MyApp.getInstance().getReportFreeGiftCodeStructure().setFreeGiftId(res1);
                            MyApp.getInstance().getReportFreeGiftCodeStructure()
                                    .setPassCode(MyApp.getInstance().getFreeGiftStructure().getPassCode());
                            MyApp.getInstance().getReportFreeGiftCodeStructure().setMode(Integer.parseInt(res2));
                            MyApp.getInstance().getReportFreeGiftCodeStructure().setProductId(res3);
                            MyApp.getInstance().getReportFreeGiftCodeStructure()
                                    .setDiscountAmount(Integer.parseInt(res4));
                            MyApp.getInstance().getReportFreeGiftCodeStructure()
                                    .setDiscountPercentage(Float.parseFloat(res5));

                            if (Integer.parseInt(res2) == 0 && !res3.isEmpty()) {
                                try {
                                    SlotStructure slotProduct = MyApp.getInstance().getSlotDataByPid(res3);
                                    BuyStructure buyProduct = new BuyStructure(slotProduct.getField(),
                                            slotProduct.getSlot(), slotProduct.getProduct(), 1);
                                    buyProduct.setFreeGift(true);
                                    MyApp.getInstance().getBuyList().add(buyProduct);
                                } catch (LogsEmptyException e) {
                                    getLogs().warning(e);
                                }
                            }

                            handlerMain.start(handlerMain.getLogs().getClassName(),
                                    CheckoutFreeGiftCodeDialog.Option.CHANGE_BUY.getOption(), "change buy");
                        } else {
                            handlerMain.start(handlerMain.getLogs().getClassName(),
                                    CheckoutFreeGiftCodeDialog.Option.SET_STATUS_TEXT.getOption(), message);
                        }
                    } catch (JSONException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "reportInvoiceInfo responseCode:" + responseCode);
                }
            }
        },
                data.getPassCode());
    }

    private void freeGiftCode(FormPostMainScheduler formPostRunMain, String passCode)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();

            json.put("key", MyApp.getInstance().getMachine().getApiKey());
            json.put("machine", MyApp.getInstance().getMachine().getMachineID());
            json.put("passCode", passCode);

            formPostRunMain.start(domainNameByUnibuy + "sell/Freebie/B027", json.toString(), null, null,
                    HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void reportAccessCode(ReportAccessCodeStructure data) throws LogsSettingEmptyException, LogsParseException {
        reportAccessCode(new FormPutMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    handlerMain.start(getClass().getSimpleName(), receive);
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "reportInvoiceInfo responseCode:" + responseCode);
                }
            }
        },
                data.getAccessCodeId(),
                data.getPassCode(),
                String.valueOf(data.getSlot()),
                data.getProductId());
    }

    private void reportAccessCode(FormPutMainScheduler formPutRunMain, String accessCodeId, String passCode, String rid,
            String pid) throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();

            json.put("key", MyApp.getInstance().getMachine().getApiKey());
            json.put("machine", MyApp.getInstance().getMachine().getMachineID());
            json.put("id", accessCodeId);
            json.put("passCode", passCode);
            json.put("rid", rid);
            json.put("pid", pid);
            json.put("type", "2");
            json.put("time", System.currentTimeMillis());

            getLogs().info("sendData:" + json.toString());

            formPutRunMain.start(domainNameByUnibuy + "sell/PassCode/B024", json.toString(), null, null,
                    HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void reportFreeGiftCode(ReportFreeGiftCodeStructure data)
            throws LogsSettingEmptyException, LogsParseException {
        reportFreeGiftCode(new FormPutMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    handlerMain.start(getClass().getSimpleName(), receive);
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "reportInvoiceInfo responseCode:" + responseCode);
                }
            }
        },
                data.getFreeGiftId(),
                data.getPassCode(),
                String.valueOf(data.getSlot()),
                String.valueOf(data.getReportFlowId()),
                data.getProductId(),
                String.valueOf(data.getMoney()));
    }

    private void reportFreeGiftCode(FormPutMainScheduler formPutRunMain, String freeGiftCodeId, String passCode,
            String tid, String reportFlowId, String pid, String money)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();

            json.put("key", MyApp.getInstance().getMachine().getApiKey());
            json.put("machine", MyApp.getInstance().getMachine().getMachineID());
            json.put("id", freeGiftCodeId);
            json.put("passCode", passCode);
            json.put("tid", tid);
            json.put("type", "2");
            json.put("paymentID", reportFlowId);
            json.put("pid", pid);
            json.put("money", money);

            getLogs().info("sendData:" + json.toString());

            formPutRunMain.start(domainNameByUnibuy + "sell/Freebie/B027", json.toString(), null, null,
                    HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void reportDispatchInfo(ReportDispatchInfoStructure data)
            throws LogsSettingEmptyException, LogsParseException {
        reportDispatchInfo(new FormPostMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        JSONObject receiveByJsonObject = new JSONObject(receive);
                        String workApi = receiveByJsonObject.getString("workApi");
                        int status = receiveByJsonObject.getInt("status");
                        String message = receiveByJsonObject.getString("message");

                        if (status == 0) {
                            // handlerMain.start(Option.REPORT_DISPATCH_RESPONSE.getOption(), message);
                        } else {
                            getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "(697)" + message);
                        }
                    } catch (JSONException e) {
                        getLogs().error(ErrorCode.JSON_FORMAT_ERROR, "B602 json format error");
                    }
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "reportDispatchInfo responseCode:" + responseCode);
                }
            }
        },
                data.getReportFlowId(),
                String.valueOf(data.getFlowType()),
                data.getProductId(),
                String.valueOf(data.getSlot()),
                String.valueOf(data.getTotalPrice()),
                data.getOrderId(),
                String.valueOf(data.getRemaining()),
                data.getMamberBarCcde(),
                data.getVoucherId(),
                String.valueOf(data.getDispatchStatusType()),
                String.valueOf(data.getOwnPrice()),
                String.valueOf(data.getUsePoints()));
    }

    private void reportDispatchInfo(FormPostMainScheduler formPostRunMain, String reportFlowId, String flowType,
            String productId, String slot, String fullPrice, String orderId, String remaining, String mamberBarCcde,
            String VoucherId, String dispatchStatusType, String ownPrice, String usePoints)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());

        try {
            JSONObject json = new JSONObject();
            json.put("req1", MyApp.getInstance().getMachine().getApiKey());
            json.put("req2", MyApp.getInstance().getMachine().getMachineID());
            json.put("req3", String.valueOf(reportFlowId));
            json.put("req4", flowType);
            json.put("req5", productId);
            json.put("req6", slot);
            json.put("req7", fullPrice);
            json.put("req8", orderId);
            json.put("req9", remaining);
            json.put("req10", mamberBarCcde);
            json.put("req11", sdf.format(new Date()));
            json.put("req12", VoucherId);
            json.put("req13", dispatchStatusType);
            json.put("req14", "");
            json.put("req15", ownPrice);
            json.put("req16", usePoints);

            getLogs().info("reportDispatchInfo:" + json.toString());

            formPostRunMain.start(domainNameByAAT + "B602", json.toString(), null, null, HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void memberVerification(MemberVerificationStructure data)
            throws LogsSettingEmptyException, LogsParseException {
        memberVerification(new FormPostMainScheduler(getSrcHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        JSONObject receiveByJsonObject = new JSONObject(receive);
                        String workApi = receiveByJsonObject.getString("workApi");
                        int status = receiveByJsonObject.getInt("status");
                        String message = receiveByJsonObject.getString("message");

                        switch (MyApp.getInstance().getMemberVerificationStructure().getVerificationType()) {
                            case 0: // 商品ID>0 (有點擊商品)
                                break;
                            case 1: // req3 為空字串且req4=0 (會員純驗證)
                                break;
                            case 2: // req3=0 (會員兌換商品列表)
                                if (status == 103) {
                                    String pid = receiveByJsonObject.getString("pid");

                                    MyApp.getInstance().getReportFlowInfoData().setReportFlowId(pid);
                                    MyApp.getInstance().getReportFlowInfoData().setFlowBarCode(
                                            MyApp.getInstance().getMemberVerificationStructure().getMemberBarCode());

                                    handlerMain.start(handlerMain.getLogs().getClassName(),
                                            FontendPickupCodeDialog.Option.CHANGE_BUY.getOption(), pid);
                                } else {
                                    handlerMain.start(handlerMain.getLogs().getClassName(),
                                            FontendPickupCodeDialog.Option.SET_STATUS_TEXT.getOption(), message);
                                }
                                break;
                            case 3: // 線上訂單現下結帳
                                break;
                            case 4: // 會員證品
                                break;
                        }
                    } catch (JSONException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        },
                data.getProductId(),
                String.valueOf(data.getProductPrice()),
                data.getMemberBarCode(),
                String.valueOf(data.getVerificationType()));
    }

    private void memberVerification(FormPostMainScheduler formPostRunMain, String productId, String productPrice,
            String memberBarCode, String verificationType) throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();
            json.put("req1", MyApp.getInstance().getMachine().getApiKey());
            json.put("req2", MyApp.getInstance().getMachine().getMachineID());
            json.put("req3", productId);
            json.put("req4", productPrice);
            json.put("req5", memberBarCode);
            json.put("req6", verificationType);
            formPostRunMain.start(domainNameByAAT + "B650", json.toString(), null, null, HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void reportElectricInfo(JSONArray electricInfoByJsonArray)
            throws LogsSettingEmptyException, LogsParseException {
        reportElectricInfo(new FormPostMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        JSONArray jsonArray = new JSONObject(receive).getJSONArray("pending");
                        getLogs().info("pending date:" + jsonArray.toString());

                        // ](200)receive:{"workApi":"/api/app/B710","status":100,"message":"Success","pending":[{"pid":"53341352","cid":"1","status":"3","num":"3600.0"}]}
                        for (int index = 0; index < jsonArray.length(); index++) {
                            JSONObject jsonObject = jsonArray.getJSONObject(index);
                            int slot = Integer.parseInt(jsonObject.getString("cid"));
                            int state = Integer.parseInt(jsonObject.getString("status"));
                            float second = Float.parseFloat(jsonObject.getString("num"));

                            SlotStructure slotData = MyApp.getInstance().getSlotData(SlotField.ELECTRIC.getField(),
                                    slot);

                            if (state == 3) {
                                if (second > 0) {
                                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.TAIWAN);
                                    Date timeEpiredDate = new Date();
                                    if (slotData.getOtherData().has("timeExpired")) {
                                        try {
                                            timeEpiredDate = sdf
                                                    .parse(slotData.getOtherData().getString("timeExpired"));
                                        } catch (JSONException | ParseException e) {
                                            getLogs().warning(e);
                                        }
                                    }

                                    String timeEpiredString = sdf.format(timeEpiredDate);
                                    getLogs().debug("timeEpiredString1:" + timeEpiredString);

                                    Calendar calendar = Calendar.getInstance();
                                    calendar.setTime(timeEpiredDate);
                                    calendar.add(Calendar.MINUTE, (int) ((second / 60) + 1));
                                    timeEpiredDate = calendar.getTime();
                                    timeEpiredString = sdf.format(timeEpiredDate);
                                    getLogs().debug("timeEpiredString2:" + timeEpiredString);

                                    try {
                                        slotData.getOtherData().put("timeExpired", timeEpiredString);
                                    } catch (JSONException e) {
                                        getLogs().warning(e);
                                    }
                                } else {
                                    if (second < 0) {
                                        slotData.setLock(!slotData.isLock());
                                    } else {
                                        slotData.setLock(false);
                                        slotData.getOtherData().remove("timeExpired");
                                    }
                                }

                                getHandlerMain().start(getLogs().getClassName(),
                                        ElectricFragment.Option.SHIPPED_PRODUCT.getOption(), "SHIPPED_PRODUCT");
                            }
                        }
                    } catch (JSONException e) {
                        getLogs().error(ErrorCode.JSON_FORMAT_ERROR, e.getLocalizedMessage());
                    } catch (LogsEmptyException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }, electricInfoByJsonArray);
    }

    private void reportElectricInfo(FormPostMainScheduler formPostRunMain, JSONArray electricInfoByJsonArray)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();
            json.put("req1", MyApp.getInstance().getMachine().getApiKey());
            json.put("req2", MyApp.getInstance().getMachine().getMachineID());
            json.put("req3", electricInfoByJsonArray);

            getLogs().info("reportElectricInfo:" + json.toString());

            formPostRunMain.start(domainNameByAAT + "B710", json.toString(), null, null, HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void postInvoiceByGreen(PostInvoiceByGreenStructure data)
            throws LogsSettingEmptyException, LogsParseException {
        postInvoiceByGreen(new FormPostMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        String dataString = new JSONObject(receive).getString("Data");
                        getLogs().info("dataString date:" + dataString);

                        String AESDecode = Tools.fromAES(dataString,
                                MyApp.getInstance().getGreenInvoice().getGreenHashKey(),
                                MyApp.getInstance().getGreenInvoice().getGreenHashIV());
                        String urlDecode = URLDecoder.decode(AESDecode, Key.STRING_CHARSET_NAME);

                        getLogs().info("urlDecode date:" + urlDecode);

                        JSONObject jsonDecodeData = new JSONObject(urlDecode);
                        String rtnCode = String.valueOf(jsonDecodeData.getInt("RtnCode"));
                        String rtnMsg = jsonDecodeData.getString("RtnMsg");
                        String invoiceNo = jsonDecodeData.getString("InvoiceNo");
                        String invoiceDate = jsonDecodeData.getString("InvoiceDate");
                        String randomNumber = jsonDecodeData.getString("RandomNumber");
                        String loveCode = MyApp.getInstance().getPostInvoiceByGreenData().getInvoiceData()
                                .getLoveCode();

                        getLogs().info("decode date:" + jsonDecodeData);

                        handlerMain.start(getClass().getSimpleName(), Option.GREEN_INVOICE_RESPONSE.getOption(),
                                new StringRefactoring(new Object[] {
                                        rtnCode, rtnMsg, invoiceNo, invoiceDate, randomNumber, loveCode
                                }) {
                                    @Override
                                    public String refactoring(Object[] source) {
                                        String[] names = new String[] {
                                                "rtnCode", "rtnMsg", "invoiceNo", "invoiceDate", "randomNumber",
                                                "loveCode"
                                        };

                                        JSONObject jsonObject = new JSONObject();
                                        for (int index = 0; index < names.length; index++) {
                                            try {
                                                jsonObject.put(names[index], source[index]);
                                            } catch (JSONException e) {
                                                throw new RuntimeException(e);
                                            }
                                        }

                                        return jsonObject.toString();
                                    }
                                }.toString());
                    } catch (InvalidAlgorithmParameterException | NoSuchPaddingException | IllegalBlockSizeException
                            | UnsupportedEncodingException | NoSuchAlgorithmException | BadPaddingException
                            | InvalidKeyException e) {
                        getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "(870)" + e.getLocalizedMessage());
                    } catch (JSONException e) {
                        getLogs().error(ErrorCode.JSON_FORMAT_ERROR, e.getLocalizedMessage());
                    }
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "postInvoiceByGreen responseCode:" + responseCode);
                }
            }
        },
                data.getOrderId(),
                data.getReportFlowId(),
                data.getTotalPrice(),
                data.getInvoiceData(),
                data.getInvoiceItem());
    }

    private void postInvoiceByGreen(FormPostMainScheduler formPostRunMain, String orderId, String reportFlowId,
            int totalPrice, InvoiceStructure invoiceData, List<InvoiceItemStructure> invoiceItem)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        if (MyApp.getInstance().getGreenInvoice().getGreenMerchantID().isEmpty() ||
                MyApp.getInstance().getGreenInvoice().getGreenHashKey().isEmpty() ||
                MyApp.getInstance().getGreenInvoice().getGreenHashIV().isEmpty()) {
            throw new LogsSettingEmptyException(logs, "GreenInvoice not setting");
        }

        try {
            long unixTime = System.currentTimeMillis() / 1000;
            JSONArray salesArray = new JSONArray();

            for (InvoiceItemStructure invoiceItemData : invoiceItem) {
                JSONObject invoiceByJsonObject = new JSONObject();
                invoiceByJsonObject.put("ItemSeq", invoiceItemData.getItemSeq());
                invoiceByJsonObject.put("ItemName", invoiceItemData.getItemName());
                invoiceByJsonObject.put("ItemCount", invoiceItemData.getItemCount());
                invoiceByJsonObject.put("ItemWord", invoiceItemData.getItemWord());
                invoiceByJsonObject.put("ItemPrice", invoiceItemData.getItemPrice());
                invoiceByJsonObject.put("ItemTaxType", invoiceItemData.getItemTaxType());
                invoiceByJsonObject.put("ItemAmount", invoiceItemData.getItemAmount());
                invoiceByJsonObject.put("ItemRemark", invoiceItemData.getItemRemark());
                salesArray.put(invoiceByJsonObject);
            }

            JSONObject json = new JSONObject();
            json.put("MerchantID", MyApp.getInstance().getGreenInvoice().getGreenMerchantID());
            String relateNumber = UUID.randomUUID().toString().replace("-", "").substring(0, 30);
            // String relateNumber = MyApp.getInstance().getMachine().getMachineID() +
            // reportFlowId + System.currentTimeMillis();
            json.put("RelateNumber", relateNumber);
            json.put("CustomerID", MyApp.getInstance().getMachine().getMachineID());
            json.put("Print", invoiceData.getCustomerIdentifier().isEmpty() ? "0" : "1");
            json.put("CustomerIdentifier", invoiceData.getCustomerIdentifier());
            json.put("CustomerName",
                    invoiceData.getCustomerIdentifier().isEmpty() ? "" : invoiceData.getCustomerIdentifier());
            json.put("CustomerAddr",
                    invoiceData.getCustomerIdentifier().isEmpty() ? "" : invoiceData.getCustomerIdentifier());
            json.put("CustomerPhone", invoiceData.getPhone());
            json.put("CustomerEmail",
                    invoiceData.getPhone().isEmpty() ? MyApp.getInstance().getGreenInvoice().getGreenEmail() : "");
            json.put("ClearanceMark", "");
            json.put("Donation", "0");
            json.put("LoveCode", "");

            getLogs().info("發票請求 RelateNumber=" + relateNumber);
            getLogs().info("Request JSON=" + json.toString());

            int CarrierType = 0;
            if (invoiceData.getLoveCode().length() > 2) {
                json.put("Donation", "1");
                json.put("LoveCode", invoiceData.getLoveCode());

                StringBuilder sb = new StringBuilder();
                sb.append(orderId);
                String str = MyApp.getInstance().getGreenInvoice().getGreenEmail();
                sb.append(str.substring(str.indexOf(64)));

                json.put("CustomerEmail", sb.toString());
                CarrierType = 1;
            } else if (invoiceData.getCarrier().length() == 8) {
                CarrierType = 3;
            } else if (invoiceData.getCarrier().length() == 16) {
                CarrierType = 2;
            } else if (invoiceData.getCustomerIdentifier().isEmpty()) {
                CarrierType = 1;
            }

            Object obj;
            if (CarrierType == 0) {
                obj = "";
            } else {
                obj = CarrierType + "";
            }

            json.put("CarrierType", obj);
            json.put("CarrierNum", CarrierType > 1 ? invoiceData.getCarrier().replace("+", " ") : "");
            json.put("TaxType", "1");
            json.put("SpecialTaxType", 0);

            json.put("SalesAmount", totalPrice);
            json.put("InvoiceRemark", "發票備註:無");
            json.put("InvType", "07");
            json.put("vat", "1");
            json.put("Items", salesArray);

            getLogs().info("json data:" + json.toString());

            String urlEncode = URLEncoder.encode(json.toString(), Key.STRING_CHARSET_NAME);
            String AESEncode = Tools.toAES(urlEncode, MyApp.getInstance().getGreenInvoice().getGreenHashKey(),
                    MyApp.getInstance().getGreenInvoice().getGreenHashIV());

            JSONObject RqHeader = new JSONObject();
            RqHeader.put("Timestamp", unixTime);
            RqHeader.put("Revision", "3.2.9");

            JSONObject jsonSendData = new JSONObject();
            jsonSendData.put("PlatformID", "");
            jsonSendData.put("RqHeader", RqHeader);
            jsonSendData.put("MerchantID", MyApp.getInstance().getGreenInvoice().getGreenMerchantID());
            jsonSendData.put("Data", AESEncode);

            formPostRunMain.start("https://einvoice.ecpay.com.tw/B2CInvoice/Issue", jsonSendData.toString(), null, null,
                    HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(getLogs(), ErrorCode.JSON_FORMAT_ERROR);
        } catch (UnsupportedEncodingException | InvalidAlgorithmParameterException | NoSuchPaddingException
                | IllegalBlockSizeException | NoSuchAlgorithmException | BadPaddingException | InvalidKeyException e) {
            throw new LogsParseException(getLogs(), e.getLocalizedMessage());
        }
    }

    public void esunpay(String barcode, int totalPrice)
            throws LogsSettingEmptyException, LogsUnsupportedOperationException {
        esunpay(barcode, totalPrice, new FormPostMainScheduler(getSrcHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int resposeCode, String receive, HandlerMain handlerMain) {
                MyApp.getInstance().getReportFlowInfoData().setFlowRequestInfo(receive);
                if (resposeCode == 200) {
                    try {
                        String dataDecoder = URLDecoder.decode(receive, Key.STRING_CHARSET_NAME);
                        JSONObject jsonObject = new JSONObject(dataDecoder);
                        String responseStatus = jsonObject.getString("Status");
                        getLogs().info("Status:" + responseStatus);
                        if (responseStatus.equals("S")) {
                            // 完成交易
                            getHandlerMain().start(getClass().getSimpleName(),
                                    Option.TRANSACTION_SUCCESSFUL.getOption(), dataDecoder.replace("\t", "ⓣ"));
                        } else {
                            // Status:F 交易失敗
                            getHandlerMain().start(getClass().getSimpleName(), Option.TRANSACTION_FAILED.getOption(),
                                    jsonObject.getString("ErrorDesc"));
                        }
                    } catch (UnsupportedEncodingException e) {
                        getLogs().error(ErrorCode.ENCODING_AND_DECODING_ERROR, e.getLocalizedMessage());
                    } catch (JSONException e) {
                        getLogs().error(ErrorCode.JSON_FORMAT_ERROR, e.getLocalizedMessage());
                    }
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "responseCode:" + resposeCode);
                }
            }
        });
    }

    private void esunpay(String barcode, int totalPrice, FormPostMainScheduler formPostRunMain)
            throws LogsSettingEmptyException, LogsUnsupportedOperationException {
        if (MyApp.getInstance().getEsunpay().getStoreID().isEmpty() ||
                MyApp.getInstance().getEsunpay().getTermID().isEmpty() ||
                MyApp.getInstance().getEsunpay().getHash().isEmpty()) {
            throw new LogsSettingEmptyException(logs, "esunpay data is empty");
        }

        JSONObject TransactionData = new JSONObject();
        try {
            TransactionData.put("StoreID", MyApp.getInstance().getEsunpay().getStoreID());
            TransactionData.put("TermID", MyApp.getInstance().getEsunpay().getTermID());
            TransactionData.put("Timeout", 20);
            TransactionData.put("BuyerID", barcode);
            TransactionData.put("OrderNo", MyApp.getInstance().getReportFlowInfoData().getOrderId());
            TransactionData.put("OrderCurrency", "TWD");
            TransactionData.put("OrderAmount", Integer.valueOf(totalPrice).intValue());
            TransactionData.put("OrderDT", Tools.getTimeStampByNow("yyyyMMddhhmmss"));
            TransactionData.put("OrderTitle", MyApp.getInstance().getReportFlowInfoData().getOrderId());
            TransactionData.put("BuyerPaymentType", 1);

            logs.info("transactionData data:" + TransactionData.toString());

            // "tradeapipayment{'StoreID':'xxxx', }sfsdgsdgwegg"
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("Type", "tradeapi");
            jsonObject.put("Action", "payment");
            jsonObject.put("TransactionData", URLEncoder.encode(TransactionData.toString(), Key.STRING_CHARSET_NAME));
            String HashDigest = Tools.getSHA256(jsonObject.getString("Type") + jsonObject.getString("Action")
                    + jsonObject.getString("TransactionData") + MyApp.getInstance().getEsunpay().getHash());
            jsonObject.put("HashDigest", HashDigest);
            logs.info("send data:" + jsonObject.toString());
            MyApp.getInstance().getReportFlowInfoData().setFlowSendInfo(jsonObject.toString());

            String dataEncode = URLEncoder.encode(jsonObject.toString(), Key.STRING_CHARSET_NAME);

            formPostRunMain.start(esunpayApi, dataEncode, null, null, HttpConnect.ContentType.X_WWW_FORM_URLENCODEED);
        } catch (JSONException e) {
            throw new LogsSettingEmptyException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        } catch (UnsupportedEncodingException e) {
            throw new LogsUnsupportedOperationException(logs, ErrorCode.ENCODING_AND_DECODING_ERROR, e);
        }
    }

    public void linepay(String barcode, int totalPrice) throws LogsParseException, LogsSettingEmptyException {
        linepay(barcode, totalPrice, new FormPostMainScheduler(getSrcHandlerMain()) {
            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                MyApp.getInstance().getReportFlowInfoData().setFlowRequestInfo(receive);
                if (responseCode == 200) {
                    try {
                        JSONObject receiveByJsonObject = new JSONObject(receive);
                        getLogs().info("dataString date:" + receiveByJsonObject.toString());

                        if (receiveByJsonObject.has("status")
                                && receiveByJsonObject.getString("status").equals("success")) {
                            getHandlerMain().start(getClass().getSimpleName(),
                                    Option.TRANSACTION_SUCCESSFUL.getOption(), "transaction_successful");
                        } else {
                            getHandlerMain().start(getClass().getSimpleName(), Option.TRANSACTION_FAILED.getOption(),
                                    "transaction_failed");
                        }
                    } catch (JSONException e) {
                        getLogs().error(ErrorCode.JSON_FORMAT_ERROR, e.getLocalizedMessage());
                    }
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "responseCode:" + responseCode);
                }
            }

            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }
        });
    }

    private void linepay(String barcode, int totalPrice, FormPostMainScheduler formPostRunMain)
            throws LogsParseException, LogsSettingEmptyException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();
            json.put("key", MyApp.getInstance().getMachine().getApiKey());
            json.put("machine", MyApp.getInstance().getMachine().getMachineID());
            json.put("barcode", barcode);
            json.put("amount", totalPrice);
            json.put("payway", "credit");
            json.put("test", 0);

            getLogs().info("linepay:" + json.toString());

            MyApp.getInstance().getReportFlowInfoData().setFlowSendInfo(json.toString());

            formPostRunMain.start(StarCloudAPI.domainNameByNewHost + "api/linepay/pay", json.toString(), null, null,
                    HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void reportSlotList(ReportSlotListStructure data) throws LogsSettingEmptyException, LogsParseException {
        reportSlotList(new FormPutMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    handlerMain.start(getClass().getSimpleName(), receive);
                } else {
                    getLogs().error(ErrorCode.NETWORK_UNKNOWN_ERROR, "reportInvoiceInfo responseCode:" + responseCode);
                }
            }
        },
                data.getAccount(),
                data.getVmctype());
    }

    private void reportSlotList(FormPutMainScheduler formPutRunMain, String account, String vmctype)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONArray jsonArray = new JSONArray();
            for (SlotField slotField : SlotField.values()) {
                for (SlotStructure slotData : MyApp.getInstance().getSlotList(slotField.getField())) {
                    JSONObject productData = new JSONObject();
                    // getLogs().info("aaaaaaaaaaaaaaaaaaaaaaa"+slotData.getProduct().getProductID());
                    try {
                        if (!slotData.getProduct().getProductID().equals("?")
                                || slotData.getProduct().getProductID() != "?") {
                            productData.put("t060v00", slotData.getProduct().getProductID());
                            productData.put("num", String.valueOf(slotData.getCount()));
                            productData.put("tid", String.valueOf(slotData.getSlot()));// +
                                                                                       // slotField.getField());//這一行將Field把它隱藏起來，怕多出一個類別碼，客戶不好判斷
                            productData.put("status", "0");
                        } else {
                            continue;
                        }
                    } catch (JSONException e) {
                        throw new RuntimeException(e);
                    }
                    jsonArray.put(productData);
                }
            }

            JSONObject jsonObject2 = new JSONObject();
            jsonObject2.put("key", MyApp.getInstance().getMachine().getApiKey());
            jsonObject2.put("machine", MyApp.getInstance().getMachine().getMachineID());
            jsonObject2.put("account", account);
            // String vmcType = myApp.AppConfig.getString("vmcType", "");
            // if (vmcType.equals("XinYuan")) {
            // String subVMC = myApp.AppConfig.getString("subVMC1", "");
            jsonObject2.put("vmcType", vmctype);
            /*
             * } else if (vmcType.equals("Easivend")) {
             * String[] subVMC1 = myApp.AppConfig.getString("subVMC1", "").split(",");
             * String[] subVMC2 = myApp.AppConfig.getString("subVMC2", "").split(",");
             * jsonObject2.put("vmcType", subVMC1[0] + "," + subVMC2[0]);
             * }
             */
            jsonObject2.put("data", jsonArray);

            getLogs().info("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=" + jsonObject2.toString());

            formPutRunMain.start(domainNameByUnibuy + "products/supplementary/B009", jsonObject2.toString(), null, null,
                    HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void deviceReport() throws LogsSettingEmptyException, LogsParseException {
        deviceReport(new FormPostMainScheduler(getSrcHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        JSONObject response = new JSONObject(receive);
                        // 處理成功響應

                    } catch (JSONException e) {

                    }
                } else {

                }
            }
        });
    }

    private void deviceReport(FormPostMainScheduler formPostRunMain)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();
            json.put("key", MyApp.getInstance().getMachine().getApiKey());
            json.put("machine", MyApp.getInstance().getMachine().getMachineID());

            formPostRunMain.start(
                    domainNameByUnibuy + "machine/device_status/B022",
                    json.toString(),
                    null,
                    null,
                    HttpConnect.ContentType.JSON);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

    public void reportSlotPost() throws LogsSettingEmptyException, LogsParseException {
        reportSlotPost(new FormPostMainScheduler(getHandlerMain()) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void response(int responseCode, String receive, HandlerMain handlerMain) {
                if (responseCode == 200) {
                    try {
                        JSONObject receiveByJsonObject = new JSONObject(receive);
                        JSONArray deliveryItem = receiveByJsonObject.getJSONArray("data");

                        JSONObject deliveryData = deliveryItem.getJSONObject(0);
                        /*
                         * req1 執行命令id
                         * req2 貨道id
                         */

                        int slotid = Integer.parseInt(deliveryData.getString("tid"));
                        int slotnum = Integer.parseInt(deliveryData.getString("num"));

                        getLogs().info("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + slotid + "   " + slotnum);

                        slotid = slotid;

                        SlotsDao slotsDao = new SlotsDao(handlerMain.getContext());
                        slotsDao.updateCount(0, slotid, slotnum);// 更新該貨道的數量(庫存)
                        slotsDao.close();

                        AppUtils.resetApp(handlerMain.getContext());

                    } catch (JSONException e) {
                        getLogs().error(ErrorCode.JSON_FORMAT_ERROR, e.getLocalizedMessage());
                    }
                }
            }
        });
    }

    private void reportSlotPost(FormPostMainScheduler formPostRunMain)
            throws LogsSettingEmptyException, LogsParseException {
        checkMachineInfo();

        try {
            JSONObject json = new JSONObject();
            json.put("key", MyApp.getInstance().getMachine().getApiKey());
            json.put("machine", MyApp.getInstance().getMachine().getMachineID());
            formPostRunMain.start(domainNameByUnibuy + "machine/reload_msg/B017", json.toString(), null, null,
                    HttpConnect.ContentType.X_WWW_FORM_URLENCODEED);
        } catch (JSONException e) {
            throw new LogsParseException(logs, ErrorCode.JSON_FORMAT_ERROR, e);
        }
    }

}
