package xn.xxp.home.auth.fragment;

import static com.njlz.util.SmartConsts.DEV_SMARTDATA_IDENTIFY;
import static com.njlz.util.SmartConsts.DEV_SMARTDATA_LOCATION;

import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.njlz.event.SmartDataEvent;
import com.njlz.face.FaceUtils;
import com.njlz.smartdata.FaceIdentifyData;
import com.njlz.smartdata.FaceLocationData;
import com.njlz.smartdata.FaceRectF;
import com.njlz.util.ThreadPoolUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONObject;

import java.util.List;

import core.ui.fragment.RcBaseFragment;
import http.client.HttpTool;
import http.vo.response.UserVo;
import kotlin.Triple;
import okhttp3.Response;
import xn.xxp.HomeActivity;
import xn.xxp.databinding.FragmentAuthLzFaceBinding;
import xn.xxp.home.auth.AuthType;
import xn.xxp.home.auth.ChoiceAuthActivity;
import xn.xxp.room.RoomTool;
import xn.xxp.room.bean.Face;
import xn.xxp.room.bean.LabConfig;

/**
 * 览众人脸识别
 */
public class LzFaceAuthFragment extends RcBaseFragment<FragmentAuthLzFaceBinding> implements SurfaceHolder.Callback, ViewTreeObserver.OnGlobalLayoutListener {
    private FragmentAuthLzFaceBinding binding;
    private SurfaceHolder surfaceHolder;
    private volatile boolean checking = false;
    private List<Face> faceList;
    private LabConfig labConfig;

