package com.tomastc.bta500;

import static android.view.View.GONE;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static com.tomastc.bta500.lib.ErrorCode.E100;
import static com.tomastc.bta500.lib.ErrorCode.E101;
import static com.tomastc.bta500.lib.ErrorCode.E200;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

import com.keyence.autoid.sdk.scan.DecodeResult;
import com.tomastc.bta500.lib.ActionListenerCallback;
import com.tomastc.bta500.lib.ErrorCode;
import com.tomastc.bta500.lib.KeyMapping;
import com.tomastc.bta500.lib.LabelInfo;
import com.tomastc.bta500.lib.NstErrorLog;
import com.tomastc.bta500.lib.Scanner;
import com.tomastc.bta500.lib.Settings;
import com.tomastc.bta500.lib.SpinAdapter;
import com.tomastc.bta500.lib.common.AsyncHttpClient;
import com.tomastc.bta500.lib.common.Utils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;

import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

public class ComponentCheckProgressActivity extends Scanner {

    private Button btn_back;
    private TextView lbl_shift_code;
    private EditText txt_mo_no, txt_parent_item_no, txt_parent_item_desc;
    private TableLayout tbl_child_items;
    private ScrollView scr_contents;
    private RelativeLayout popupLayout1, popupLayout2;

    private boolean screen_locked = false;

    private Map<String, JSONObject> mapItems = new LinkedHashMap<>();

