<template>
  <el-dialog v-model="algorithmManage.visible.value" width="70%" append-to-body>
    <template v-slot:header>
      <div
        class="cleartitle"
        style="display: flex; justify-content: flex-start; align-items: center"
      >
        <img src="@/assets/images/logo_video.png" width="25px" alt="" />
        <span>{{ title }}</span>
      </div>
    </template>
    <el-row class="row-box">
      <el-col :span="12">
        <el-row :gutter="10" class="mb8" style="justify-content: space-between">
          <el-col :span="1.5">
            <div
              class="form-title"
              style="
                display: flex;
                justify-content: flex-start;
                align-items: center;
              "
            >
              <span>基础信息</span>
            </div>
          </el-col>
          <el-col :span="6.8" style="display: flex"> </el-col>
        </el-row>
        <div class="left-form">
          <el-form
            ref="algLevelRef"
            :model="unref(algorithmManage.form)"
            :rules="rules"
            label-position="left"
            label-width="110px"
            class="demo-form-inline"
          >
            <el-form-item
              label="区域管理"
              prop="regionalId"
              v-if="unref(device.list).length"
            >
              <el-cascader
                style="width: 100%"
                v-model="unref(algorithmManage.form).regionalId"
                :options="areaManger.list.value"
                :props="{
                  children: 'children',
                  value: 'id',
                  checkStrictly: true,
                }"
                placeholder="请选择上级区域"
                clearable
              />
            </el-form-item>
            <el-form-item label="点位名称" prop="locationName">
              <el-input v-model="unref(algorithmManage.form).locationName" />
            </el-form-item>
            <el-form-item
              label="摄像头名称"
              prop="deviceId"
              v-if="unref(device.list).length"
            >
              <el-select
                v-model="unref(algorithmManage.form).deviceId"
                placeholder="请选择摄像头"
                @change="handleDeviceChange"
              >
                <el-option
                  v-for="item in unref(device.list)"
                  :key="item.id"
                  :label="item.deviceName"
                  :value="item.id"
                ></el-option>
              </el-select>
            </el-form-item>
            <!-- RTSP地址 -->
            <el-form-item label="RTSP地址" prop="videoUrl">
              <el-input
                v-model="unref(algorithmManage.form).videoUrl"
                readonly
              />
            </el-form-item>
            <el-form-item label="是否重新拉流" prop="restartFlow">
              <el-switch
                v-model="unref(algorithmManage.form).restartFlow"
                inline-prompt
                active-text="是"
                inactive-text="否"
                active-value="true"
              />
            </el-form-item>
            <el-form-item label="重新拉流时间" prop="reStreamingTime">
              <el-input v-model="unref(algorithmManage.form).reStreamingTime"
                ><template #suffix>/秒</template></el-input
              >
            </el-form-item>
            <el-form-item label="拉流间隔时间" prop="inferenceInterval">
              <el-input v-model="unref(algorithmManage.form).inferenceInterval"
                ><template #suffix>/秒</template></el-input
              >
            </el-form-item>
          </el-form>
        </div>
        <div class="left-list">
          <div class="form-title">算法列表</div>
          <el-table
            :data="
              unref(algorithmManage.form).aiRegionalLocationList ||
              aiAlgorithm.list.value
            "
            height="200px"
          >
            <el-table-column
              label="算法名称"
              align="center"
              prop="algorithmName"
            />
            <el-table-column label="选择" align="center" prop="alarmColor">
              <template #default="scope">
                <span>
                  <el-switch
                    v-model="scope.row.status"
                    active-value="0"
                    inactive-value="1"
                  ></el-switch>
                </span>
              </template>
            </el-table-column>
            <el-table-column
              label="识别区域"
              width="180"
              align="center"
              class-name="small-padding fixed-width"
            >
              <template #default="scope">
                <el-button
                  link
                  type="primary"
                  @click="beginDraw(scope.row)"
                  v-hasPermi="['system:post:edit']"
                  >绘制</el-button
                >
                <el-button
                  link
                  type="primary"
                  @click="aiConfig(scope.$index, scope.row)"
                  v-hasPermi="['system:post:remove']"
                  >配置</el-button
                >
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-col>
      <el-col :span="11" :offset="1" class="right-draw" id="video-box">
        <div>
          <el-button
            @click="getPhoto"
            v-if="!algorithmManage.form.value.liveMap"
            >拍照取图</el-button
          >
          <el-button @click="getNewPhoto" v-else>重新取图</el-button>
          <el-button type="primary" @click="clearDraw">重绘标记</el-button>
          <el-button type="primary" @click="++drawIndex">重绘下一个</el-button>
        </div>
        <div class="right-draw-content">
          <template v-if="algorithmManage.form.value.liveMap">
            <template v-if="drawId">
              <svg @click="pointDraw" class="drawSvg">
                <text
                  x="0"
                  y="0"
                  font-family="Arial"
                  font-size="20"
                  fill="blue"
                  text-anchor="middle"
                >
                  多边形
                </text>
                <polygon
                  :fill="item.fill"
                  stroke="blue"
                  stroke-width="1"
                  v-for="item in graph[drawId]"
                  :points="item.point"
                  :key="item.key"
                />
              </svg>
            </template>
            <template v-else>
              <svg
                @click="pointDraw"
                v-for="(gItem, key) in graph"
                :key="gItem.id"
                class="drawSvg"
              >
                <g :key="item.id" v-for="item in gItem">
                  <text
                    v-if="item.start"
                    :x="item.start[0]"
                    :y="item.start[1]"
                    font-family="Arial"
                    font-size="12"
                    fill="blue"
                    text-anchor="middle"
                  >
                    {{ item.title }}
                  </text>
                  <polygon
                    :fill="item.fill"
                    stroke="blue"
                    stroke-width="1"
                    :points="item.point"
                    :key="item.key"
                  />
                </g>
              </svg>
            </template>
            <img :src="ImgUrl" class="drawImg" alt="" />
          </template>
          <template v-else>
            <canvas id="video-canvas" class="drawImg"></canvas>
            <canvas id="canvas" style="display: none"></canvas>
          </template>
        </div>
        <div class="right">
          <el-button type="primary" @click="submit">确认</el-button>
          <el-button type="primary" plain @click="algorithmManage.toClose"
            >取消</el-button
          >
        </div>
      </el-col>
    </el-row>
  </el-dialog>
  <el-dialog
    :title="unref(aiAlgorithm.form).algorithmName"
    v-model="aiAlgorithm.visible.value"
    width="50%"
  >
    <el-form
      ref="algorithmManage.formRef"
      :model="aiAlgorithm.form"
      label-width="160px"
    >
      <!-- <el-form-item label="算法名称" prop="algorithmName">
        <el-input v-model="unref(aiAlgorithm.form).algorithmName" readonly />
      </el-form-item> -->
      <el-form-item label="告警间隔" prop="alarmInterval">
        <el-input
          placeholder="单位/秒"
          v-model="unref(aiAlgorithm.form).alarmInterval"
        />
      </el-form-item>
      <el-form-item label="行为持续多长时间报警" prop="continueWarnTime">
        <el-input
          placeholder="单位/秒"
          v-model="unref(aiAlgorithm.form).continueWarnTime"
        />
      </el-form-item>
      <el-form-item label="识别间隔（跳帧）" prop="identifyIntervals">
        <el-input v-model="unref(aiAlgorithm.form).identifyIntervals" />
      </el-form-item>
      <el-form-item label="标签阈值" prop="labelThreshold">
        <el-input v-model="unref(aiAlgorithm.form).labelThreshold" />
      </el-form-item>
      <el-table :data="unref(aiAlgorithmLabel.list)" class="labels-table">
        <el-table-column label="识别标签" align="center" prop="remark" />
        <el-table-column label="标签阈值" align="center" prop="labelThreshold">
          <template #default="scope">
            <span v-if="scope.row.isEdit">
              <template v-if="unref(algorithmManage.form).id">
                <el-input
                  v-model="unref(aiAlgorithmLabel.form).labelThreshold"
                  placeholder="请输入标签阈值"
                />
              </template>
              <template v-else>
                <el-input
                  v-model="scope.row.labelThreshold"
                  placeholder="请输入标签阈值"
                />
              </template>
            </span>
            <span v-else>{{ scope.row.labelThreshold }}</span>
          </template>
        </el-table-column>
        <el-table-column label="状态" align="center" prop="postSort">
          <template #default="scope">
            <el-switch
              v-model="scope.row.status"
              :active-value="1"
              :inactive-value="0"
              @change="(e, e1) => changeStatus(scope.row, e, e1)"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="操作"
          width="180"
          align="center"
          class-name="small-padding fixed-width"
        >
          <template #default="scope">
            <el-button
              link
              type="primary"
              @click="aiAlgorithmLabelEdit(scope.row, scope.$index)"
              v-hasPermi="['system:post:edit']"
              >{{ scope.row.isEdit ? "确定" : "修改阈值" }}</el-button
            >
            <!-- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:post:remove']">删除</el-button> -->
          </template>
        </el-table-column>
      </el-table>

      <div class="right">
        <el-button type="primary" @click="sureConfig">确认</el-button>
        <el-button type="primary" plain @click="aiAlgorithm.toClose"
          >取消</el-button
        >
      </div>
    </el-form>
  </el-dialog>
