package com.oo.eye.activity;

import android.os.CountDownTimer;
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.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.widget.AfterTestDialog;

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

import butterknife.BindView;
import butterknife.OnClick;

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.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;

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

    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 long totalTime = 5000;
    private long intervalTime = 1000;

    private AfterTestDialog mAfterTestDialog;

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

    @Override
    protected void init() {
        initialize();
        prepareQueue();
    }

    private void initialize() {
        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);

        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;
        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 = Eye.getIndexByValue(e, true) - 1;
                nextE(true);
            }
        }.start();
        speak("请遮住您的" + eye + "眼");
        mCollect.clear();
    }

    private void speak(String text) {
        BDttsUtils.getInstance().speak(text);
    }

    /**
     * 描画E字
     *
     * @param e
     */
    private void drewE(E e) {
        int angle = 0;
        LogUtil.e("getDirect:"+e.getDirect());
        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);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 选择的方向
     *
     * @param direct
     */
    private void userChoose(int direct) {
        //获取当前行答过的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 void userChooseError() {
        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;
            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();
        }

        mAfterTestDialog = new AfterTestDialog.Builder(EyeTestActivity.this,R.style.style_common_dialog)
                .setLeftEye(""+mLeftEye)
                .setRightEye(""+mRightEye)
                .setUserName(""+measureStudent.getRealname())
                .setShowContinueText(isShow)
                .setNextName(nextName)
                .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;
            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;

                }
            }
        }
        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);
                }
                break;
        }
    }
}
