package com.oo.eye.activity;

import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.app.baselibrary.base.common.BaseActivity;
import com.app.baselibrary.commonUtil.LogUtil;
import com.app.baselibrary.commonUtil.NibiruUtils;
import com.app.baselibrary.commonUtil.PreferencesUtils;
import com.oo.eye.EyeConfig;
import com.oo.eye.R;
import com.oo.eye.R2;
import com.oo.eye.bean.Eye;
import com.oo.eye.bean.Eye.E;
import com.oo.eye.bean.EyeHistroyBean;
import com.oo.eye.manager.DaemonSender;

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

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

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 LEFT_TOP = 4;
    static final int RIGHT_TOP = 5;
    static final int LEFT_BOTTOM = 6;
    static final int RIGHT_BOTTOM= 7;
    private E mSelectE;

    @BindView(R2.id.rl_eye_test_center_time1)
    RelativeLayout timeLayout1;
    @BindView(R2.id.tv_eye_test_center_time1)
    TextView timeText1;

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

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

    @BindView(R2.id.view_eye_test_mask1)
    View maskView1;

    @BindView(R2.id.tv_eye_vision1)
    TextView eyeVision1;
    @BindView(R2.id.tv_eye_vision_count1)
    TextView count1;
    @BindView(R2.id.tv_eye_vision_allow1)
    TextView allow1;
    @BindView(R2.id.tv_eye_vision_right1)
    TextView right1;
    @BindView(R2.id.tv_eye_vision_error1)
    TextView error1;

    private int test_dis = 0;

    private ArrayList<ArrayList<E>> mList = new ArrayList<>();
    private int mLocation;
    private int mLevelIndex = -1;
    private LinkedHashMap<Integer, List<E>> mCollect = new LinkedHashMap<>();
    private EyeHistroyBean mHistroyBean;
    //是否是右眼训练
    private boolean isSecondTest;
    private double mLeftEye = 5.0;
    private int mLeftLine = 0;
    private double mRightEye = 5.0;
    private int mRightLine = 0;
    private long mLastOnKeyTime = -1;
    private boolean isTestSuccess = false;
    private boolean isStartTest = false;

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

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

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

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

    @Override
    protected void init() {
        NibiruUtils.switchVR(true);
        DaemonSender.startEyeTest(this);
        speak("视力测试马上开启");
        initialize();
        prepareQueue();
    }

    private void initialize() {
        mList.clear();
        for (int i = 0; i < 14; i++) {
            mList.add(initLineList(i));
        }
    }

    private void prepareQueue() {
        mHistroyBean = EyeConfig.getInstance().getCuurentBean();
        continueTest();
    }

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

    /**
     * 开始测试
     *
     * @param isNewTest true 代表测试的第一只眼 代表左眼  false代表测量另一只眼 右眼
     */
    private void resetView(final boolean isNewTest) {
        mLevelIndex = -1;
        isSecondTest = !isNewTest;

        String eye = isNewTest ? "右" : "左";

        if (isNewTest) {
            if (mHistroyBean != null) {
                mLeftEye = mHistroyBean.getLeft_eye();
                mRightEye = mHistroyBean.getRight_eye();
            }
        }
        timeLayout1.setVisibility(View.VISIBLE);
        eLayout1.setVisibility(View.GONE);
        maskView1.setVisibility(View.GONE);
        new CountDownTimer(totalTime, intervalTime) {
            @Override
            public void onTick(long millisUntilFinished) {
                long time = millisUntilFinished / 1000;
                timeText1.setText(time + "");
                float f = millisUntilFinished * 1.0f / totalTime;
                if (isSecondTest) {
                    maskView1.setAlpha(1 - f);
                    maskView1.setVisibility(View.VISIBLE);
                } else {
                    maskView1.setVisibility(View.GONE);
                }
                LogUtil.e("onTick");
            }

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

    private void speak(String text) {
        DaemonSender.sendDBTTS(this, text);
    }

    /**
     * 描画E字
     *
     * @param e
     */
    private void drewE(E e) {
        //视力等级
        float level = e.getLevel();
        //视标边长
        int px = Eye.getDip(this, level);
//		RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(px, px);
//		eImageView1.setLayoutParams(params);
//		eImageView2.setLayoutParams(params);
        //视标方向
        int resId;
        switch (e.getDirect()) {
            default:
            case TOP:
                resId = R.drawable.c_top;
                break;
            case RIGHT:
                resId = R.drawable.c_right;
                break;
            case BOTTOM:
                resId = R.drawable.c_bottom;
                break;
            case LEFT:
                resId = R.drawable.c_left;
                break;
            case LEFT_TOP:
                resId = R.drawable.c_left_top;
                break;
            case RIGHT_TOP:
                resId = R.drawable.c_right_top;
                break;
            case LEFT_BOTTOM:
                resId = R.drawable.c_left_bottom;
                break;
            case RIGHT_BOTTOM:
                resId = R.drawable.c_right_bottom;
                break;
        }
        eImageView1.setImageResource(resId);
    }

    /**
     * 随机生成每一行的视标E
     *
     * @param index 第几行
     * @return list
     */
    private ArrayList<E> initLineList(int index) {
        float level = 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, level);
            list.add(e);
        }
        return list;
    }

    /**
     * 获取第一个E;
     *
     * @param random
     * @param index
     * @return
     */
    private int getFirstDirect(Random random, int index) {
        int direct = random.nextInt(4);
        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(4);
        //相邻的不能一样
        while (lastDirect == newDirect) {
            newDirect = random.nextInt(4);
        }

        return newDirect;
    }


    /**
     * 下一个测试
     */
    private void next(boolean isNextLine) {
        if (isNextLine) {
            mLevelIndex++;
            mLocation = 0;
            eyeVision1.setText("" + Eye.getLevelByIndex(mLevelIndex, true));
            count1.setText("");
            allow1.setText("");
            right1.setText("");
            error1.setText("");
        } else {
            mLocation++;
        }

        mSelectE = mList.get(mLevelIndex).get(mLocation);
        drewE(mSelectE);
    }

    /**
     * 选择的方向
     *
     * @param direct
     */
    private void userChoose(int direct) {
        LogUtil.e("direct:" + direct);
        LogUtil.e("mLevelIndex:" + mLevelIndex);
        //获取当前行答过的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();
//		int verifyErrorCount = 0;
//		//获取每行有多少个e
//		int lineSum = getLineSumByIndex(mLevelIndex);
//		//获取每行答对几个e
//		int leastAnswerCount = Eye.getLeastAnswerCount(mLevelIndex);
//		LogUtil.e("leastAnswerCount:"+leastAnswerCount);
//		//获取当前行答过的e
//		List<E> list = mCollect.get(mLevelIndex);
//		if (null == list || list.size() == 0) {
//			list = new ArrayList<>();
//		}
//		mSelectE.setUserChoose(direct);
//		list.add(mSelectE);
//
//		int rightAnswerCount = 0;
//		for (E e : list) {
//			if (e.isCorrect()) {
//				rightAnswerCount++;
//			}
//		}
//		LogUtil.e("rightAnswerCount:"+rightAnswerCount);
//		//当前行答错的数
//		int errorCount = list.size() - rightAnswerCount;
//		LogUtil.e("errorCount:"+errorCount);
//		//判断是否满足答对的要求
//		boolean isNextLine = rightAnswerCount >= leastAnswerCount;
//		LogUtil.e("isNextLine:"+isNextLine);
//		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) &&
//					mCollect.get(mLevelIndex - 1) != null && mCollect.get(mLevelIndex - 1).size() > 0)) {
//				if(isSecondTest){
//					mRightLine = leastAnswerCount;
//				}else{
//					mLeftLine = leastAnswerCount;
//				}
//				showResult();
//				return;
//			}else {
//				backLastLine();
//				return;
//			}
//		}
//		next(isNextLine);
    }

    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++;
            }
        }
        LogUtil.e("rightAnswerCount:" + rightAnswerCount);
        //当前行答错的数
        int errorCount = list.size() - rightAnswerCount;
        LogUtil.e("errorCount:" + errorCount);
        //判断是否满足答对的要求
        boolean isNextLine = rightAnswerCount >= leastAnswerCount;
        LogUtil.e("isNextLine:" + isNextLine);
        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;
        }
        count1.setText("总共:" + lineSum);
        allow1.setText("正确数:" + leastAnswerCount);
        right1.setText("答对数:" + rightAnswerCount);
        error1.setText("错误数:" + errorCount);
        //必须答对一半才往下走一行的
        //如果错误次数超过一半 (默认位置时上一行没有数据时候)回退一行
        if (errorCount > verifyErrorCount) {
            //如果上一行数据不为空 结束测试
            if (mLevelIndex == 0 || (mCollect.containsKey(mLevelIndex - 1) &&
                    mCollect.get(mLevelIndex - 1) != null && mCollect.get(mLevelIndex - 1).size() > 0)) {
                if (isSecondTest) {
                    mRightLine = leastAnswerCount;
                } else {
                    mLeftLine = leastAnswerCount;
                }
                showResult();
                return;
            } else {
                backLastLine();
                return;
            }
        }
        next(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();
//		int verifyErrorCount = 0;
//		int lineSum = getLineSumByIndex(mLevelIndex);
//		int leastAnswerCount = Eye.getLeastAnswerCount(mLevelIndex);
//		int rightAnswerCount = 0;
//		int direct  = mSelectE.getDirect()+1;
//
//		//获取当前行答过的e
//		List<E> list = mCollect.get(mLevelIndex);
//		mSelectE.setUserChoose(direct);
//		list.add(mSelectE);
//
//		if (null == list || list.size() == 0) {
//			list = new ArrayList<>();
//		} else {
//			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) &&
//					mCollect.get(mLevelIndex - 1) != null && mCollect.get(mLevelIndex - 1).size() > 0)) {
//				if (isSecondTest) {
//					showResult();
//					return;
//				}
//
//				mLeftEye = getResult();
//				resetView(false);
//				return;
//			}else {
//				backLastLine();
//				return;
//			}
//		}
//		next(isNextLine);
    }


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

    /**
     * 单眼测试结束
     */
    private void showResult() {
        //如果不是手动提交
        final Double eyeResult = getResult();
        if (isSecondTest) {//右眼训练
            mRightEye = eyeResult;
            showStudentTestDialog();
        } else {//左眼训练
            mLeftEye = eyeResult;
            resetView(false);
            return;
        }
    }


    private void showStudentTestDialog() {
        int selectId = PreferencesUtils.getInt(EyeConfig.EYE_SETTING_KEY, 0);
        String text = ("测视结束左眼视力" + mLeftEye + "右眼视力" + mRightEye).replace(".", "点");
        if (selectId == 1) {
            text = ("测视结束左眼视力" + Eye.transformSmall(mLeftEye) + "右眼视力" +
                    Eye.transformSmall(mRightEye)).replace(".", "点");
        }
        speak(text);
        Intent intent = new Intent(this, AfterEyeTestActivity.class);
        intent.putExtra("leftEye", mLeftEye);
        intent.putExtra("rightEye", mRightEye);
        intent.putExtra("leftLine", mLeftLine);
        intent.putExtra("rightLine", mRightLine);
        startActivity(intent);
        finish();
    }

    @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("----点击的Key值----"+event.getKeyCode());
            switch (event.getKeyCode()) {
                case KeyEvent.KEYCODE_BUTTON_X:
                    userChoose(TOP);
                    return true;
                case KeyEvent.KEYCODE_BUTTON_B:
                    userChoose(BOTTOM);
                    return true;
                case KeyEvent.KEYCODE_BUTTON_A:
                    userChoose(LEFT);
                    return true;
                case KeyEvent.KEYCODE_BUTTON_Y:
                    userChoose(RIGHT);
                    return true;
                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_DPAD_CENTER://遥控中间键
                    //用户点击返回键：
                    userChooseError();
                    return true;

            }
            return true;
        }
        return super.dispatchKeyEvent(event);
    }

    private double getResult() {
        if (null == mCollect || mCollect.size() == 0) {
            if (test_dis == 0) {
                return 4.0;
            } else {
                return 3.8;
            }
        }
        int result = 0;
        for (LinkedHashMap.Entry<Integer, List<E>> entry : mCollect.entrySet()) {
            result = entry.getKey();
        }
        final String levelByIndex = "" + Eye.getLevelByIndex(result, test_dis == 0);
        return Double.parseDouble(levelByIndex);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            finish();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // TODO: add setContentView(...) invocation
        ButterKnife.bind(this);
    }

    @OnClick({R.id.next_left})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.next_left:
                break;
        }
    }
}