</template>

<script setup>
import { computed, onMounted, ref, unref, watch } from "vue";
import { useIndex } from "../hooks";
import { colors, base64ToFile } from "../utils";
import request from "@/utils/request";
import { ElMessage, ElMessageBox } from "element-plus";
import "@/utils/jsmpeg.min";
const { algorithmManage, areaManger } = defineProps({
  algorithmManage: Object,
  areaManger: Object,
});
const device = useIndex({
  list: "/yunshou/aiDevice/list",
});
const aiAlgorithm = useIndex(
  {
    list: "/yunshou/userAlgorithm/list",
    detail: "/yunshou/aiAlgorithmConfig/",
  },
  () => {},
  null,
  false
);

const rules = {
  // 区域管理
  regionalId: [{ required: true, message: "请选择上级区域" }],
  locationName: [
    { required: true, message: "请输入点位名称", trigger: "blur" },
  ],
  // 摄像头名称
  deviceId: [{ required: true, message: "请选择摄像头", trigger: "change" }],
  // RTSP地址
  videoUrl: [{ required: true, message: "请输入RTSP地址", trigger: "blur" }],
  // // 是否重新拉流
  // restartFlow: [
  //   { required: true, message: "请选择是否重新拉流", trigger: "change" },
  // ],
  // 是否重新拉流
  videoUrl: [{ required: true, message: "请输入视频流" }],
  // 重新拉流时间
  reStreamingTime: [
    { required: true, message: "请输入重新拉流时间", trigger: "blur" },
  ],
  // 拉流间隔时间
  inferenceInterval: [
    { required: true, message: "请输入拉流间隔时间", trigger: "blur" },
  ],
};
const algLevelRef = ref(null);

