<script setup lang="ts">
import { doGetToken } from "@/api/login/HuiBang";
import { loginFaceLogin } from "@/api/login";
definePage({
  style: {
    navigationBarTitleText: '人脸识别',
    navigationStyle: 'custom',
  },
})
import { ref, onMounted } from 'vue';
import { HUIBANG_BASE_URL } from '@/config/setting';
import {ensureDecodeURIComponent, parseUrlToObj} from "@/utils";
import {isPageTabbar} from "@/tabbar/store";
import {setToken} from "@/utils/token-util";
import {loginPublic} from "@/utils/login-util";
import {tabbarList} from "@/tabbar/config";
const code = ref<string>('');//用于辅助验证人脸的code
const showFace = ref<boolean>(false);
const facingMode = ref<string>("user");//摄像头类型
const mediaStreamTrack = ref();// 媒体流，用于关闭摄像头
const videoStyle = ref(
  {
    width: '250px',
    height: '250px',
    transform: 'rotate(0deg)',
    borderRadius: '50%',
  }
)
const videoStyle2 = ref(
  {
    width: '250px',
    height: '250px',
    borderRadius: '50%',
  }
)
const ssoToken = ref<string>('');
const userFaceImage = ref<string>(''); //人脸图片

onMounted(() => {
  code.value = uni.getStorageSync("u-code");
})

const onCodeConfirm = () => {
  if (code.value.length < 4) {
    uni.showToast({ title: "请填写完整信息", icon: 'none'})
    return;
  }
  showFace.value = true;
  init();
}

const init = () => {
  getToken();
  invokingCamera();
}

//初始化镜头
const invokingCamera = () => {
  showFace.value = true;
  // 检查浏览器对摄像头的支持情况

  console.log(navigator,'参数数据')

  if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
    uni.showToast({ title: "您的设备不支持打开摄像头功能", icon: 'none'})
    return;
  }
  const constraints = {
    audio: false,
    video: {
      // 前置摄像头
      facingMode: {
        exact: facingMode.value
      },
      // 手机端相当于高
      width: 200,
      // 手机端相当于宽
      height: 200,
    },
  };
  // 请求摄像头权限并获取视频流
  navigator.mediaDevices.getUserMedia(constraints)
    .then((stream) => {
      mediaStreamTrack.value = stream;
      // 成功获取到视频流，这里可以对视频流进行处理
      // 例如，将视频流显示在页面上的某个元素中
      const videoElement = document.querySelector("video");
      videoElement!.srcObject = stream;
      videoElement!.play();
      setTimeout(() => {
        handlePhotographClick();
      }, 1000);
    })
    .catch((err) => {
      // 获取视频流失败，进行相应提示
      console.log('获取摄像头视频流失败：', err);
    })
}
//关闭镜头
const handlePhotographCloseClick = () => {
  if (mediaStreamTrack.value) {
    // 关闭摄像头
    mediaStreamTrack.value.getTracks().forEach(function (track: any) {
      track.stop();
    });
    mediaStreamTrack.value = null;
  }
}
//拍照
const handlePhotographClick = () => {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  const video = document.querySelector("video");
  canvas.width = Math.min(video!.videoWidth, video!.videoHeight);
  canvas.height = Math.max(video!.videoWidth, video!.videoHeight);
  // canvas.width = Math.max(video.videoWidth, video.videoHeight);
  // canvas.height = Math.min(video.videoWidth, video.videoHeight);
  //console.log(canvas.width);
  //console.log(canvas.height);
  ctx!.drawImage(video!, 0, 0, canvas.width, canvas.height);

  // ****** 镜像处理 ******
  function getPixel(imageData: any, row: any, column: any) {
    const uint8ClampedArray = imageData.data;
    const width = imageData.width;
    const height = imageData.height;
    const pixel = [];
    for (let i = 0; i < 4; i++) {
      pixel.push(uint8ClampedArray[row * width * 4 + column * 4 + i]);
    }
    return pixel;
  }

  function setPixel(imageData: any, row: any, column: any, pixel: any) {
    const uint8ClampedArray = imageData.data;
    const width = imageData.width;
    const height = imageData.height;
    for (let i = 0; i < 4; i++) {
      uint8ClampedArray[row * width * 4 + column * 4 + i] = pixel[i];
    }
  }

  const mirrorImageData = ctx!.createImageData(canvas.width, canvas.height);
  const imageData = ctx!.getImageData(0, 0, canvas.width, canvas.height);
  for (let h = 0; h < canvas.height; h++) {
    for (let w = 0; w < canvas.width; w++) {
      const pixel = getPixel(imageData, h, canvas.width - w - 1);
      setPixel(mirrorImageData, h, w, pixel);
    }
  }
  ctx!.putImageData(mirrorImageData, 0, 0);
  // ****** 镜像处理 ******
  const base64 = canvas.toDataURL("image/jpeg");
  userFaceImage.value = base64;
  //console.log(self.userFaceImage);
  faceLogin();
}
//切换镜头
const handleChangeFacingMode = () => {
  facingMode.value = facingMode.value === 'user' ? 'environment' : 'user';
  handlePhotographCloseClick();
  invokingCamera();
}
//获取token
const getToken = () => {
  doGetToken().then((token: string) => {
    ssoToken.value = token
  })
}
//人脸登录
const faceLogin = () => {
  uni.request({
    url: HUIBANG_BASE_URL + '/api/doInterface?code=doStrongFaceLogin',
    data: {
      token: ssoToken.value,
      check_code: code.value,
      imgBase64: userFaceImage.value.split(',')[1]
    },
    method: 'POST',
    header: {
      'Content-Type': 'application/json'
    },
    success: (res: any) => {
      if (res.data.state === 'ok') {
        uni.setStorageSync("u-code", code.value);
        loginFaceLogin({ token: res.data.token }).then((res) => {
          setToken(res.token)
          doLogin()
          handlePhotographCloseClick();
        })
      } else {
        handlePhotographClick();
      }
    },
    fail: (res) => {
      uni.showToast({ title: JSON.stringify(res), icon: 'none'})
    }
  });
}


