package com.ads.cal.calculator.activity;

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.GridLayout;
import android.widget.ListView;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.ads.cal.calculator.MyApplication;
import com.ads.cal.calculator.R;
import com.ads.cal.calculator.base.BaseActivity;
import com.ads.cal.calculator.utils.CalculatorUtils;
import com.ads.cal.calculator.utils.DeviceUtil;
import com.ads.cal.calculator.utils.EventIdUtils;
import com.ads.cal.calculator.utils.FireBaseAnalyticsUtils;
import com.ads.cal.calculator.utils.LogUtils;
import com.ads.cal.calculator.utils.SpUtils;
import com.ezylang.evalex.Expression;

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

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class CalculatorActivity extends BaseActivity {
    private static final int[] NUMBER_BUTTON_IDS = {
            R.id.one, R.id.two, R.id.three, R.id.four, R.id.five,
            R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.zero, R.id.dian
    };

    private static final int[] OPERATOR_BUTTON_IDS = {
            R.id.percent, R.id.division, R.id.multiplication,
            R.id.addition, R.id.subtraction
    };

    private static final int[] SCIENCE_NUMBER_BUTTON_IDS = {
            R.id.one_, R.id.two_, R.id.three_, R.id.four_, R.id.five_,
            R.id.six_, R.id.seven_, R.id.eight_, R.id.nine_, R.id.zero_, R.id.dian_
    };

    private static final int[] SCIENCE_OPERATOR_BUTTON_IDS = {
            R.id.percent_, R.id.division_, R.id.multiplication_,
            R.id.addition_, R.id.subtraction_
    };

    private static final int[] CONTROL_BUTTON_IDS = {R.id.ac, R.id.delete, R.id.equal, R.id.brackets};
    private static final int[] SCIENCE_CONTROL_BUTTON_IDS = {R.id.ac_, R.id.delete_, R.id.equal_, R.id.brackets_};

    private EditText editText;
    private final StringBuilder builder = new StringBuilder();
    private TextView tvResult;
    private int leftBrackets, rightBrackets;
    private ListView listView;

    @Override
    protected String getPageExpEventId() {
        return EventIdUtils.CALCULATOR_EXP;
    }

    @Override
    protected int getLayoutId() {
        return R.layout.app_acitivity_calculator;
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        // 保存状态
    }

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        // 恢复状态
    }

    @Override
    protected void initData() {
        // 初始化数据
    }

    @Override
    protected void initView() {
        editText = findViewById(R.id.editText);
        tvResult = findViewById(R.id.tvResult);
        listView = findViewById(R.id.history_list);
        FrameLayout.LayoutParams layout = (FrameLayout.LayoutParams) listView.getLayoutParams();
        layout.setMarginEnd(DeviceUtil.getScreenWidth(MyApplication.getApplication()) / 4);
        initSimple();
        initScience();
        toggle();

        editText.requestFocus();
        editText.setInputType(InputType.TYPE_NULL);
        editText.setSingleLine(false);
        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // 文字改变前
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // 文字改变中
                tvResult.setText(evaluateExpression(s.toString(), ""));
            }

            @Override
            public void afterTextChanged(Editable s) {
                // 文字改变后
                editText.setSelection(editText.getText().length());
            }
        });
        TextView history = findViewById(R.id.history);
        history.setOnClickListener(v -> {
            if (listView.getVisibility() != View.VISIBLE) {
                listView.setVisibility(View.VISIBLE);
            } else {
                listView.setVisibility(View.GONE);
            }
            setHistoryData();
            FireBaseAnalyticsUtils.init().send(EventIdUtils.CALCULATOR_HISTORY_CLK);
        });

        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
    }

    private void toggle() {
        GridLayout standardLayout = findViewById(R.id.standard_gridlayout);
        TextView standard = findViewById(R.id.standard);
        TextView science = findViewById(R.id.science);
        standard.setOnClickListener(v -> {
            standard.setBackgroundResource(R.drawable.app_ffffff_corner_13);
            standard.setTextColor(getResources().getColor(R.color.app_007AFF));
            science.setBackgroundResource(0);
            science.setTextColor(getResources().getColor(R.color.app_373737));
            standardLayout.setVisibility(View.VISIBLE);
            FireBaseAnalyticsUtils.init().send(EventIdUtils.CALCULATOR_STANDARD_CLK);
        });
        science.setOnClickListener(v -> {
            science.setBackgroundResource(R.drawable.app_ffffff_corner_13);
            science.setTextColor(getResources().getColor(R.color.app_007AFF));
            standard.setBackgroundResource(0);
            standard.setTextColor(getResources().getColor(R.color.app_373737));
            standardLayout.setVisibility(View.GONE);
            FireBaseAnalyticsUtils.init().send(EventIdUtils.CALCULATOR_SCIENCE_CLK);
        });
    }

    private void initNumberView() {
        for (int id : NUMBER_BUTTON_IDS) {
            setOperatorClickListener(findViewById(id));
        }
    }

    private void initSimple() {
        for (int id : OPERATOR_BUTTON_IDS) {
            setOperatorClickListener(findViewById(id));
        }

        TextView clear = findViewById(R.id.ac);
        TextView delete = findViewById(R.id.delete);
        TextView equal = findViewById(R.id.equal);
        TextView brackets = findViewById(R.id.brackets);
        initNumberView();
        clear.setOnClickListener(v -> clear());
        delete.setOnClickListener(v -> delete());
        equal.setOnClickListener(v -> equal());
        brackets.setOnClickListener(v -> brackets());
    }

    private void initScience() {
        for (int id : SCIENCE_OPERATOR_BUTTON_IDS) {
            setOperatorClickListener(findViewById(id));
        }

        TextView clear = findViewById(R.id.ac_);
        TextView delete = findViewById(R.id.delete_);
        TextView equal = findViewById(R.id.equal_);
        TextView brackets = findViewById(R.id.brackets_);
        initNumberViewScience();
        clear.setOnClickListener(v -> clear());
        delete.setOnClickListener(v -> delete());
        equal.setOnClickListener(v -> equal());
        brackets.setOnClickListener(v -> brackets());
    }

    private void initNumberViewScience() {
        for (int id : SCIENCE_NUMBER_BUTTON_IDS) {
            setOperatorClickListener(findViewById(id));
        }

        setOperatorClickListener(findViewById(R.id.sin));
        setOperatorClickListener(findViewById(R.id.cos));
        setOperatorClickListener(findViewById(R.id.tan));
        setOperatorClickListener(findViewById(R.id.genhao));
        setOperatorClickListener(findViewById(R.id.pai));

        TextView sin = findViewById(R.id.sin);
        sin.setOnClickListener(v -> {
            builder.append(sin.getText()).append("(");
            setEditTextContent();
            leftBrackets++;
        });
        TextView cos = findViewById(R.id.cos);
        cos.setOnClickListener(v -> {
            builder.append(cos.getText()).append("(");
            setEditTextContent();
            leftBrackets++;
        });
        TextView tan = findViewById(R.id.tan);
        tan.setOnClickListener(v -> {
            builder.append(tan.getText()).append("(");
            setEditTextContent();
            leftBrackets++;
        });
    }

    private void setOperatorClickListener(TextView operatorTextView) {
        operatorTextView.setOnClickListener(v -> {
            builder.append(operatorTextView.getText());
            setEditTextContent();
        });
    }

    private void setEditTextContent() {
        if (null == editText) {
            return;
        }
        LogUtils.log("builder = " + builder.toString());
        editText.setText(builder.toString());
        setHistoryListVisibility();
    }

    private String evaluateExpression(String value, String hint) {
        try {
            Expression expression = new Expression(CalculatorUtils.fixMathExpression(value));
            return expression.evaluate().getStringValue();
        } catch (Exception e) {
            Log.e("CalculatorActivity", "Error evaluating expression", e);
            return hint;
        }
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // 配置改变时的处理
    }

    private void delete() {
        int length = builder.length();
        if (length > 0) {
            char c = builder.charAt(length - 1);
            if (c == '(') {
                leftBrackets--;
            } else if (c == ')') {
                rightBrackets--;
            }
            builder.delete(length - 1, length);
            setEditTextContent();
        }
    }

    private void equal() {
        String text = builder.toString();
        if (!TextUtils.isEmpty(text)) {
            String value = evaluateExpression(text, getString(R.string.app_calculator_error_hint));
            LogUtils.log(value);
            if (TextUtils.isEmpty(value)) {
                return;
            }
            if (value.equals(getString(R.string.app_calculator_error_hint))) {
                tvResult.setText(value);
                return;
            }
            editText.setText(value);
            tvResult.setText("");
            saveToLocalData(text + "|" + "=" + value);
            builder.setLength(0);
        }
    }

    private void saveToLocalData(String value) {
        try {
            LogUtils.log(value);
            String localData = SpUtils.getString(this, "key", "");
            JSONObject object;
            LogUtils.log(localData);
            if (!TextUtils.isEmpty(localData)) {
                object = new JSONObject(localData);
            } else {
                object = new JSONObject();
            }
            JSONArray jsonArray = object.optJSONArray("data");
            if (null == jsonArray) {
                jsonArray = new JSONArray();
            }
            jsonArray.put(value);
            object.put("data", jsonArray);
            SpUtils.saveString(this, "key", object.toString());
            LogUtils.log(object.toString());
        } catch (Exception e) {
            LogUtils.log(e.toString());
        }
    }


    private void brackets() {
        if (leftBrackets == rightBrackets) {
            int length = builder.length();
            boolean isOperator = length > 0 && CalculatorUtils.isOperator(builder.charAt(length - 1));
            if (isOperator) {
                builder.append("(");
            } else {
                if (length > 0) {
                    builder.append("×(");
                } else {
                    builder.append("(");
                }
            }
            leftBrackets++;
        } else if (leftBrackets > rightBrackets) {
            builder.append(")");
            rightBrackets++;
        }
        setEditTextContent();
    }

    private void clear() {
        builder.setLength(0);
        setEditTextContent();
        leftBrackets = 0;
        rightBrackets = 0;
    }

    private HistoryAdapter historyAdapter;

    private void setHistoryData() {
        if (null == historyAdapter) {
            historyAdapter = new HistoryAdapter(this);
            listView.setAdapter(historyAdapter);
        }
        historyAdapter.notifyData();
    }

    private static class HistoryAdapter extends BaseAdapter {
        private final List<String> mData;
        private final WeakReference<Context> weakReference;

        public HistoryAdapter(Context context) {
            mData = new ArrayList<>();
            weakReference = new WeakReference<>(context);
        }

        public void notifyData() {
            try {
                mData.clear();
                String localData = SpUtils.getString(weakReference.get(), "key", "");
                if (!TextUtils.isEmpty(localData)) {
                    JSONObject object = new JSONObject(localData);
                    JSONArray jsonArray = object.optJSONArray("data");
                    if (jsonArray != null) {
                        for (int i = 0; i < jsonArray.length(); i++) {
                            mData.add(jsonArray.getString(i));
                        }
                        notifyDataSetChanged();
                    }
                }
            } catch (Exception e) {
                LogUtils.log(e.toString());
            }
        }

        @Override
        public int getCount() {
            return mData.size();
        }

        @Override
        public Object getItem(int position) {
            return mData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (null == convertView) {
                convertView = LayoutInflater.from(weakReference.get()).inflate(R.layout.app_calculator_history_item, null, false);
            }
            TextView text = convertView.findViewById(R.id.text);
            TextView value = convertView.findViewById(R.id.value);
            String data = mData.get(position);
            if (data.contains("|")) {
                String[] strings = data.split("\\|");
                if (strings.length > 1) {
                    value.setText(strings[1]);
                }
                if (strings.length > 0) {
                    text.setText(strings[0]);
                }
            }
            return convertView;
        }
    }

    private void setHistoryListVisibility() {
        if (listView.getVisibility() == View.VISIBLE) {
            listView.setVisibility(View.GONE);
        }
    }

    @Override
    public void onBackPressed() {
        if (listView.getVisibility() == View.VISIBLE) {
            setHistoryListVisibility();
        } else {
            super.onBackPressed();
        }
    }

    public static void instance(Context context) {
        Intent intent = new Intent(context, CalculatorActivity.class);
        context.startActivity(intent);
    }
}