const isEdit = false;
let aiAlgorithmLabel = useIndex(
  //新增调用算法label
  {
    list: "/yunshou/aiAlgorithmLabel/list",
    detail: "/yunshou/aiAlgorithmLabel/",
    edit: "/yunshou/aiAlgorithmLabel/",
  },
  () => {},
  null,
  false
);
watch(
  () => algorithmManage.form.value,
  (e) => {
    aiAlgorithmLabel = useIndex(
      //编辑调用当前标签的label
      {
        list: "/yunshou/aiRegionalLocationAlgorithmLabel/list",
        detail: "/yunshou/aiRegionalLocationAlgorithmLabel/",
        edit: "/yunshou/aiRegionalLocationAlgorithmLabel",
      },
      () => {},
      null,
      false
    );
    // console.log(algorithmManage.form.value.aiRegionalLocationList)
    algorithmManage.form.value.aiRegionalLocationList.forEach((val) => {
      graph[val.id] = val.drawingArea && JSON.parse(val.drawingArea);
    });
  }
);
function handleDeviceChange(e, index) {
  const d = device.list.value.find((x) => x.id == e);
  algorithmManage.form.value.videoUrl = d.videoUrl;
  getVideos();
}
onMounted(() => {
  getVideos();
  aiAlgorithm.search.value.algorithmStatus = 0;
  aiAlgorithm.getList();
});

const ImgUrl = computed(() => {
  const url = algorithmManage.form.value.liveMap;
  if (url) {
    // 是否为base64
    if (url.indexOf("data:image/png;base64") != -1) {
      return url;
    } else {
      return import.meta.env.VITE_IMG_BASE_PATH + url;
    }
  }
  return "";
});

