package com.handset.serialportsensor.activity;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.handset.serialportlib.ByteUtils;
import com.handset.serialportlib.CRCUtils;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.account.AccountManager;
import com.handset.serialportsensor.adapter.SettingsAdapter;
import com.handset.serialportsensor.bean.RawData;
import com.handset.serialportsensor.bean.SettingsItem;
import com.handset.serialportsensor.bean.TestRecordsTotal;
import com.handset.serialportsensor.constant.Constant;
import com.handset.serialportsensor.presenter.SurfaceContract;
import com.handset.serialportsensor.presenter.SurfacePresenter;
import com.handset.serialportsensor.utils.DateUtils;
import com.handset.serialportsensor.utils.ToastHelper;
import com.handset.serialportsensor.utils.ExcelMa;
import com.handset.serialportsensor.utils.PersistHelper;
import com.handset.serialportsensor.view.ExportProgressDialog;

import org.kymjs.kjframe.KJDB;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.handset.serialportsensor.utils.DateStyle.YYYY_MM_DD_HH_MM;

public class SensorSettingsActivity extends BaseActivity implements SettingsAdapter.OnItemClickListener, SurfaceContract.ISerialView {
    private final static String logTag = "HANDSET-JE002-EX";

    private String sensorId;

    private Integer baudRate;

    private AlertDialog resetDialog;

    private ExcelMa mExcelMa = new ExcelMa();

    private SurfacePresenter mPresenter = new SurfacePresenter((this));

    private int[] iconsAdmin = new int[]{
            R.mipmap.ic_settings1, R.mipmap.ic_settings2, R.mipmap.ic_settings3,
            R.mipmap.ic_settings4, R.mipmap.ic_settings5, R.mipmap.ic_settings6, R.mipmap.ic_settings7,
            R.mipmap.ic_settings8, R.mipmap.ic_settings9, R.mipmap.ic_settings9, R.mipmap.ic_settings9
    };
    private String[] namesAdmin = new String[]{"波特率设置", "阈值设置", "弹筒信息", "数据导出", "数据恢复", "设置系统时间", "重置密码"};
    private int[] mPositionAdmin = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    private int[] iconsRoot = new int[]{
            R.mipmap.ic_settings7, R.mipmap.ic_settings8, R.mipmap.img_right,
            R.mipmap.ic_settings2, R.mipmap.ic_settings9
    };

    private String[] namesRoot = new String[]{"重置密码", "恢复传感器出厂设置", "第三方传感器弹筒信息开关", "传感器ID设置", "查看操作日志"};
    private int[] mPositionRoot = new int[]{6, 7, 8, 9, 10};

    public static void open(Integer baudRate, Integer role, String sensorId, Context context) {
        Intent intent = new Intent(context, SensorSettingsActivity.class);
        intent.putExtra(Constant.ROLE_KEY, role);
        Log.e(logTag, "sensorId 444: " + sensorId);
        intent.putExtra(Constant.BAUD_RATE, baudRate);
        intent.putExtra(Constant.SENSOR_ID, sensorId);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sensor_settings);
        initView();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

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

    private void initView() {
        initTitle();
        RecyclerView recyclerView = findViewById(R.id.recycle_view);
        recyclerView.setLayoutManager(new LinearLayoutManager((this)));
        Intent intent = getIntent();
        int role = Constant.NOT_CONNECTED_ROLE;
        if (intent != null) {
            role = intent.getIntExtra(Constant.ROLE_KEY, Constant.NOT_CONNECTED_ROLE);
            baudRate = intent.getIntExtra(Constant.BAUD_RATE, (38400));
            sensorId = intent.getStringExtra(Constant.SENSOR_ID);
            Log.i(logTag, ("hex string sensorId: " + sensorId));
        }
        ArrayList<SettingsItem> items = new ArrayList<>();
        Log.i(logTag, ("accountId: " + AccountManager.get().getUserId()));
        if (AccountManager.get().getUserId().equals("admin")) {
            for (int i = 0; i < namesAdmin.length; i++) {
                items.add(new SettingsItem(namesAdmin[i], iconsAdmin[i], mPositionAdmin[i]));
            }
        } else {
            for (int i = 0; i < namesRoot.length; i++) {
                items.add(new SettingsItem(namesRoot[i], iconsRoot[i], mPositionRoot[i]));
            }
        }

        SettingsAdapter adapter = new SettingsAdapter(items, role);
        adapter.setOnItemClickListener(this);
        recyclerView.setAdapter(adapter);

        findViewById(R.id.btn_logout).setOnClickListener((View v) -> {
            AccountManager.get().logout();
            finish();
            startActivity(new Intent((SensorSettingsActivity.this), LoginActivity.class));
        });
    }

    private void initTitle() {
        ImageView ivBack = findViewById(R.id.title_back);
        ivBack.setVisibility(View.VISIBLE);
        ivBack.setOnClickListener((View view) -> finish());
        TextView tvTitle = findViewById(R.id.title_text);
        tvTitle.setText(R.string.sensor_settings_title);
    }