const back = () => {
  uni.navigateBack({
    delta: 1
  })
}

const showKeyboard = ref(false);
const redirectUrl = ref('')


onLoad((options) => {
  console.log('login options: ', options)
  if (options.redirect) {
    redirectUrl.value = ensureDecodeURIComponent(options.redirect)
  }
  else {
    redirectUrl.value = tabbarList[0].pagePath
  }
  console.log('redirectUrl.value: ', redirectUrl.value)
})

function doLogin() {
  console.log(redirectUrl.value)
  let path = redirectUrl.value
  if (!path.startsWith('/')) {
    path = `/${path}`
  }
  const { path: _path, query } = parseUrlToObj(path)
  console.log('_path:', _path, 'query:', query, 'path:', path)
  console.log('isPageTabbar(_path):', isPageTabbar(_path))
  if (isPageTabbar(_path)) {
    // 经过我的测试 switchTab 不能带 query 参数, 不管是放到 url  还是放到 query ,
    // 最后跳转过去的时候都会丢失 query 信息
    uni.switchTab({
      url: path,
    })
  }
  else {
    console.log('redirectTo:', path)
    uni.redirectTo({
      url: path,
    })
  }
}

</script>
<template>
    <view class="content">
      <wd-navbar title="人脸识别" left-text="返回" placeholder fixed left-arrow right-text="按钮" @click-left="back">
        <template #right>
          <wd-icon  v-if="showFace" name="camera" size="22px" @click="handleChangeFacingMode"></wd-icon>
        </template>
      </wd-navbar>
        <view class="body">
            <view v-if="!showFace" class="code">
                <view class="des">
                    <h3>填写您的手机/身份证后四位</h3>
                    <p style="margin-top: 15px;color:#909399 ;">请在此处输入</p>
                </view>
                <view class="code-input">
                  <!-- 密码输入框 -->
                  <wd-password-input :length="4"  v-model="code" :mask="false" :focused="showKeyboard" @focus="showKeyboard = true" />
                  <!-- 数字键盘 -->
                  <wd-number-keyboard v-model="code" extra-key="X" v-model:visible="showKeyboard" :maxlength="4" @blur="showKeyboard = false" />
                </view>
                <view class="submit">
                    <view  @click="onCodeConfirm" >确定</view>
                </view>
            </view>
            <view v-else class="face">
                <view class="face-box">
                    <video id="video" autoplay :style="facingMode === 'user' ? videoStyle2 : videoStyle" object-fit="fill">
                    </video>
                </view>
                <view class="face-tip">
                    <p>请平视摄像头，并保持光线充足</p>
                </view>
                <!-- <view class="face-button">
                <u-button type="primary" text="开始识别" @click="init()"></u-button>
              </view> -->
            </view>
        </view>
    </view>
</template>

<style lang="scss" scoped>
.content {
    height: 100%;
}

.body {
    height: calc(100% - 85px);
    background-color: #ffffff;
    padding: 20px;

    .code {
        height: calc(100%);
        //display: flex;
        //flex-direction: column;
        //align-items: center;

        .des {
            width: 100%;
            margin-top: 20px;
        }

        .code-input {
            margin-top: 40px;
            margin-bottom: 80px;
        }

        .submit {
            width: 100%;
          div {
            line-height: 96rpx;
            border-radius: 20rpx;
            text-align: center;
            font-size: 32rpx;
            color: #ffffff;
            background-color: #409EFF;
          }
        }
    }

    .face {
        height: calc(100%);
        display: flex;
        flex-direction: column;
        align-items: center;

        .face-tip {
            color: #909399;
            margin-top: 20px;
        }

        .face-button {
            width: 100%;
            margin-top: 20px;
        }
    }

    video {
        transform: rotateY(180deg);
        -webkit-transform: rotateY(180deg);
        /* Safari 和 Chrome */
        -moz-transform: rotateY(180deg);
        border: 1px solid;
    }

    /* 移除:deep()选择器，直接使用类名 */
    .uni-video-bar {
        display: none;
    }

    .uni-video-cover {
        display: none;
    }
}
</style>