function submit() {
  algLevelRef.value.validate(async (valid) => {
    if (valid) {
      let algorithms = [];
      algorithmManage.form.value.runningState = "0";
      if (algorithmManage.form.value.liveMap) {
        await toUpload(); //上传图片
      }
      if (algorithmManage.form.value.id) {
        unref(algorithmManage.form).aiRegionalLocationList.forEach((val) => {
          val.drawingArea = graph[val.id]
            ? JSON.stringify(graph[val.id])
            : val.drawingArea
            ? val.drawingArea
            : "";
        });
        algorithms = unref(algorithmManage.form).aiRegionalLocationList;
      } else {
        unref(aiAlgorithm.list).forEach((val) => {
          algorithms.push({
            algorithmId: val.id,
            drawingArea: graph[val.id]
              ? JSON.stringify(graph[val.id])
              : val.drawingArea
              ? val.drawingArea
              : "",
            status: val.status,
            ...val.params,
          });
        });
      }
      algorithmManage.form.value.algorithms = algorithms;
      if(Array.isArray(algorithmManage.form.value.regionalId))algorithmManage.form.value.regionalId=algorithmManage.form.value.regionalId.pop();
      algorithmManage.toSubmit();
    }
  });
}
function aiAlgorithmLabelEdit(scope) {
  if (algorithmManage.form.value.id) {
    //编辑调用当前标签的label
    if (!scope.isEdit) {
      aiAlgorithmLabel.toEdit(scope);
    }
    if (scope.isEdit) {
      aiAlgorithmLabel.toSubmit();
    }
  } else {
  }
  scope.isEdit = !scope.isEdit;
}
function toUpload() {
  if (
    algorithmManage.form.value.liveMap.indexOf("data:image/png;base64") == -1
  ) {
    return Promise.resolve();
  }
  const file = base64ToFile(algorithmManage.form.value.liveMap);
  const formData = new FormData();
  formData.append("file", file);
  return request({
    url: "/common/upload",
    method: "post",
    data: formData,
    headers: {
      "Content-Type": "multipart/form-data",
    },
  }).then((res) => {
    algorithmManage.form.value.liveMap = res.fileName;
  });
}
const configIndex = ref(0);
function aiConfig(index, e) {
  configIndex.value = index;
  const current = unref(aiAlgorithm.list)[index];
  aiAlgorithm.form.value = algorithmManage.form.value.id
    ? e
    : {
        algorithmName: current.algorithmName,
      };
  aiAlgorithm.visible.value = true;
  if (algorithmManage.form.value.id) {
    aiAlgorithmLabel.search.value.regionalLocationAlgorithmId = e.id;
  } else {
    aiAlgorithmLabel.search.value.algorithmId = e.id;
  }
  aiAlgorithmLabel.search.value.showStatus = 0;
  aiAlgorithmLabel.getList().then(() => {
    if (current.params) {
      aiAlgorithm.form.value = {
        ...current.params,
        ...unref(aiAlgorithm.form),
      };
      if (current.params.labels) {
        //编辑标签
        current.params.labels.forEach((x) => {
          const index = unref(aiAlgorithmLabel.list).findIndex(
            (y) => y.id == x.id
          );
          if (index > -1) {
            unref(aiAlgorithmLabel.list)[index].labelThreshold =
              x.labelThreshold;
            unref(aiAlgorithmLabel.list)[index].isEdit = false;
            unref(aiAlgorithmLabel.list)[index].status = x.status;
          }
        });
      }
    }
  });
}

function changeStatus(scope, e, e1) {
  scope.isEdit = false; //通过isEdit来判断是否发生变化
  aiAlgorithmLabel.editSubmit(scope);
}
// 确认配置
function sureConfig() {
  if (algorithmManage.form.value.id) {
    const current = unref(algorithmManage.form).aiRegionalLocationList[
      configIndex.value
    ];
    unref(algorithmManage.form).aiRegionalLocationList[configIndex.value] = {
      ...current,
      ...unref(aiAlgorithm.form),
    };
  } else {
    const labels = unref(aiAlgorithmLabel.list).filter((x) => "isEdit" in x);
    unref(aiAlgorithm.list)[configIndex.value].params = unref(aiAlgorithm.form);
    unref(aiAlgorithm.list)[configIndex.value].params.labels = labels.map((x) =>
      unref(x)
    );
  }
  aiAlgorithm.toClose();
}
let drawId = ref();
let drawIndex = ref(0);
const graph = reactive({});

