package com.oo.eye.activity;

import android.os.Build;
import android.os.CountDownTimer;
import android.os.Handler;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.app.baselibrary.base.app.AppManager;
import com.app.baselibrary.base.common.BaseActivity;
import com.app.baselibrary.commonUtil.BDttsUtils;
import com.app.baselibrary.commonUtil.CheckUtil;
import com.app.baselibrary.commonUtil.LogUtil;
import com.app.baselibrary.commonUtil.PreferencesUtils;
import com.app.baselibrary.commonUtil.ToastUtil;
import com.oo.eye.EyeConfig;
import com.oo.eye.R;
import com.oo.eye.bean.Eye;
import com.oo.eye.bean.Eye.E;
import com.oo.eye.bean.StudentBean;
import com.oo.eye.db.DbManager;
import com.oo.eye.net.EyeDataManager;
import com.oo.eye.widget.AfterTestDialog;
import com.oo.eye.widget.BeforeTestDialog;
import com.oo.seex.netlibrary.net.response.OldResponseImpl;
import com.oo.seex.netlibrary.net.response.RxCallback;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import butterknife.BindView;
import butterknife.OnClick;
import rx.android.schedulers.AndroidSchedulers;

import static com.oo.eye.EyeConfig.EYE_DIRECTION_4;
import static com.oo.eye.EyeConfig.EYE_SETTING_5;
import static com.oo.eye.bean.Eye.getIndexByValue;
import static com.oo.eye.bean.Eye.getLineSumByIndex;

/**
 */

public class EyeTestActivity extends BaseActivity {

    static final int TOP = 0;
    static final int RIGHT = 1;
    static final int BOTTOM = 2;
    static final int LEFT = 3;
    static final int RIGHT_TOP = 4;
    static final int RIGHT_BOTTOM = 5;
    static final int LEFT_BOTTOM = 6;
    static final int LEFT_TOP = 7;

    private E mSelectE;

    @BindView(R.id.title_eye)
    TextView mEyeText;
    @BindView(R.id.title_eye_)
    TextView mEyeText_;
    @BindView(R.id.next_left)
    TextView mNextText;
    @BindView(R.id.rl_eye_test_center_time1)
    RelativeLayout timeLayout1;
    @BindView(R.id.tv_name_left)
    TextView nameText;
    @BindView(R.id.tv_eye_test_center_ready1)
    TextView readyText;
    @BindView(R.id.tv_eye_test_center_time1)
    TextView timeText1;

    @BindView(R.id.rl_eye_test_center_e1)
    RelativeLayout eLayout1;

    @BindView(R.id.iv_eye_test_center_e1)
    ImageView eImageView1;

    @BindView(R.id.test_distance)
    TextView mDistanceText;

    private int mDistance = EyeConfig.EYE_DISTANCE_5;
    private int mDirection = EYE_DIRECTION_4;
    private int mGroupDecimal = EyeConfig.EYE_SETTING_5;
    private int mAutoJudge = 0;

    private ArrayList<ArrayList<E>> mList = new ArrayList<>();
    private int mLocation;
    private int mLevelIndex = -1;
    private LinkedHashMap<Integer, List<E>> mCollect = new LinkedHashMap<>();
    private StudentBean measureStudent;
    private List<StudentBean> mStudentList = new ArrayList<>();
    //是否是右眼训练
    private boolean isSecondTest;
    private int currentIndex;
    private double mLeftEye = 5.0;
    private double mRightEye = 5.0;
    private long mLastOnKeyTime = -1;
    private boolean isStartTest = false;

    private boolean isKeyDwon = false;
    private boolean isJudgeChoose = false;

    private Handler mHandler;
    private Runnable mRunnable;//执行几秒钟默认选择错误的线程
    private boolean isChoose = false;

    private long totalTime = 5000;
    private long intervalTime = 1000;

    private AfterTestDialog mAfterTestDialog;

    private boolean isTemporary;
    private BeforeTestDialog mBeforeTestDialog;

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