    @NonNull
    @Override
    protected FragmentAuthLzFaceBinding createViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) {
        return binding = FragmentAuthLzFaceBinding.inflate(inflater, container, false);
    }

    @Override
    protected void initViews(@Nullable Bundle savedInstanceState) {
        try {
            FaceUtils.getInstance().init(getActivity());
            EventBus.getDefault().register(this);
            binding.faceFRV.setDrawConfig(Color.GREEN, 1, false, false);
            surfaceHolder = binding.faceSV.getHolder();
            surfaceHolder.addCallback(this);
            binding.faceSV.getViewTreeObserver().addOnGlobalLayoutListener(this);
            faceList = RoomTool.getInstance().faceDao().getAll();
            labConfig = RoomTool.getInstance().labConfigDao().getLabConfig();
        } catch (Exception e) {
            LogUtils.e(Log.getStackTraceString(e));
            showToast("正在同步人脸,请稍后重试!");
            ActivityUtils.finishToActivity(HomeActivity.class, false);
        }
    }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onEvent(SmartDataEvent messageEvent) {
        switch (messageEvent.getDataType()) {
            // 识别结果
            case DEV_SMARTDATA_IDENTIFY:
                showRecognitionResult();
                break;
            // 检测结果
            case DEV_SMARTDATA_LOCATION:
                showFaceDetectResult();
                break;
        }
    }


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

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


    @Override
    public void onStop() {
        super.onStop();
        ThreadUtils.cancel(faceTask);
        ThreadUtils.cancel(labUserTask);
        EventBus.getDefault().unregister(this);
        FaceUtils.getInstance().destroy();
        LogUtils.d("览众释放");
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        initPreview();
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {

    }

    @Override
    public void onGlobalLayout() {
        binding.faceSV.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    }

    private void initPreview() {
        ThreadPoolUtil.getInstance().exe(new Runnable() {
            @Override
            public void run() {
                if (!isDetached()) {
                    int ret = FaceUtils.getInstance().startPreview(binding.faceSV);
                    if (ret != 0) {
                        ToastUtils.showLong("打开相机失败，错误码 = " + ret);
                    } else {
                        int operateRet = FaceUtils.getInstance().startFaceRecog();
                        if (operateRet != 0) {
                            ToastUtils.showLong("开启人脸识别失败，错误码 ：" + operateRet);
                        }
                    }
                }
            }
        });
    }

    /**
     * 显示人脸检测结果
     */
    private void showFaceDetectResult() {
        FaceLocationData[] faceLocationDatas = FaceUtils.getInstance().getFaceLocationDatas();
        if (faceLocationDatas == null) {
            return;
        }
        for (FaceLocationData faceLocationData : faceLocationDatas) {
            FaceRectF[] faceRectFs = faceLocationData.getFaceRectFS();
            binding.faceFRV.setFaceRectFs(faceRectFs);
        }
    }


    ThreadUtils.SimpleTask<UserVo> faceTask;
    ThreadUtils.SimpleTask<Triple<Integer, String, UserVo>> labUserTask;

    /**
     * 获取识别结果
     */
    public void showRecognitionResult() {
        if (!checking && !isDetached()) {
            checking = true;
            FaceUtils.getInstance().stopFaceTask();
            FaceIdentifyData[] datas = FaceUtils.getInstance().getIdentifyResultDatas();
            if (datas != null && datas.length > 0) {
                ThreadUtils.cancel(faceTask);
                LogUtils.json("识别到人", datas);
                faceTask = new ThreadUtils.SimpleTask<UserVo>() {
                    @Override
                    public UserVo doInBackground() throws Throwable {
                        FaceIdentifyData faceIdentifyData = datas[0];
                        LogUtils.json("识别结果", faceIdentifyData);
                        String faceId = faceIdentifyData.getFaceId();
                        if (null == faceId || faceId.isEmpty() || null == faceList) {
                            return null;
                        }
                        for (Face face : faceList) {
                            if (faceId.startsWith(String.valueOf(face.getUserId()))) {
                                UserVo userVo = new UserVo();
                                userVo.userId = String.valueOf(face.getUserId());
                                userVo.userName = face.getUserName();
                                userVo.userType = face.getUserType();
                                userVo.pageType = face.getPageType();
                                userVo.isWhite = face.getIsWhite();
                                userVo.isDutyUser = face.getIsDutyUser();
                                return userVo;
                            }
                        }

                        return null;
                    }

                    @Override
                    public void onSuccess(UserVo result) {
                        LogUtils.json("识别结果", result);
                        if (!isDetached()) {
                            if (result == null) {
                                ThreadUtils.runOnUiThreadDelayed(() -> {
                                    checking = false;
                                    FaceUtils.getInstance().startFaceRecog();
                                }, 1000);
                                showToast("识别失败，请重试！");
                            } else {
                                ThreadUtils.cancel(labUserTask);
                                labUserTask = new ThreadUtils.SimpleTask<Triple<Integer, String, UserVo>>() {
                                    @Override
                                    public Triple<Integer, String, UserVo> doInBackground() throws Throwable {
                                        try {
                                            Response response = HttpTool.getLabStatusById(String.valueOf(labConfig.getLabId()), result.userId);
                                            if (response.isSuccessful()) {
                                                String json = response.body().string();
                                                LogUtils.d("识别准入", json);
                                                JSONObject jsonObject = new JSONObject(json);
                                                int code = jsonObject.getInt("code");
                                                String message = jsonObject.getString("message");
                                                if (200 == code) {
                                                    UserVo userVo = GsonUtils.fromJson(jsonObject.getJSONObject("data").toString(), UserVo.class);
                                                    return new Triple<>(code, TextUtils.isEmpty(message) ? "" : message, userVo);
                                                }
                                                return new Triple<>(code, TextUtils.isEmpty(message) ? "" : message, result);
                                            }
                                        } catch (Exception e) {
                                            LogUtils.e(Log.getStackTraceString(e));
                                        }
                                        return null;
                                    }

                                    @Override
                                    public void onSuccess(Triple<Integer, String, UserVo> result) {
                                        if (!isDetached()) {
                                            if (null == result) {
                                                showToast("查询异常,请重试!");
                                                ThreadUtils.runOnUiThreadDelayed(() -> {
                                                    if (!isDetached() && isAdded() && getActivity() != null) {
                                                        checking = false;
                                                        FaceUtils.getInstance().startFaceRecog();
                                                    }
                                                }, 1000);
                                                return;
                                            }
                                            if (result.getFirst() != 200) {
                                                ThreadUtils.runOnUiThreadDelayed(() -> {
                                                    if (!isDetached() && isAdded() && getActivity() != null) {
                                                        checking = false;
                                                        FaceUtils.getInstance().startFaceRecog();
                                                    }
                                                }, 1000);
                                                showToast(result.getSecond());
                                            } else {
                                                if (isAdded() && getActivity() != null) {
                                                    ChoiceAuthActivity fourChoiceAuthActivity = (ChoiceAuthActivity) LzFaceAuthFragment.this.requireActivity();
                                                    fourChoiceAuthActivity.authSuccess(AuthType.FACE, result.getThird());
                                                }
                                            }
                                        }
                                    }
                                };
                                ThreadUtils.executeByCached(labUserTask);
                            }
                        }
                    }
                };
                ThreadUtils.executeByCached(faceTask);
            } else {
                ThreadUtils.runOnUiThreadDelayed(() -> {
                    if (!isDetached()) {
                        checking = false;
                        FaceUtils.getInstance().startFaceRecog();
                    }
                }, 1000);
            }
        }
    }
}