const isPhoto = ref(false);
function getPhoto() {
  isPhoto.value = true;
}
let player;
function getVideos() {
  let canvas = document.getElementById("video-canvas");
  let url = algorithmManage.form.value.videoUrl;
  if (player) {
    player.destroy();
    player = null;
  }
  player = new JSMpeg.Player("ws://192.168.4.232:9999/rtsp?url=" + btoa(url), {
    canvas: canvas,
    disableGl: true,
    onVideoDecode: function (decoder, time) {
      // 视频帧解码后立即截图
      if (isPhoto.value) {
        var url = canvas.toDataURL("image/png");
        algorithmManage.form.value.liveMap = url;
        isPhoto.value = false;
      }
      // 可以在这里保存图片或者进行其他操作
    },
  });
}

/* 重新取图 */
function getNewPhoto() {
  unref(algorithmManage.form).liveMap = "";
  for (let key in graph) {
    graph[key] = [];
  }
  if (unref(algorithmManage.form).id) {
    unref(algorithmManage.form).aiRegionalLocationList.forEach((x) => {
      x.drawingArea = [];
    });
  }
  setTimeout(() => {
    getVideos();
  });
}
const draw = ref();
function beginDraw(e) {
  if (!algorithmManage.form.value.liveMap) {
    // 添加弹窗
    ElMessage({
      message: "请先拍照取图",
      type: "error",
    });
    return;
  }
  draw.value = e;
  drawId.value = e.id;
  if (typeof e.drawingArea == "string" && e.drawingArea) {
    graph[e.id] = JSON.parse(e.drawingArea);
  }
  drawIndex.value = graph[drawId.value] ? graph[drawId.value].length : 0;
}
function clearDraw() {
  if (!drawId.value) {
    ElMessageBox.confirm("是否清空全部重绘？").then((res) => {
      for (let key in graph) {
        graph[key] = [];
      }
      if (unref(algorithmManage.form).id) {
        unref(algorithmManage.form).aiRegionalLocationList.forEach((x) => {
          x.drawingArea = [];
        });
      }
      ElMessage({
        message: "清空成功",
        type: "success",
      });
    });
  } else {
    ElMessageBox.confirm("是否清空当前重绘？").then((res) => {
      graph[drawId.value] = [];
      drawIndex.value = 0;
      ElMessage({
        message: "清空成功",
        type: "success",
      });
    });
  }
}
function pointDraw(e) {
  if (!graph[drawId.value]) {
    graph[drawId.value] = [];
  }
  if (!graph[drawId.value][drawIndex.value]) {
    graph[drawId.value][drawIndex.value] = {
      fill: colors(),
      point: "",
      title: draw.value.algorithmName,
      start: [e.offsetX, e.offsetY],
    };
  }
  graph[drawId.value][drawIndex.value].point += `${e.offsetX},${e.offsetY} `;
}
</script>

<style scoped lang="scss">
.form-title {
  display: flex;
  align-items: center; /*for vertical align*/
  font-size: 16px;
  font-weight: 600;
  border-radius: 5px;
  padding: 0;
}
.left-list {
  flex: 1;
  overflow: auto;
}
.form-title::before {
  content: "";
  display: inline-block;
  width: 10px; /* 矩形的宽度 */
  height: 30px; /* 矩形的高度 */
  background-color: #1890ff; /* 矩形的背景颜色 */
  margin-right: 10px;
  border-radius: 8px;
}
.drawImg {
  width: 100%;
  height: 100%;
  object-fit: fill;
}
.right {
  text-align: right;
}
.right-draw {
  display: grid;
  grid-template-rows: 30px 1fr 30px;
  gap: 20px;
  .right-draw-content {
    position: relative;
    height: 500px;
    svg {
      position: absolute;
      left: 0;
      top: 0;
      height: 100%;
      width: 100%;
    }
  }
}
.row-box {
  height: 620px;
}
.labels-table {
  height: 200px;
  margin-bottom: 20px;
}
</style>