    @Override
    public void onItemClick(View view, int position) {
        int id = mPositionAdmin[position];
        if (AccountManager.get().getUserId().equals("root")) {
            id = mPositionRoot[position];
        }

        Intent intent;
        switch (id) {
            case 0:
                intent = new Intent((SensorSettingsActivity.this), BaudRateSettingActivity.class);
                intent.putExtra(Constant.BAUD_RATE, baudRate);
                intent.putExtra(Constant.SENSOR_ID, sensorId);
                startActivity(intent);
                break;
            case 1:
                startActivity(new Intent((SensorSettingsActivity.this), ThresholdActivity.class));
                break;
            case 2:
                intent = new Intent((SensorSettingsActivity.this), ConeSettingActivity.class);
                Log.e(logTag, "sensorId 222: " + sensorId);
                intent.putExtra(Constant.BAUD_RATE, baudRate);
                intent.putExtra(Constant.SENSOR_ID, sensorId);
                startActivity(intent);
                break;
            case 3:
                //数据导出
                confirmExport();
                break;
            case 4:
                //数据恢复
                startActivity(new Intent((SensorSettingsActivity.this), DataRecoverActivity.class));
                break;
            case 5:
                startActivity(new Intent(Settings.ACTION_DATE_SETTINGS));
                break;
            case 6:
                startActivity(new Intent((SensorSettingsActivity.this), PasswordResetActivity.class));
                break;
            case 7:
                ToastHelper.showResetSensorDialog((this), new ToastHelper.OnDialogClickListener() {
                    @Override
                    public void onOKClickListener(View view) {
                        reset();
                    }

                    @Override
                    public void onCancelClickListener(View view) {

                    }
                });
                break;
            case 8:
                if (AccountManager.get().getUserId().equals("root")) {
                    startActivity(new Intent((SensorSettingsActivity.this), ThirdSensorSettingsActivity.class));
                } else {
                    Toast.makeText((this), "请登录root 后在操作", Toast.LENGTH_SHORT).show();
                }
                break;
            case 9:
                if (AccountManager.get().getUserId().equals("root")) {
                    intent = new Intent((SensorSettingsActivity.this), ChangeSensorIdSettingsActivity.class);
                    intent.putExtra(Constant.BAUD_RATE, baudRate);
                    intent.putExtra(Constant.SENSOR_ID, sensorId);
                    startActivityForResult(intent, (10001));
                } else {
                    Toast.makeText((this), "请登录root 后在操作", Toast.LENGTH_SHORT).show();
                }
                break;
            case 10:
                if (AccountManager.get().getUserId().equals("root")) {
                    startActivityForResult(new Intent((SensorSettingsActivity.this), ViewOperateLogListActivity.class), 10001);
                } else {
                    Toast.makeText((this), "请登录root 后在操作", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 10001) {
            if (resultCode == RESULT_OK && data != null) {
                String sensorId = data.getStringExtra(Constant.SENSOR_ID);
                sendSensorId(sensorId);
            }
        }
    }

    private void sendSensorId(String sensorId) {
        StringBuilder sb = new StringBuilder(this.sensorId);
        sb.append("00").append("80").append("04").append(sensorId);
        String cooked = "DDDD".concat(sb.toString().concat(CRCUtils.genCrc(sb.toString())));
        Log.i(logTag, "sensor no set: cooked: " + cooked);
        Log.i(logTag, "sensor no set: cooked 2: " + Arrays.toString(cooked.getBytes()));
        mPresenter.write(cooked);
    }

    private void openAssignFolder(final String times) {
        mExportProgressDialog = null;
        new Thread(() -> {
            List<TestRecordsTotal> testRecordsTotals = KJDB.getDefaultInstance().findAllByWhere(TestRecordsTotal.class, "1=1");
            mExcelMa.write(testRecordsTotals, new PersistHelper.ExportCallback() {
                @Override
                public void exportProgress(int counts, int remain) {
                    Log.d(logTag, "exportProgress  [counts, remain]:" + counts + "  " + remain);
                    showExportProgress(counts, remain);
                }

                @Override
                public void finish(int counts, int remain) {
                    if (remain != 0) {
                        showCancelTip();
                    }
                }
            }, times);
        }).start();
    }

    //数据导出确认
    private void confirmExport() {
        runOnUiThread(() -> {
            dismissDialog(null);
            final String items = DateUtils.formatMilliesTimestamp(System.currentTimeMillis(), YYYY_MM_DD_HH_MM);
            final String name = "检测结果(" + items + ").xlsx";
            String alarm = "导出数据到 内部存储/htjc/sensor/export/" + name + "";
            AlertDialog a = ToastHelper.showChooseDialogNoShow(
                    getString(R.string.import_out_confirm),
                    R.mipmap.ic_exclamation_mark,
                    alarm,
                    getResources().getColor(R.color.button),
                    getString(R.string.confirm), getString(R.string.cancel),
                    (SensorSettingsActivity.this),
                    new ToastHelper.OnDialogClickListener() {
                        @Override
                        public void onOKClickListener(View view) {
                            openAssignFolder(items);
                        }

                        @Override
                        public void onCancelClickListener(View view) {
                        }
                    });
            showDialog(a);
        });
    }

    private void showCancelTip() {
        runOnUiThread(() -> {
            AlertDialog alertDialog = ToastHelper.showTipDialogNoShow((SensorSettingsActivity.this), R.mipmap.chuchang_gray, R.string.cancel);
            showDialog(alertDialog);
            disMissDialogDelay(alertDialog, (3000));
        });
    }

    ExportProgressDialog mExportProgressDialog;

    private void showExportProgress(final int count, final int remain) {
        if (mExportProgressDialog == null) {
            runOnUiThread(() -> {
                mExportProgressDialog = new ExportProgressDialog();
                mExportProgressDialog.showExportDialogNoShow(
                        (SensorSettingsActivity.this),
                        (View view) -> mExcelMa.stopExport(),
                        count,
                        remain,
                        getString(R.string.importing_to_excel_file),
                        getString(R.string.import_out)
                );
                showDialog(mExportProgressDialog.mAlertDialog);
            });
        } else {
            mExportProgressDialog.update(this, count, remain);
        }
    }

    //正在设置
    private void showSettingDialog() {
        runOnUiThread(() -> {
                    resetDialog = ToastHelper.showTipDialog((SensorSettingsActivity.this), R.mipmap.ic_setting, R.string.reset_tip);
                    disMissDialogDelay(resetDialog, (10000));
                }
        );
    }

    private Handler mHandler = new Handler();
    private Runnable mRunnable;

    @Override
    public void disMissDialogDelay(final AlertDialog alertDialog, int delayMillis) {
        mRunnable = () -> {
            Log.i(logTag, "SensorSettingsActivity, disMissDialogDelay");
            mPresenter.close();
            dismissDialogD(alertDialog);
        };
        mHandler.postDelayed(mRunnable, delayMillis);
    }

    private void reset() {
        showSettingDialog();
        new Thread(() -> {
            Looper.prepare();
            new Handler().postDelayed(() -> mPresenter.open(baudRate), (500));
            Looper.loop();
        }
        ).start();

        handler.sendEmptyMessageDelayed(Constant.Command.COMMAND_49, (3000));
    }

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == Constant.Command.COMMAND_49) {//恢复出厂值
                StringBuilder sb = new StringBuilder(sensorId);
                sb.append("00").append("49").append("00");
                String cooked = "DDDD".concat(sb.toString().concat(CRCUtils.genCrc(sb.toString())));
                Log.i(logTag, "SensorSettingsActivity, cooked: " + cooked);
                mPresenter.write(cooked);
            }
        }
    };

    @Override
    public void onSerialOpen(boolean isOpen) {

    }

    @Override
    public void onSerialBaudRate(Integer baudRate) {

    }

    @Override
    public void onSerialData(RawData rawData) {
        if (rawData.getItemType() == RawData.TYPE_RECEIVE) {
            Log.i(logTag, "SensorSettingsActivity, onSerialData: " + rawData.getMessage());
            byte[] bytes = ByteUtils.hexStrToBytes(rawData.getMessage());
            Log.i(logTag, "SensorSettingsActivity, onSerialData 2: " + Arrays.toString(bytes));
            if (bytes.length > 8) {
                if ((bytes[6] & 0xff) == 0 && (bytes[7] & 0xff) == Constant.Command.COMMAND_4A) {
                    Log.i(logTag, "SensorSettingsActivity, onSerialData, 0x49 feedback: " + rawData.getMessage());
                    mPresenter.close();
                    dismissDialog(resetDialog);
                    mHandler.removeCallbacks(mRunnable);
                    restoreToFactorySuccess();
                } else {
                    mPresenter.close();
                    dismissDialog(resetDialog);
                    mHandler.removeCallbacks(mRunnable);
                    restoreToFactoryFail();
                }
            }
        }
    }

    @Override
    public void onSerialError(Integer errorCode) {

    }

    //设置成功
    private void restoreToFactorySuccess() {
        runOnUiThread(() -> {
            disMissLoadingDialog(resetDialog);
            ToastHelper.showSubmitDialog(
                    getString(R.string.restore_factory_success),
                    R.mipmap.img_right,
                    getString(R.string.go_back_init_screen_content),
                    getResources().getColor(R.color.blue_button_bg),
                    getString(R.string.btn_ensure),
                    (SensorSettingsActivity.this),
                    (View view) -> finish()
            );
        });
    }

    //设置失败
    private void restoreToFactoryFail() {
        runOnUiThread(() -> {
                    disMissLoadingDialog(resetDialog);
                    ToastHelper.showSubmitDialog(
                            getString(R.string.restore_factory_failed),
                            R.mipmap.img_cross,
                            getString(R.string.go_back_init_screen_content),
                            getResources().getColor(R.color.button),
                            getString(R.string.btn_ensure),
                            (SensorSettingsActivity.this),
                            (View view) -> {
                            }
                    );
                }
        );
    }
}