    @Override
    protected void init() {
        boolean help = PreferencesUtils.getBoolean(EyeConfig.EYE_HELP_SETTING_KEY, true);
        if (help) {
            showBeforeDialog(true);
        } else {
            prepareQueue();
        }
        initialize();
    }

    private void showBeforeDialog(final boolean isFrist) {
        mBeforeTestDialog = new BeforeTestDialog.Builder(EyeTestActivity.this, R.style.style_common_dialog)
                .setOnClickListener(new BeforeTestDialog.BeforeTestListener() {
                    @Override
                    public void onClick() {
                        if (isFrist) {
                            prepareQueue();
                        } else {
                            showStudentTestDialog();
                        }
                    }
                }).create();
        mBeforeTestDialog.show();
    }

    private void initialize() {
        mHandler = new Handler();
        mStudentList = EyeConfig.getInstance().getStudents();
        mDistance = PreferencesUtils.getInt(EyeConfig.EYE_DISTANCE_SETTING_KEY, EyeConfig.EYE_DISTANCE_5);
        mDirection = PreferencesUtils.getInt(EyeConfig.EYE_DIRECTION_SETTING_KEY, EYE_DIRECTION_4);
        mGroupDecimal = PreferencesUtils.getInt(EyeConfig.EYE_SETTING_KEY, EyeConfig.EYE_SETTING_5);
        mAutoJudge = PreferencesUtils.getInt(EyeConfig.EYE_WAIT_SETTING_KEY, 0);
        isTemporary = getIntent().getBooleanExtra("isTemporary", false);
        String dis = mDistance == EyeConfig.EYE_DISTANCE_5 ? "5" : "2.5";
        mDistanceText.setText("当前测视距离为" + dis + "米");
        mList.clear();
        for (int i = 0; i < 14; i++) {
            mList.add(initLineList(i));
        }
    }

    private void prepareQueue() {
        if (null != mStudentList && mStudentList.size() > 0) {
            prepareStudentTest(0);
        } else {
            AppManager.getInstance().killOtherActivity(EyeTestMainActivity.class);
            startActivity(EyeTestMainActivity.class);
            finish();
        }
    }

    private void continueTest() {
        if (!isStartTest) {
            isStartTest = true;
            resetView(true);
        }
    }

    /**
     * 准备测试
     *
     * @param index
     */
    private void prepareStudentTest(int index) {
        currentIndex = index;
        isStartTest = false;
        mCollect.clear();
        measureStudent = mStudentList.get(index).transition(mDistance);
        if (measureStudent.getRealname() != null || !TextUtils.isEmpty(measureStudent.getRealname())) {
            nameText.setText(measureStudent.getRealname());
        } else {
            nameText.setText("");
        }
        if (index < mStudentList.size() - 1) {
            mNextText.setText("放弃当前，跳到下一位");
        } else {
            mNextText.setText("结束测试");
        }
        continueTest();
    }

    /**
     * 开始测试
     *
     * @param isNewTest true 代表测试的第一只眼 代表左眼  false代表测量另一只眼 右眼
     */
    private void resetView(final boolean isNewTest) {
        isKeyDwon = false;
        mLevelIndex = -1;
        isSecondTest = !isNewTest;
        String eye = isNewTest ? "右" : "左";
        if (isNewTest) {
            if (measureStudent != null) {
                mLeftEye = measureStudent.getLeft_eye();
                mRightEye = measureStudent.getRight_eye();
            }
        }
        timeLayout1.setVisibility(View.VISIBLE);
        readyText.setText("请遮住您的" + eye + "眼");
        eLayout1.setVisibility(View.GONE);
        new CountDownTimer(totalTime, intervalTime) {
            @Override
            public void onTick(long millisUntilFinished) {
                long time = millisUntilFinished / 1000;
                timeText1.setText(time + "");
            }

            @Override
            public void onFinish() {
                LogUtil.e("onFinish");
                timeLayout1.setVisibility(View.GONE);
                eLayout1.setVisibility(View.VISIBLE);
                double e = 5.0;
                //如果是左眼次测试
                if (isNewTest) {
                    if (measureStudent != null) {
                        e = measureStudent.getLeft_eye();
                    }
                } else {
                    //右眼测试
                    if (isSecondTest) {
                        if (measureStudent != null) {
                            e = measureStudent.getRight_eye();
                        }
                    }
                }
                mLevelIndex = getIndexByValue(e, true) - 1;
                nextE(true);
            }
        }.start();
        speak("测试马上开始，请遮住您的" + eye + "眼");
        mCollect.clear();
    }

