package com.qy.agv.activity;

import static com.qy.agv.util.Constant.CACHE_BIND_CONTROL;
import static com.qy.agv.util.Constant.CACHE_LOGIN_KEY;
import static com.qy.agv.util.Constant.user;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.SimpleAdapter;

import com.google.gson.Gson;
import com.qy.agv.R;
import com.qy.agv.activity.adapter.DirViewAdapter;
import com.qy.agv.activity.dao.MainDao;
import com.qy.agv.activity.model.RelocModel;
import com.qy.agv.activity.model.RobotModel;
import com.qy.agv.comm.BaseActivity;
import com.qy.agv.comm.CacheService;
import com.qy.agv.databinding.QyRobotBinding;
import com.qy.agv.receiver.SocketService;
import com.qy.agv.util.Constant;
import com.qy.agv.util.DataUtil;
import com.qy.agv.util.DateUtil;
import com.qy.agv.util.HttpsUtil;
import com.qy.agv.util.MyProgress;
import com.qy.agv.util.StringUtils;
import com.qy.agv.util.ToastUtils;

import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;
import org.xutils.common.Callback;
import org.xutils.http.RequestParams;
import org.xutils.x;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ControlActivity extends BaseActivity {
    public static Logger mylog =Logger.getLogger(ControlActivity.class);

    private Context context;
    private DirViewAdapter dirViewAdapter;
    private QyRobotBinding binding;
    private RobotModel robotModel;
    private final Map<Integer, String> statusMap = new HashMap<Integer, String>();
    private final Map<Integer, String> relocMap = new HashMap<Integer, String>();
    public ServiceConnection sc;
    public SocketService socketService;
    private Intent socketIntent;
    private int robot_status = 0;
    private String speed = "0";
    private PopupWindow popupWindow;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = QyRobotBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        x.view().inject(this);
        context = this;
//        if(user==null){
//            ToastUtils.showToast(context, "该设备没有登录");
//            finish();
//            return;
//        }
        initCommonTop2();
        init();
        bindRobot();
        initStatus();
        initRelocStatus();
        reloadRobot();
    }

    @SuppressLint("ClickableViewAccessibility")
    public void init(){
        binding.btnResetLm.setOnClickListener(view->{
            if(robotModel==null){
                ToastUtils.showToast(context, "没有绑定机器人");
                return;
            }
            selPosition(1);
        });
        binding.btnConfirmLm.setOnClickListener(view->{
            if(robotModel==null){
                ToastUtils.showToast(context, "没有绑定机器人");
                return;
            }
            sendCommand("qrdw");
        });

        dirViewAdapter = new DirViewAdapter(DataUtil.getDir(""),this);
        dirViewAdapter.setOnTouchListener((View v, MotionEvent event) ->{
            int sel = v.getId();
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if(sel == 0 && robot_status != 100){
                        robot_status = 100;
                        //上升
                        sendCommand("rise");
                    }
                    if(sel == 1 && robot_status != 19){
                        robot_status = 19;
                        //前进
                        sendCommand("forward");
                    }
                    if(sel == 2 && robot_status != 101){
                        robot_status = 101;
                        //下降
                        sendCommand("decline");
                    }
                    if(sel == 3 && robot_status != 21){
                        //左转
                        robot_status = 21;
                        sendCommand("left");
                    }
                    if(sel == 4 && robot_status != 102){
                        //停止
                        robot_status = 102;
                        sendCommand("stop");
                    }
                    if(sel == 5 && robot_status != 22){
                        robot_status = 22;
                        //右转
                        sendCommand("right");
                    }
                    if(sel == 7 && robot_status != 20){
                        robot_status = 20;
                        //后退
                        sendCommand("back");
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    if(robot_status > 0){
                        if(robot_status < 100){
                            //停止
                            sendCommand("stop");
                        }
                        robot_status = 0;
                    }
                    break;
            }
            return true;
        });
        binding.gridView.setAdapter(dirViewAdapter);
        binding.gridView.setFocusable(false);
        dirViewAdapter.notifyDataSetChanged();
    }

    @Override
    public void receiverTask(String barcode) {
        if(barcode.startsWith("02-")) {
            parserRobot(barcode);
        }
        if(barcode.startsWith("01-")) {
            if(robotModel==null){
                ToastUtils.showToast(context, "没有绑定机器人");
                return;
            }
            barcode = barcode.replace("01-", "");
            String title = "";
            if(barcode.startsWith("CDW")){
                title = "重新定位";
            }
            String[] info_array = barcode.split(",");
            if(info_array.length > 1){
                String task = info_array[0];
                if(barcode.startsWith(task+",0")) {
                    String selRobot = task + "," + robotModel.getRobotId();
                    barcode = barcode.replace(task + ",0", selRobot);
                }
            }
            push(barcode, title);
        }
    }

    public void bindRobot() {
       String bindRobotID = CacheService.getInstance(context).getCache(CACHE_BIND_CONTROL, "ROBOT_ID");
       if(!StringUtils.isEmpty(bindRobotID)){
           parserRobot("02-" + bindRobotID);
       }
    }

    public void parserRobot(String bindRobotID){
        if(StringUtils.isEmpty(bindRobotID)){
            ToastUtils.showToast(context, "机器人编号不能为空");
            return;
        }
        if(bindRobotID.startsWith("02-")){
            bindRobotID = bindRobotID.replace("02-", "");
            searchRobot(bindRobotID, true);
        }
    }

    private void searchRobot(String bindRobotID, boolean isSocket) {
        MyProgress myProgress = MyProgress.getInstance();
        myProgress.show(context, "提示", "正在加载");
        RequestParams params = httParams(Constant.ROBOT_DETAIL);
        params.addBodyParameter("robotId", bindRobotID);
        CacheService.getInstance(context).clear(CACHE_BIND_CONTROL);
        x.http().get(params, new Callback.CommonCallback<JSONObject>() {
            @Override
            public void onSuccess(JSONObject rs) {
                mylog.info(rs.toString());
                try {
                    if (rs.getInt("code") != 200) {
                        ToastUtils.showToast(context, "请求失败");
                    } else {
                        if (rs.getBoolean("success")) {
                            Object data_o = rs.get("data");
                            robotModel = new Gson().fromJson(data_o.toString(), RobotModel.class);
                            Constant.robotModel = robotModel;
                            Constant.robotModel.setPort(Constant.SOCKET_PORT);
                            binding.robotNo.setText(robotModel.getRobotId());
//                            speed = Constant.robotModel.getRobotSpeed();
                            Integer robot_status = robotModel.getTaskStatus();
                            binding.robotState.setText(statusMap.get(robot_status));
                            binding.tvElectric.setText(robotModel.getElectricQuantity()+"%");
                            int relocStatus = robotModel.getRelocStatus();
                            if(relocStatus == 3) {
                                binding.tvRobotSite.setText(robotModel.getCurrentStation());
                            }else if(relocStatus == 2){
                                binding.tvRobotSite.setText("正在重定位");
                            }else if(relocStatus == 0 || relocStatus == 1){
                                showSiteDialog(relocStatus);
                            }else{
                                binding.tvRobotSite.setText("位置异常");
                            }
                            binding.tvRunMsg.setText(SocketService.status);
//                            binding.robotState.setText(speed + "米/秒");
                            CacheService.getInstance(context).saveCache(CACHE_BIND_CONTROL, "ROBOT_ID", robotModel.getRobotId());
                            if(isSocket){
                                bindSocketService();
                            }
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    mylog.error(e);
                }
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                ex.printStackTrace();
                mylog.error("请求异常：", ex);
                HttpsUtil.parserError(ControlActivity.this, ex);
            }

            @Override
            public void onFinished() {myProgress.close();
            }

            @Override
            public void onCancelled(CancelledException arg0) {
                mylog.error("onRead:", arg0);
            }
        });
    }

    private void reloadRobot(){
        new Handler().postDelayed(()->{
            if(robotModel!=null){
                searchRobot(robotModel.getRobotId(), false);
            }
        }, 3000);

        new Handler().postDelayed(()->{
            binding.tvRunMsg.setText(SocketService.status);
        }, 1000);
    }

    private void push(String qrcode, String title){
        if(StringUtils.isEmpty(qrcode)){
            ToastUtils.showToast(context, "指令参数不能为空");
            return;
        }
        MyProgress progress = MyProgress.getInstance();
        progress.show(context, "提示", "正在发送"+title+"请求任务");
        RequestParams params = httParams(Constant.PUSH_TASK);
        params.addBodyParameter("user_id", user.getUser_id().toString());
        params.addBodyParameter("qrcode", qrcode);
        x.http().post(params, new Callback.CommonCallback<JSONObject>() {
            @Override
            public void onSuccess(JSONObject rs) {
                mylog.info(rs);
                try {
                    if (rs.getInt ("code")!= 200) {
                        ToastUtils.showToast(context, "请求失败");
                    } else {
                        if(rs.getBoolean("success")){
                            ToastUtils.showToast(context, "请求发送成功");
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                ex.printStackTrace();
                HttpsUtil.parserError(ControlActivity.this, ex);
            }
            @Override
            public void onFinished() {
                progress.close();
            }
            @Override
            public void onCancelled(CancelledException arg0) {
                mylog.error("onRead:", arg0);
            }
        });
    }


    private void initStatus(){
        statusMap.put(0, "空闲");
        statusMap.put(1, "警告");
        statusMap.put(2, "运行");
        statusMap.put(3, "暂停");
        statusMap.put(4, "正常");
        statusMap.put(5, "失败");
        statusMap.put(6, "取消");
    }

    private void initRelocStatus(){
        relocMap.put(0, "定位失败");
        relocMap.put(1, "定位正确");
        relocMap.put(2, "正在重定位");
        relocMap.put(3, "定位完成");
    }

    protected void bindSocketService() {
        sc = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                SocketService.SocketBinder binder = (SocketService.SocketBinder) iBinder;
                socketService = binder.getService();
            }
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
            }
        };
        socketIntent = new Intent(getApplicationContext(), SocketService.class);
        bindService(socketIntent, sc, BIND_AUTO_CREATE);
    }

    @Override
    protected String getCommonTopTitle() {
        return "单机控制";
    }

    @Override
    protected int getCommonTopICO() {
        return 0;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        super.onKeyDown(keyCode, event);
        if(keyCode == 4 || keyCode == 67){
            finish();
        }
        if(keyCode == robot_status){
            return true;
        }
        if(16 >= keyCode && keyCode >= 8){
            double current_speed = (keyCode - 7) * 0.1 + 0.05;
            if(current_speed > 0.85){
                current_speed = 0.85;
            }
            speed = new BigDecimal(current_speed).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
            binding.robotState.setText(speed+"米/秒");
        }
        if(keyCode == 111){//上升
            robot_status = 111;
            sendCommand("rise");
        }
        if(keyCode == 61){//下降
            robot_status = 61;
            sendCommand("decline");
        }
        if(keyCode == 19){ //前进
            robot_status = 19;
            sendCommand("forward");
        }
        if(keyCode == 20){ //后退
            robot_status = 20;
            sendCommand("back");
        }
        if(keyCode == 21){//左转
            robot_status = 21;
            sendCommand("left");
        }
        if(keyCode == 22){//右转
            robot_status = 22;
            sendCommand("right");
        }
        return true;
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        super.onKeyDown(keyCode, event);
        if(robot_status > 0){
            if(robot_status!=61 && robot_status != 111){
                //停止
                sendCommand("stop");
            }
            robot_status = 0;
        }
        return true;
    }

    private void sendCommand(String cmd, String...args){
        if(socketService == null){
            ToastUtils.showToast(context, "没有连接机器人");
            return;
        }
        String id = socketService.getSendID();
        boolean rs = false;
        switch (cmd){
            case "rise":
                rs = socketService.sendData("Hrise,"+id+",T");
                break;
            case "decline":
                rs = socketService.sendData("Hdecline,"+id+",T");
                break;
            case "forward":
                binding.robotState.setText(speed + "米/秒");
                rs = socketService.sendData("Hforward,"+id+","+speed+"T");
                break;
            case "back":
                binding.robotState.setText(speed + "米/秒");
                rs = socketService.sendData("Hback,"+id+","+speed+"T");
                break;
            case "left":
                binding.robotState.setText(speed + "米/秒");
                rs = socketService.sendData("Hleft,"+id+","+speed+"T");
                break;
            case "right":
                binding.robotState.setText(speed + "米/秒");
                rs = socketService.sendData("Hright,"+id+","+speed+"T");
                break;
            case "stop":
                rs = socketService.sendData("Hstop,"+id+",T");
                break;
            case "cdw":
                rs = socketService.sendData("Hcdw,"+id+","+args[0]+"T");
                if(rs){
                    Map<String, String> msg = new HashMap<>();
                    msg.put("1T", "重定位成功");
                    msg.put("2T", "重定位失败");
                    socketService.checkID.put(id, msg);
                    checkCDW(id, 3);
                }
                break;
            case "cdwtx":
                rs = socketService.sendData("Hcdwtx,"+id+",T");
                break;
            case "qrdw":
                Map<String, String> msg = new HashMap<>();
                msg.put("0T", "定位成功");
                msg.put("1T", "定位失败");
                socketService.checkID.put(id, msg);
                rs = socketService.sendData("Hqrdw,"+id+",T");
                break;
        }
        if(!rs){
            ToastUtils.showToast(context, "发送失败");
        }
    }

    private void selPosition(int type){
        View view = binding.getRoot().getRootView();
        List<Map<String,String>> params = new ArrayList<>();
        List<RelocModel> relocModels = MainDao.getInstance().searchReloc(context);
        for (RelocModel relocModel : relocModels) {
            Map<String, String> map = new HashMap<>();
            map.put("name", relocModel.getRelocName());
            map.put("value", relocModel.getId());
            params.add(map);
        }
        if(params.size() == 0){
            return;
        }
        ListView mListView = new ListView(this);
        mListView.setBackgroundResource(R.color.white);
        SimpleAdapter simplead = new SimpleAdapter(this, params,
                R.layout.popupwindow_list_item, new String[] { "name"},
                new int[] {R.id.tv_msg});
        mListView.setAdapter(simplead);
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                try {
                    if(type == 1) {
                        String value = params.get(position).get("value");
                        sendCommand("cdw", value);
                    }
                    if(type == 2){
                        push("", "");
                    }
                    popupWindow.dismiss();
                }catch (Exception ex){
                    mylog.error("选择位置异常", ex);
                }
            }
        });
        WindowManager manager = this.getWindowManager();
        DisplayMetrics outMetrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(outMetrics);
        double width = outMetrics.widthPixels*0.8;
        popupWindow = new PopupWindow(view, (int) width,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        //设置窗体的内容
        popupWindow.setContentView(mListView);
        popupWindow.setOutsideTouchable(false);
        popupWindow.setFocusable(false);
        popupWindow.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
        setBackgroundAlpha(0.5f);
        popupWindow.showAtLocation(view, Gravity.CENTER, 0, 0);
        popupWindow.setOnDismissListener(()->{
            setBackgroundAlpha(1.0f);
        });
    }

    public void setBackgroundAlpha(float bgAlpha) {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = bgAlpha;
        getWindow().setAttributes(lp);
    }

    private void checkCDW(String seqID, int flag){
        if(flag == 0){
            socketService.checkID.remove(seqID);
            return;
        }
        flag = flag -1;
        if(socketService.checkID.containsKey(seqID)){
            int finalFlag = flag;
            new Handler().postDelayed(()->{
                sendCommand("cdwtx");
                checkCDW(seqID, finalFlag);
            }, 1000);
        }
    }

    public void showSiteDialog(int status){
        String msg = "";
        if(status == 0){
            msg = "位置异常，请将机器人移到站点，再重新定位";
        }
        if(status == 1){
            msg = "已定位，请将机器人移到"+robotModel.getCurrentStation()+"站点，再确认定位";
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(msg);
        builder.setPositiveButton("OK", (DialogInterface dialog, int which)->{
                dialog.dismiss();
            }
        );
        AlertDialog mAlertDialog = builder.create();
        mAlertDialog.show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(sc!=null) {
            unbindService(sc);
        }
        if(socketIntent != null) {
            stopService(socketIntent);
        }
    }
}
