package com.oo.eye.activity;

import android.os.Bundle;
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.common.BaseActivity;
import com.app.baselibrary.commonUtil.BDttsUtils;
import com.app.baselibrary.commonUtil.LogUtil;
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 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(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 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 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() {
        initialize();
        prepareQueue();
    }

    private void initialize() {
        mStudentList = EyeConfig.getInstance().getStudents();

        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 {
            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("");
        }
        continueTest();
    }

    private void nextStudent() {
        final int next = currentIndex+1;
        if (next >= mStudentList.size()) {
            isTestSuccess = true;
            speak("本次测试结束");
//            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();
        } else {
            prepareStudentTest(next);
        }
    }

    /**
     * 开始测试
     *
     * @param isNewTest true 代表测试的第一只眼 代表左眼  false代表测量另一只眼 右眼
     */
    private void resetView(final boolean isNewTest) {
        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) {
        eImageView1.setImageResource(Eye.getBitmapRid(e.getLevel(),mDistance));
        eImageView1.setPivotX(eImageView1.getWidth()/2);
        eImageView1.setPivotY(eImageView1.getHeight()/2);//支点在图片中心
        switch (e.getDirect()){
            case TOP:
                eImageView1.setRotation(0);
                break;
            case RIGHT_TOP:
                eImageView1.setRotation(45);
                break;
            case RIGHT:
                eImageView1.setRotation(90);
                break;
            case RIGHT_BOTTOM:
                eImageView1.setRotation(135);
                break;
            case BOTTOM:
                eImageView1.setRotation(180);
                break;
            case LEFT_BOTTOM:
                eImageView1.setRotation(225);
                break;
            case LEFT:
                eImageView1.setRotation(270);
                break;
            case LEFT_TOP:
                eImageView1.setRotation(315);
                break;
        }
    }

    /**
     * 随机生成每一行的视标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(8);
        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(8);
        //相邻的不能一样
        while (lastDirect == newDirect) {
            newDirect = random.nextInt(8);
        }

        return newDirect;
    }


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

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

    /**
     * 选择的方向
     *
     * @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) &&
                    mCollect.get(mLevelIndex - 1) != null && mCollect.get(mLevelIndex - 1).size() > 0)) {
                if (isSecondTest) {
                    mRightLine = leastAnswerCount;
                } else {
                    mLeftLine = leastAnswerCount;
                }
                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() {
//        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);
        nextStudent();
    }

    @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;
            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 true;
        }
        return super.dispatchKeyEvent(event);
    }


    private double getResult() {
        if (null == mCollect || mCollect.size() == 0) {
            if (mDistance == EyeConfig.EYE_DISTANCE_5) {
                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, mDistance == EyeConfig.EYE_DISTANCE_5);
        return Double.parseDouble(levelByIndex);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN){
            userChooseError();
        }
        return super.onTouchEvent(event);

    }

    @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);
        ButterKnife.bind(this);
    }

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