    private void speak(String text) {
        if (BDttsUtils.getInstance() != null) {
            BDttsUtils.getInstance().speak(text);
        }
    }

    /**
     * 描画E字
     *
     * @param e
     */
    private void drewE(E e) {
        int angle = 0;
        switch (e.getDirect()) {
            case TOP:
                angle = 0;
                break;
            case RIGHT_TOP:
                angle = 45;
                break;
            case RIGHT:
                angle = 90;
                break;
            case RIGHT_BOTTOM:
                angle = 135;
                break;
            case BOTTOM:
                angle = 180;
                break;
            case LEFT_BOTTOM:
                angle = 225;
                break;
            case LEFT:
                angle = 270;
                break;
            case LEFT_TOP:
                angle = 315;
                break;
        }
        eImageView1.destroyDrawingCache();
        eImageView1.setImageBitmap(Eye.getBitmap(this, e.getLevel(), mDistance, angle));
        isKeyDwon = true;
    }

    /**
     * 随机生成每一行的视标E
     *
     * @param index 第几行
     * @return list
     */
    private ArrayList<E> initLineList(int index) {
        float levelValue = Eye.getLevelSizeByIndex(index);
        int sum = getLineSumByIndex(index);
        //随机数生成方向
        Random random = new Random();
        E e;
        ArrayList<E> list = new ArrayList<>();
        int direct = getFirstDirect(random, index);
        for (int i = 0; i < sum; i++) {
            if (i > 0) {
                direct = getRandomDirect(list, direct, sum);
            }
            e = new E(i, direct, index, levelValue);
            list.add(e);
        }
        return list;
    }

    /**
     * 获取第一个E;
     *
     * @param random
     * @param index
     * @return
     */
    private int getFirstDirect(Random random, int index) {
        int direct = random.nextInt(mDirection);
        if (index > 0) {
            if (mList.get(index - 1).get(0).getDirect() == direct)
                direct = getFirstDirect(random, index);
        }
        return direct;
    }

    /**
     * 获取下一个E的方向的判断；
     *
     * @param list
     * @param direct
     * @param sum
     * @return
     */
    private int getRandomDirect(ArrayList<E> list, int direct, int sum) {
        int lastDirect = direct;
        direct = randomDirect(direct);
        int num = sum / 2;
        if (sum % 2 == 0 && sum / 2 > 1) {
            num = sum / 2 - 1;
        }
        if (getEDirectorNum(list, direct) >= num) {
            direct = getRandomDirect(list, lastDirect, sum);
        }
        return direct;
    }

    /**
     * 获取该行出现的形同方向的E的个数；
     *
     * @param list
     * @param direct
     * @return
     */
    private int getEDirectorNum(ArrayList<E> list, int direct) {
        int num = 0;
        if (list == null || list.size() == 0)
            return num;
        for (E e :
                list) {
            if (e.getDirect() == direct)
                num++;
        }
        return num;
    }


    /**
     * 相邻的两个不能是同一个方向
     *
     * @param lastDirect 上一次的方向
     * @return 新的方向
     */
    private int randomDirect(int lastDirect) {
        //随机数生成方向
        Random random = new Random();
        int newDirect = random.nextInt(mDirection);
        //相邻的不能一样
        while (lastDirect == newDirect) {
            newDirect = random.nextInt(mDirection);
        }

        return newDirect;
    }