    private void keepErrorLog(String mo_no, LabelInfo labelInfo, ErrorCode errorCode) {

        try {
            // Prepare error information
            NstErrorLog nstErrorLog = new NstErrorLog(
                    mo_no == null || (mo_no != null && mo_no.isEmpty()) ? "-" : mo_no
                    , labelInfo == null ? "-" : labelInfo.getChild_item_no()
                    , labelInfo == null ? "-" : labelInfo.getSlip_no()
                    , labelInfo == null || (labelInfo != null && labelInfo.getLabel_qty() == null) ? 0 : labelInfo.getLabel_qty()
                    , labelInfo == null || (labelInfo != null && labelInfo.getActual_qty() == null) ? 0 : labelInfo.getActual_qty()
                    , errorCode.getDet()
                    , getString(R.string.COMPO_PGM_NAME)
                    , Settings.getUserLogin_list().get(0).getUser_id()
                    , String.valueOf(errorCode.getId())
            );

            JSONObject json = new JSONObject();
            json.put("cmd", "nst-error-log");
            json.put("NST_ERROR_LOG", nstErrorLog.toString());

            new AsyncHttpClient(getApplicationContext()
                    ,Settings.getMgmtList().get("web_api") + "/nst_compo_detail.php"
                    , json.toString()
            ) {
                @Override
                public void onFinished(String response, int resp_code) {
                    Log.d(getString(R.string.tag), "response: " + response);
                }

                @Override
                protected void onError(Exception e) {
                }
            }.execute();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void redrawCheckProgressTable() {

        Log.d(getString(R.string.tag), "redrawCheckProgressTable() called");

        try {
            Context context = getApplicationContext();

            DecimalFormat formatter = new DecimalFormat("#,###.00");

            // clear tbl_serial_scan
            tbl_child_items.removeAllViews();

            // Sorting item no (key)
            String[] keys = mapItems.keySet().toArray(new String[0]);
            Arrays.sort(keys);

            int i = 0;
            for (String key : keys) {
                JSONObject item = mapItems.get(key);

                int bgColor = Color.argb((++i%2) == 0 ? 0x30 : 0x10, 0xaa, 0xaa, 0xaa);
                int bgColorStatus = bgColor;
                int bgColorYellow = Color.argb(0xff, 0xff, 0xff, 0x00);
                int bgColorGreen = Color.argb(0xff, 0x00, 0xff, 0x00);
                int textColor = Color.argb(0xff, 0x00, 0x00, 0x00);

                //JSONObject item = mapItems.get(key);
                String child_item_no = item.getString("CHILD_ITEM_NO");
                Log.d(getString(R.string.tag), "found child item -> " + child_item_no);
                String child_item_desc = item.getString("CHILD_ITEM_DESC");
                String dmd_qty = formatter.format(item.getDouble("Dmd_qty"));
                String outstanding_qty = formatter.format(item.getDouble("Outstanding_qty"));
                String uom = item.getString("UOM"); // unit
                String status = "";
                if (item.getString("Sts_cd").trim().equals("1")) {
                    status = "OK";
                    bgColorStatus = bgColorGreen;
                } else if (item.getDouble("Inp_qty") > 0) {
                    status = "IN PROCESS";
                    bgColorStatus = bgColorYellow;
                }

                TableRow tableRow = new TableRow(context);
                TableRow.LayoutParams layoutParams = new TableRow.LayoutParams(
                        TableLayout.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT);
                layoutParams.setMargins(1,1,1,1);
                tableRow.setLayoutParams(layoutParams);

                TextView textView = new TextView(context);
                textView.setText(child_item_no);
                textView.setTextSize(10);
                textView.setWidth(65);
                textView.setHeight(30);
                textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
                textView.setBackgroundColor(bgColor);
                textView.setTextColor(textColor);
                textView.setPadding(1,5,0,0);
                textView.setLayoutParams(layoutParams);
                tableRow.addView(textView);

                textView = new TextView(context);
                textView.setText(child_item_desc);
                textView.setTextSize(10);
                textView.setWidth(60);
                textView.setHeight(30);
                textView.setBackgroundColor(bgColor);
                textView.setTextColor(textColor);
                textView.setPadding(1,5,0,0);
                textView.setLayoutParams(layoutParams);
                tableRow.addView(textView);

                textView = new TextView(context);
                textView.setText(dmd_qty);
                textView.setTextSize(10);
                textView.setWidth(38);
                textView.setHeight(30);
                textView.setBackgroundColor(bgColor);
                textView.setTextColor(textColor);
                textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
                textView.setPadding(1,5,0,0);
                textView.setLayoutParams(layoutParams);
                tableRow.addView(textView);

                textView = new TextView(context);
                textView.setText(outstanding_qty);
                textView.setTextSize(10);
                textView.setWidth(38);
                textView.setHeight(30);
                textView.setBackgroundColor(bgColor);
                textView.setTextColor(textColor);
                textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
                textView.setPadding(1,5,0,0);
                textView.setLayoutParams(layoutParams);
                tableRow.addView(textView);

                textView = new TextView(context);
                textView.setText(uom);
                textView.setTextSize(10);
                textView.setWidth(33);
                textView.setHeight(30);
                textView.setBackgroundColor(bgColor);
                textView.setTextColor(textColor);
                textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
                textView.setPadding(1,5,0,0);
                textView.setLayoutParams(layoutParams);
                tableRow.addView(textView);

                textView = new TextView(context);
                textView.setText(status);
                textView.setTextSize(10);
                textView.setWidth(59);
                textView.setHeight(30);
                textView.setBackgroundColor(bgColorStatus);
                textView.setTextColor(textColor);
                textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
                textView.setPadding(1,5,0,0);
                textView.setLayoutParams(layoutParams);
                tableRow.addView(textView);

                Log.d(getString(R.string.tag), "Add textview -> " + child_item_no);

                tbl_child_items.addView(tableRow);

                // scroll to last item added
                //scr_contents.post(new ScrollToTrick(scr_contents, tableRow));
            }

        } catch (Exception e) {
            Log.e(getString(R.string.tag), e.getMessage());
            e.printStackTrace();
        }

    }

    @Override
    public void processData(String data, DecodeResult.Result result, String codeType) {
        try {

            Log.d(getString(R.string.tag), String.format("data read[%d bytes]: %s", data.length(), data));
            // always hide keyboard after scan
            //Utils.hideKeyboardFrom(getApplicationContext(), default_view);


            // reset buffering
            reset();

            // Format: MO_QR_CODE e.g. 23034038
            // Length: 8
            // Other:

            if (data.length()!=8) {
                keepErrorLog(null, null, E100);
                alertError(E100.toString(), new ActionListenerCallback() {
                    @Override
                    public void onActionSuccess(String successMessage) throws Exception {

                    }

                    @Override
                    public void onActionFailure(Throwable throwableError) {

                    }
                }, screen_locked=false);
                throw new Exception(E100.toString());
            }

            loadProgressTable(data.trim()); // MO Number QRcode

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Load child items from server
     * @param mo_no
     * @return amount of items found
     */
    private void loadProgressTable(String mo_no) {

        //key manual check userid --> add to map
        try {
            JSONObject json = new JSONObject();
            json.put("cmd", "get-check-progress-table");
            json.put("mo_no", mo_no);

            new AsyncHttpClient(getApplicationContext()
                    ,Settings.getMgmtList().get("web_api") + "/nst_compo_detail.php"
                    , json.toString()
            ) {
                @Override
                public void onFinished(String response, int resp_code) {
                    Log.d(getString(R.string.tag), "response: " + response);
                    Toast.makeText(getApplicationContext(), "Component detail downloaded.", Toast.LENGTH_LONG).show();
                    // update mapItems
                    try {
                        JSONArray jArray = new JSONArray(response);
                        Log.d(getString(R.string.tag), "response json length: " + jArray.length());
                        if (jArray.length() != 0) { // keep current inquiry items
                            mapItems = new HashMap<>();
                            for (int i=0; i<jArray.length(); i++) {
                                JSONObject jobj = jArray.getJSONObject(i);
                                String key = jobj.getString("CHILD_ITEM_NO");
                                mapItems.put(key, jobj);
                                Log.d(getString(R.string.tag), "Put item to list : " + key);
                            }

                            Log.d(getString(R.string.tag), "After add to items list, length:: " + mapItems.values().size());

                            // Display master detail
                            JSONObject jtmp = jArray.getJSONObject(0);
                            txt_mo_no.setText(mo_no);
                            txt_parent_item_no.setText(jtmp.getString("PARENT_ITEM_NO"));
                            txt_parent_item_desc.setText(
                                    jtmp.getString("PARENT_ITEM_DESC") == "null"
                                    ? "-"
                                    : jtmp.getString("PARENT_ITEM_DESC")
                            );

                            redrawCheckProgressTable();

                        } else {
                            keepErrorLog(null, null, E101);
                            alertError(E101.toString(), new ActionListenerCallback() {
                                @Override
                                public void onActionSuccess(String successMessage) throws Exception {
                                }

                                @Override
                                public void onActionFailure(Throwable throwableError) {

                                }
                            }, screen_locked=false);
                            throw new Exception(E101.toString());
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                protected void onError(Exception e) {
                    keepErrorLog(null, null, E200);
                    alertError(E200.toString(), new ActionListenerCallback() {
                        @Override
                        public void onActionSuccess(String successMessage) throws Exception {

                        }

                        @Override
                        public void onActionFailure(Throwable throwableError) {

                        }
                    }, screen_locked=false);
                    e.printStackTrace();
                }
            }.execute();
        } catch (JSONException e) {
            Log.e(getString(R.string.tag), e.getMessage());
        }
    }

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_component_check_progress);

        default_view = (EditText) findViewById(R.id.txt_tmp);

        btn_back = (Button) findViewById(R.id.btn_back);

        txt_mo_no = (EditText) findViewById(R.id.txt_mo_no);
        txt_parent_item_no = (EditText) findViewById(R.id.txt_parent_item_no);
        txt_parent_item_desc = (EditText) findViewById(R.id.txt_parent_item_desc);
        tbl_child_items = (TableLayout) findViewById(R.id.tbl_child_items);

        lbl_shift_code = (TextView) findViewById(R.id.lbl_shift_code);
        lbl_shift_code.setText("Shift code : " + Settings.getShiftCode().getId());

        popupLayout1 = (RelativeLayout) findViewById(R.id.popupLayout1);
        popupLayout2 = (RelativeLayout) findViewById(R.id.popupLayout2);
        scr_contents = (ScrollView) findViewById(R.id.scr_contents);

        if (!getIntent().getExtras().getString("mo_no").isEmpty()) {
            txt_mo_no.setText(getIntent().getExtras().getString("mo_no"));
            txt_parent_item_no.setText(getIntent().getExtras().getString("parent_item_no"));
            txt_parent_item_desc.setText(getIntent().getExtras().getString("parent_item_desc"));
            loadProgressTable(txt_mo_no.getText().toString());
        }

        btn_back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }

    private void reset() {
        txt_mo_no.setText("");
        txt_parent_item_no.setText("");
        txt_parent_item_desc.setText("");
        tbl_child_items.removeAllViews();
        mapItems.clear();
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        Log.d(getString(R.string.tag), String.format("keyCode: %d", keyCode) );
        if (keyCode >= KeyMapping.P1.getId()
                && keyCode <= KeyMapping.P4.getId())
        {
            if (popupLayout1.getVisibility() == VISIBLE) {
                Button btnOk = (Button) findViewById(R.id.popupLayout1_btn1);
                Button btnConfirm = (Button) findViewById(R.id.popupLayout1_btn2);
                switch (KeyMapping.fromId(keyCode)) {
                    case P1:
                        btnOk.performClick();
                        break;

                    case P2:
                        btnConfirm.performClick();
                        break;

                }
            } else {
                switch (KeyMapping.fromId(keyCode)) {
                    case P1:
                        btn_back.performClick();
                        break;

                }
            }
        } else if (keyCode == KeyMapping.ENT.getId()) {
            if (popupLayout2.getVisibility() == VISIBLE) {
                Button btn = (Button) findViewById(R.id.popupLayout2_btn1);
                btn.requestFocus();
                btn.performClick();
            }
            return false;
        }

        return super.onKeyUp(keyCode, event);
    }


    private void confirmation(String msg, int color, boolean isBtnOkShow
            , ActionListenerCallback callback, SpinAdapter spinAdapter) {


        Log.d(getString(R.string.tag), "confirmation() " + msg);

        RelativeLayout layout = popupLayout1;
        TextView lbl_msg = (TextView) findViewById(R.id.popupLayout1_txt);
        Button btnOk = (Button) findViewById(R.id.popupLayout1_btn1);
        Button btnConfirm = (Button) findViewById(R.id.popupLayout1_btn2);
        Spinner ddl_options = (Spinner) findViewById(R.id.ddl_options);

        ddl_options.setVisibility (spinAdapter == null ? GONE : VISIBLE);

        if (spinAdapter != null) {
            ddl_options.setAdapter(spinAdapter);
        }

        lbl_msg.setText(msg);
        lbl_msg.setTextColor(color);
        btnOk.setVisibility(isBtnOkShow ? VISIBLE : INVISIBLE);
        layout.setVisibility(VISIBLE);
        btnOk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    layout.setVisibility(GONE);
                    callback.onActionFailure(null);
                } catch (Exception e) {
                    e.printStackTrace();
                };
            }
        });
        btnConfirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    layout.setVisibility(GONE);
                    if (spinAdapter != null) {
                        callback.onActionSuccess(
                                spinAdapter.getItem(
                                        ddl_options.getSelectedItemPosition()
                                ).getName()
                        );
                    } else {
                        callback.onActionSuccess("");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                };
            }
        });

    }

    private void alertOk(String msg, ActionListenerCallback callback) {
        // Enable the ENT key down, it must current focus on multiline text input
        default_view.requestFocus();

        RelativeLayout layout = popupLayout2;
        TextView lbl_msg = (TextView) findViewById(R.id.popupLayout2_txt);
        Button btn = (Button) findViewById(R.id.popupLayout2_btn1);
        EditText txt_leader_password = (EditText) findViewById(R.id.txt_leader_password);

        lbl_msg.setText(msg);
        lbl_msg.setTextColor(getColor(R.color.black));
        layout.setVisibility(VISIBLE);
        txt_leader_password.setVisibility(GONE);
        btn.setBackgroundColor(getColor(R.color.green));
        btn.setTextColor(getColor(R.color.white));
        btn.setText("OK [ENT]");
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // stop activity
                try {
                    layout.setVisibility(GONE);
                    callback.onActionSuccess("");
                } catch (Exception e) {
                    // In case if item is the top most view
                };
            }
        });

    }

    private void alertError(String msg, ActionListenerCallback callback, Boolean isLockScreen) {
        alertError(msg, callback, isLockScreen, R.string.LEVEL_PERMIT_UNLOCK_SCREEN);
    }

    private void alertError(String msg, ActionListenerCallback callback, Boolean isLockScreen, int level_permit) {
        // Enable the ENT key down, it must current focus on multiline text input
        default_view.requestFocus();

        RelativeLayout layout = popupLayout2;
        TextView lbl_msg = (TextView) findViewById(R.id.popupLayout2_txt);
        Button btn = (Button) findViewById(R.id.popupLayout2_btn1);
        EditText txt_leader_password = (EditText) findViewById(R.id.txt_leader_password);

        if (isLockScreen) {
            txt_leader_password.setVisibility(VISIBLE);
            txt_leader_password.setText("");

            Utils.playMedia(getApplicationContext(), R.raw.ship_siren);
        } else {
            txt_leader_password.setVisibility(GONE);

            Utils.playTones(ToneGenerator.TONE_CDMA_ABBR_ALERT, 10000, 900);
        }

        lbl_msg.setText(msg);
        lbl_msg.setTextColor(getColor(R.color.red));
        layout.setVisibility(VISIBLE);
        btn.setBackgroundColor(getColor(R.color.red));
        btn.setTextColor(getColor(R.color.white));
        btn.setText("NG [" + (isLockScreen?"scan":"ENT") + "]");
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // stop activity
                try {
                    if (!isLockScreen) {
                        layout.setVisibility(GONE);
                        callback.onActionSuccess("");
                    } else {

                        /**
                         * Not implemented for this project, just close the error dialog
                         *
                         // check password
                         if (!Settings.getMgmtList().containsKey(getString(level_permit))) {
                         callback.onActionFailure(new Exception(String.valueOf(E111.getId())));
                         return;
                         }

                         List<String> levelTokens = Arrays.asList(Settings.getMgmtList().get(getString(level_permit))
                         .split(getString(R.string.DELIMITER_SETTINGS)));
                         EditText txt_leader_password = (EditText) findViewById(R.id.txt_leader_password);
                         if (!MainActivity.instance.userHashMap.containsKey(txt_leader_password.getText().toString())) {
                         callback.onActionFailure(new Exception(String.valueOf(E112.getId())));
                         return;
                         }

                         User user = MainActivity.instance.userHashMap.get(txt_leader_password.getText().toString());
                         if (levelTokens.contains(user.getLevel())) {
                         screen_locked = false;
                         layout.setVisibility(GONE);
                         callback.onActionSuccess("");
                         } else {
                         callback.onActionFailure(new Exception(String.valueOf(E122.getId())));
                         }
                         *
                         */
                        layout.setVisibility(GONE);
                        callback.onActionSuccess("");
                    }



                } catch (Exception e) {
                    // In case if item is the top most view
                };
            }
        });

    }
}