    /**
     * 下一个E字标
     */
    private void nextE(boolean isNextLine) {
        try {
            if (isNextLine) {
                mLevelIndex++;
                mLocation = 0;
            } else {
                mLocation++;
            }

            mSelectE = mList.get(mLevelIndex).get(mLocation);
            String levelByIndex = "4.0";
            if (mGroupDecimal == EYE_SETTING_5) {
                levelByIndex = "" + Eye.getLevelByIndex(mSelectE.getLevel(), mDistance == EyeConfig.EYE_DISTANCE_5);
            } else {
                levelByIndex = "" + Eye.get2LevelByIndex(mSelectE.getLevel(), mDistance == EyeConfig.EYE_DISTANCE_5);
            }
            mEyeText.setText(levelByIndex);
            mEyeText_.setText("" + (mLocation + 1));
            drewE(mSelectE);
            isJudgeChoose = false;
            startRunnable();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void startRunnable() {
        if (mRunnable == null) {
            mRunnable = new Runnable() {
                @Override
                public void run() {
                    LogUtil.e("mRunnable------");
                    if (isChoose) {
                        return;
                    }
                    userChooseError();
                }
            };
        }
        if (mAutoJudge > 0) {
            LogUtil.e("开启mRunnable");
            mHandler.postDelayed(mRunnable, mAutoJudge * 1000);
        }
        isChoose = false;
    }

    private void removeRunnable() {
        isChoose = true;
        try {
            if (mHandler != null && mRunnable != null) {
                mHandler.removeCallbacks(mRunnable);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 选择的方向
     *
     * @param direct
     */
    private synchronized void userChoose(int direct) {
        removeRunnable();
        if (!isJudgeChoose) {
            isJudgeChoose = true;
            //获取当前行答过的e
            List<E> list = mCollect.get(mLevelIndex);
            if (null == list || list.size() == 0) {
                list = new ArrayList<>();
            }
            mSelectE.setUserChoose(direct);
            list.add(mSelectE);
            mCollect.put(mLevelIndex, list);
            judge();
        }
    }

    private void judge() {
        int verifyErrorCount = 0;
        //获取每行有多少个e
        int lineSum = getLineSumByIndex(mLevelIndex);
        //获取每行答对几个e
        int leastAnswerCount = Eye.getLeastAnswerCount(mLevelIndex);
        //获取当前行答过的e
        List<E> list = mCollect.get(mLevelIndex);
        int rightAnswerCount = 0;
        for (E e : list) {
            if (e.isCorrect()) {
                rightAnswerCount++;
            }
        }
        //当前行答错的数
        int errorCount = list.size() - rightAnswerCount;
        //判断是否满足答对的要求
        boolean isNextLine = rightAnswerCount >= leastAnswerCount;
        mCollect.put(mLevelIndex, list);

        if (isNextLine) {
            if (mLevelIndex == 13) {
                showResult();
                return;
            } else {
                List<E> nextList = mCollect.get(mLevelIndex + 1);
                if (nextList != null && nextList.size() > 0) {
                    showResult();
                    return;
                }
            }
        }

        //防止出现-1的现象；
        if (lineSum - leastAnswerCount > 0) {
            verifyErrorCount = lineSum - leastAnswerCount;
        } else {
            verifyErrorCount = 0;
        }
        //必须答对一半才往下走一行的
        //如果错误次数超过一半 (默认位置时上一行没有数据时候)回退一行
        if (errorCount > verifyErrorCount) {
            //如果上一行数据不为空 结束测试
            if (mLevelIndex == 0 ||
                    (mCollect.containsKey(mLevelIndex - 1) && !CheckUtil.isEmpty(mCollect.get(mLevelIndex - 1)))) {
                showResult();
                return;
            } else {
                backLastLine();
                return;
            }
        }
        nextE(isNextLine);
    }

    /**
     * 答错
     */
    private synchronized void userChooseError() {
        removeRunnable();
        if (!isJudgeChoose) {
            isJudgeChoose = true;
            int direct = mSelectE.getDirect() + 1;
            //获取当前行答过的e
            List<E> list = mCollect.get(mLevelIndex);
            if (null == list || list.size() == 0) {
                list = new ArrayList<>();
            }
            mSelectE.setUserChoose(direct);
            list.add(mSelectE);
            mCollect.put(mLevelIndex, list);
            judge();
        }
    }


    //返回到上一行
    private void backLastLine() {
        mLevelIndex = mLevelIndex - 2;
        nextE(true);
    }

    /**
     * 单眼测试结束
     */
    private void showResult() {
        //如果不是手动提交
        final Double eyeResult = getResult();
        if (isSecondTest) {//右眼训练
            mRightEye = eyeResult;
            speak("测试完成");
            boolean help = PreferencesUtils.getBoolean(EyeConfig.EYE_HELP_SETTING_KEY, true);
            //判断是否是最后一个人
            boolean isLastStuent = (currentIndex == mStudentList.size() - 1);
            if (help && !isLastStuent) {
                showBeforeDialog(false);
            } else {
                showStudentTestDialog();
            }
        } else {//左眼训练
            mLeftEye = eyeResult;
            resetView(false);
            return;
        }
    }


    private void showStudentTestDialog() {
        final int next = currentIndex + 1;
        boolean isShow = false;
        String nextName = "";
        if (next < mStudentList.size()) {
            isShow = true;
            nextName = mStudentList.get(next).getRealname();
        }
        double left = mLeftEye;
        double right = mRightEye;
        if (mGroupDecimal != EyeConfig.EYE_SETTING_5) {
            int leftIndex = Eye.getIndexByValue(mLeftEye, mDistance == EyeConfig.EYE_DISTANCE_5);
            left = Eye.getLevelByIndex(leftIndex, mDistance == EyeConfig.EYE_DISTANCE_5);
            int rightIndex = Eye.getIndexByValue(mRightEye, mDistance == EyeConfig.EYE_DISTANCE_5);
            right = Eye.getLevelByIndex(rightIndex, mDistance == EyeConfig.EYE_DISTANCE_5);
        }
        if (isTemporary) {
            measureStudent.setLeft_eye(left);
            measureStudent.setRight_eye(right);
            DbManager.getDaoSession(EyeTestActivity.this).insert(measureStudent);
        } else {
            Map<String, String> map = new HashMap<>();
            map.put("sid", !CheckUtil.isEmpty(measureStudent.getSid()) ? measureStudent.getSid() : "");
            map.put("uid", !CheckUtil.isEmpty(measureStudent.getUid()) ? measureStudent.getUid() : "");
            map.put("eid", "0");
            map.put("left_eye", "" + left);
            map.put("right_eye", "" + right);
            map.put("distance", "" + (mDistance == EyeConfig.EYE_DISTANCE_5 ? 5 : 2.5));
            map.put("deviceId", Build.ID);
            map.put("pid", !CheckUtil.isEmpty(measureStudent.getPid()) ? measureStudent.getPid() : "");
            EyeDataManager.getInstance().postEyeTestData(map).observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new RxCallback<OldResponseImpl<Object>>() {
                        @Override
                        protected void onSuccess(OldResponseImpl<Object> stringOldResponse) {
                            ToastUtil.showLongMessage("视力数据保存成功");
                        }

                        @Override
                        protected void onError(int errorCode, String errorMessage) {
                            ToastUtil.showLongMessage("视力数据保存失败");
                        }
                    });
        }
        boolean isLastStuent = (currentIndex == mStudentList.size() - 1);
        mAfterTestDialog = new AfterTestDialog.Builder(EyeTestActivity.this, R.style.style_common_dialog)
                .setLeftEye("" + mLeftEye)
                .setRightEye("" + mRightEye)
                .setUserName("" + measureStudent.getRealname())
                .setShowContinueText(isShow)
                .setNextName(nextName)
                .setFinishTv(isLastStuent ? "完成" : "结束测试")
                .setTrainTime(new Date())
                .setOnLittleHelperListener(new AfterTestDialog.AfterTestListener() {
                    @Override
                    public void onFinish() {
                        AppManager.getInstance().killOtherActivity(EyeTestMainActivity.class);
                        startActivity(EyeTestMainActivity.class);
                        finish();
                    }

                    @Override
                    public void onContinue() {
                        //现显示提示界面
                        prepareStudentTest(next);
                    }
                }).create();
        mAfterTestDialog.show();
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_UP) {
            //两次点击大于1秒
            long currentTime = System.currentTimeMillis();
            if (mLastOnKeyTime > 0 && currentTime - mLastOnKeyTime < 500) {
                return true;
            }
            mLastOnKeyTime = currentTime;
            LogUtil.e("---查看按键对应的数字---" + event.getKeyCode());
            if (isKeyDwon) {
                switch (event.getKeyCode()) {
                    case KeyEvent.KEYCODE_DPAD_UP:
                        userChoose(TOP);
                        return true;
                    case KeyEvent.KEYCODE_DPAD_DOWN:
                        userChoose(BOTTOM);
                        return true;
                    case KeyEvent.KEYCODE_DPAD_LEFT:
                        userChoose(LEFT);
                        return true;
                    case KeyEvent.KEYCODE_DPAD_RIGHT:
                        userChoose(RIGHT);
                        return true;
                    case KeyEvent.KEYCODE_MOVE_HOME:
                        userChoose(LEFT_TOP);
                        return true;
                    case KeyEvent.KEYCODE_MOVE_END:
                        userChoose(LEFT_BOTTOM);
                        return true;
                    case KeyEvent.KEYCODE_PAGE_UP:
                        userChoose(RIGHT_TOP);
                        return true;
                    case KeyEvent.KEYCODE_PAGE_DOWN:
                        userChoose(RIGHT_BOTTOM);
                        return true;
                    case KeyEvent.KEYCODE_NUMPAD_ENTER://遥控中间键
                        //用户点击返回键：
                        userChooseError();
                        return true;
                    case KeyEvent.KEYCODE_DEL://返回键
                        finish();
                        return true;
                }
            }
        }
        return super.dispatchKeyEvent(event);
    }


    private double getResult() {
        int result = 0;
        if (null != mCollect && mCollect.size() > 0) {

            for (LinkedHashMap.Entry<Integer, List<E>> entry : mCollect.entrySet()) {
                result = entry.getKey();
            }
        }
        String levelByIndex = "";
        if (mGroupDecimal == EYE_SETTING_5) {
            levelByIndex = "" + Eye.getLevelByIndex(result, mDistance == EyeConfig.EYE_DISTANCE_5);
        } else {
            levelByIndex = "" + Eye.get2LevelByIndex(result, mDistance == EyeConfig.EYE_DISTANCE_5);
        }
        return Double.parseDouble(levelByIndex);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            //两次点击大于1秒
            long currentTime = System.currentTimeMillis();
            if (mLastOnKeyTime > 0 && currentTime - mLastOnKeyTime < 500) {
                return true;
            }
            mLastOnKeyTime = currentTime;
            if (isKeyDwon) {
                userChooseError();
            }
        }
        return super.onTouchEvent(event);

    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            AppManager.getInstance().killOtherActivity(EyeTestMainActivity.class);
            startActivity(EyeTestMainActivity.class);
            finish();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @OnClick({R.id.next_left})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.next_left:
                int next = currentIndex + 1;
                if (next < mStudentList.size()) {
                    prepareStudentTest(next);
                } else {
                    finish();
                }
                break;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (BDttsUtils.getInstance() != null) {
            BDttsUtils.getInstance().pause();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (BDttsUtils.getInstance() != null) {
            BDttsUtils.getInstance().resume();
        }
    }

    @Override
    public void finish() {
        super.finish();
        if (BDttsUtils.getInstance() != null) {
            BDttsUtils.getInstance().stop();
        }
    }
}
