<template>
  <div class="table-box">
    <ProTable ref="proTable" :columns="columns" row-key="id" :request-api="listDataApi" :init-param="initParam">
      <template #yuan="scope">
        <uploadImg :is-show-data="true" :disabled="true" :image-url="scope.row.url" />
        <!--        <el-image style="width: 100px" :src="'/api' + scope.row.url" @click="markImg(scope.row)" />-->
      </template>
      <!-- 表格 header 按钮 -->
      <template #tableHeader="scope">
        <el-button type="primary" v-auth="['demo:data:add']" :icon="CirclePlus" @click="openDialog(1, '数据新增')"> 新增 </el-button>
        <el-button type="primary" v-auth="['demo:data:import']" :icon="Upload" plain @click="batchAdd"> 导入数据集 </el-button>
        <el-button type="primary" v-auth="['demo:data:export']" :icon="Download" plain @click="downloadFile"> 导出 </el-button>
        <el-button
          type="danger"
          v-auth="['demo:data:remove']"
          :icon="Delete"
          plain
          :disabled="!scope.isSelected"
          @click="batchDelete(scope.selectedListIds)"
        >
          批量删除
        </el-button>
      </template>
      <!-- 表格操作 -->
      <template #operation="scope">
        <!-- <el-button type="primary" link :icon="EditPen" v-auth="['demo:data:edit']" @click="openDialog(2, '数据标注', scope.row)"> 标注 </el-button> -->
        <el-button type="primary" link :icon="EditPen" v-auth="['demo:data:edit']" @click="markImg(scope.row)"> 标注 </el-button>
        <el-button type="primary" link :icon="EditPen" v-auth="['demo:data:edit']" @click="openDialog(2, '数据编辑', scope.row)"> 编辑 </el-button>
        <el-button type="primary" link :icon="View" v-auth="['demo:data:query']" @click="openDialog(3, '数据查看', scope.row)"> 查看 </el-button>
        <el-button type="primary" link :icon="Delete" v-auth="['demo:data:remove']" @click="deleteData(scope.row)"> 删除 </el-button>
      </template>
    </ProTable>

    <FormDialog ref="formDialogRef" />
    <ImportPicDataset ref="dialogRef" />
    <ImgDetect
      ref="imgDetect"
      :img="cover"
      :area="area"
      :width="width"
      :height="height"
      @success="handleImgSuccess"
      :classes="classes"
      :json-data="jsonData"
    >
    </ImgDetect>
  </div>
</template>

<script setup lang="tsx" name="Data">
import { ref, reactive, toRefs, onMounted } from 'vue'
import { useHandleData } from '@/hooks/useHandleData'
import { useDownload } from '@/hooks/useDownload'
import { ElMessage, ElMessageBox } from 'element-plus'
import ProTable from '@/components/ProTable/index.vue'
import FormDialog from '@/components/FormDialog/index.vue'
import ImportPicDataset from '@/components/ImportPicDataset/index.vue'
import { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
import { Delete, EditPen, Download, Upload, View, CirclePlus } from '@element-plus/icons-vue'
// import { fabric } from 'fabric'
// import { useDrawArea } from '@/utils/fabric'
import { getDictsApi } from '@/api/modules/system/dictData'
import ImgDetect from '../components/img-detect.vue'
import uploadImg from '@/components/Upload/Img.vue'
import {
  listDataApi,
  delDataApi,
  addDataApi,
  updateDataApi,
  importTemplateApi,
  importDataDataApi,
  exportDataApi,
  getDataApi
} from '@/api/modules/demo/data'
import { listDataApi as listDictDataApi } from '@/api/modules/system/dictData'
import { uploadPure } from '@/api/modules/upload'
import http from '@/api'

onMounted(() => {
  state.cacheData.url = 'http://localhost:9090/profile/upload/2024/08/08/144745610/test.png'
  // handleImgSuccess({
  //   data: 'test change data',
  //   jsonData: 'jsonData12345 test change',
  //   url: 'testurl'
  // })
})

const imgDetect = ref()
const state = reactive({
  area: '' as string,
  width: 1920 as number,
  height: 1080 as number,
  cover: '',
  classes: [],
  //   [
  //   {
  //     name: '飞机',
  //     color: '#ea5413',
  //     label: 'plane'
  //   },
  //   {
  //     name: '汽车',
  //     color: '#ff00ff',
  //     label: 'car'
  //   }
  // ],
  jsonData: [],
  cacheData: {}
  // '{"version":"5.3.0","objects":[{"type":"image","version":"5.3.0","originX":"left","originY":"top","left":0,"top":0,"width":918,"height":789,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":0.68,"scaleY":0.68,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"cropX":0,"cropY":0,"src":"http://localhost:8848/api/profile/upload/2024/08/08/144745610/3-3.jpg","crossOrigin":null,"filters":[]},{"type":"rect","version":"5.3.0","originX":"left","originY":"top","left":181.38,"top":251.38,"width":244,"height":162,"fill":"rgba(255, 255, 255, 0)","stroke":"#E34F51","strokeWidth":5,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":-25,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"rx":0,"ry":0}]}'
})
const { area, width, height, cover, classes, jsonData } = toRefs(state)

// ProTable 实例
const proTable = ref<ProTableInstance>()
// const getImageUrl = name => {
//   return new URL(name, import.meta.url).href
// }

const initParam = reactive({ type: 1 })
// 删除数据管理信息
const deleteData = async (params: any) => {
  await useHandleData(delDataApi, params.id, `删除【${params.name}】数据`)
  proTable.value?.getTableList()
}

// 标注图片
const markImg = data => {
  console.log('data is', data)
  state.cacheData = data
  state.jsonData = []
  if (!data.url || data.url.length === 0) {
    ElMessage.warning('缺失图像,暂时不能进行区域添加！')
    return
  }

  listDictDataApi({
    pageNum: 1,
    pageSize: 10,
    dictType: 'class_definition'
  })
    .then(res => {
      // console.log(res)
      state.classes = []
      for (let i = 0; i < res.data.list.length; i++) {
        state.classes.push({
          name: res.data.list[i].dictLabel,
          color: res.data.list[i].cssClass,
          label: res.data.list[i].dictValue
        })
      }

      if (state.cacheData.labelurl && state.cacheData.labelurl.length > 0) {
        console.log('get label jsonData', state.cacheData.labelurl)
        http
          .get<any>(state.cacheData.labelurl)
          .then(res => {
            state.jsonData = []
            console.log(res)
            let arr = res.replace('\r', '').split('\n')
            console.log(arr)
            for (let i = 0; i < arr.length; i++) {
              let subArr = arr[i].split(' ')
              // console.log(subArr)
              let cssVal = '#000000'
              let label = '-1'
              for (let j = 0; j < state.classes.length; j++) {
                if (state.classes[j].label === subArr[0]) {
                  cssVal = state.classes[j].color
                  label = state.classes[j].label
                  break
                }
              }
              state.jsonData.push({
                subArr: subArr,
                pathString:
                  'M ' +
                  subArr[1] * 1920 +
                  ' ' +
                  subArr[2] * 1080 +
                  ' L ' +
                  subArr[3] * 1920 +
                  ' ' +
                  subArr[4] * 1080 +
                  ' L ' +
                  subArr[5] * 1920 +
                  ' ' +
                  subArr[6] * 1080 +
                  ' L ' +
                  subArr[7] * 1920 +
                  ' ' +
                  subArr[8] * 1080 +
                  ' z',
                // left: 0,
                // top: 0,
                fill: '',
                stroke: cssVal,
                strokeWidth: 5,
                label: label
              })
            }
            // console.log(state.jsonData)
            imgDetect.value.visible = true
          })
          .catch(err => {
            console.log(err)
          })
      } else {
        imgDetect.value.visible = true
      }
    })
    .catch(err => {
      console.log(err)
    })

  state.cover = '/api' + data.url

  // area 代表后端的传来的标注数据
  // console.log(state.cover)

  // const area = []
  // if (state.cover != '') {
  //   if (area.length != 0) {
  //     handleImgSuccess(area)
  //   }
  //
  //   console.log("true???")
  // } else {
  //   ElMessage.warning('缺失图像,暂时不能进行区域添加！')
  // }
}
// const getList = () => {
//   useDrawArea({
//     src: state.cover,
//     width: state.width,
//     height: state.height,
//     area: state.area
//   })
//     .then(url => {
//       state.cover = url as string
//     })
//     .catch(error => {
//       console.log(error)
//     })
// }
const handleImgSuccess = data => {
  // console.log(data)
  state.jsonData = data['jsonData']
  state.cover = data['url']

  state.cacheData.labelurl = data['data']

  state.cacheData.increment = 'NONE'

  let arr = state.cacheData.url.split('upload')
  // console.log(arr)
  let filenames = arr[arr.length - 1].split('.')
  filenames[filenames.length - 1] = 'txt'
  // console.log(filenames.join('.'))
  let filename = filenames.join('.')
  filename = filename.replace(/\\/g, '/')
  if (filename.startsWith('/')) {
    filename = filename.substring(1)
  }
  // console.log(filename)

  labelFile(data['data'], filename).then(res => {
    // console.log(res)
    if (res.code === 200) {
      state.cacheData.labelurl = res.data.url
      updateDataApi(state.cacheData)
        .then(res => {
          // console.log(res)
          if (res.data) {
            ElMessage.success('操作成功')
          }
        })
        .catch(err => {
          console.log(err)
        })
    }
  })

  // data.forEach(item => {
  //   if (item.startsWith('{')) {
  //     return
  //   }
  //   const area = item.split(';')
  //   // try=tly blx=tlx brx=trx bry=bly
  //   // mark: 当前用的应该是左上角定点位置和长宽，应该替换为存储点
  //   const tlx = Math.round(Number(area[0]) * 1920)
  //   const tly = Math.round(Number(area[1]) * 1080)
  //   const trx = tlx + Math.round(Number(area[2]) * 1920)
  //   const bly = tly + Math.round(Number(area[3]) * 1080)
  //   state.area += `${tlx};${tly};${trx};${tly};${trx};${bly};${tlx};${bly},`
  // })
  // // console.log('state.area', state.area)
  // state.area.slice(0, -1)
  // getList()
}

// 创建并提交标注txt文件
const labelFile = (data, filename) => {
  // 创建Blob对象
  const blob = new Blob([data], { type: 'text/plain' })

  // 创建表单数据并添加文件
  const formData = new FormData()

  formData.append('file', blob, filename)

  return uploadPure(formData)
}

const labeledTypeData = [
  {
    label: '是',
    value: true
  },
  {
    label: '否',
    value: false
  }
]

// 批量删除数据管理信息
const batchDelete = async (ids: string[]) => {
  await useHandleData(delDataApi, ids, '删除所选数据信息')
  proTable.value?.clearSelection()
  proTable.value?.getTableList()
}

// 导出数据管理列表
const downloadFile = async () => {
  ElMessageBox.confirm('确认导出数据管理数据?', '温馨提示', { type: 'warning' }).then(() =>
    useDownload(exportDataApi, '数据管理列表', proTable.value?.searchParam)
  )
}

// 批量添加数据管理
const dialogRef = ref<InstanceType<typeof ImportPicDataset> | null>(null)
const batchAdd = () => {
  const params = {
    title: '数据管理添加数据集',
    tempApi: importTemplateApi,
    importApi: importDataDataApi,
    getTableList: proTable.value?.getTableList
  }
  dialogRef.value?.acceptParams(params)
}

const formDialogRef = ref<InstanceType<typeof FormDialog> | null>(null)
// 打开弹框的功能
const openDialog = async (type: number, title: string, row?: any) => {
  let res = { data: {} }
  if (row?.id) {
    res = await getDataApi(row?.id || null)
  }
  // 重置表单
  setFormItems()
  const params = {
    title,
    width: 580,
    isEdit: type !== 3,
    itemsOptions: formItems,
    model: type == 1 ? {} : res.data,
    api: type == 1 ? addDataApi : updateDataApi,
    getTableList: proTable.value?.getTableList
  }
  formDialogRef.value?.openDialog(params)
}

// 表格配置项
const columns = reactive<ColumnProps<any>[]>([
  { type: 'selection', fixed: 'left', width: 70 },
  { prop: 'yuan', label: '原图', width: 200 },
  {
    prop: 'batchNum',
    label: '批次号',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'name',
    label: '名称',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'objectType',
    label: '目标类型',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'objectSubtype',
    label: '目标子类型',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'scene',
    label: '场景',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'dataSource',
    label: '数据源',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'gatherSpot',
    label: '采集地点',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'gatherTime',
    label: '采集时间',
    search: {
      el: 'date-picker',
      props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
    },
    width: 120
  },
  {
    prop: 'dataType',
    label: '数据类型',
    enum: () => getDictsApi('data_type'),
    search: {
      el: 'tree-select'
    },
    fieldNames: { label: 'dictLabel', value: 'dictValue' },
    width: 120
  },
  // {
  //   prop: 'fileType',
  //   label: '文件类型',
  //   search: {
  //     el: 'input'
  //   },
  //   width: 120
  // },
  // {
  //   prop: 'increment',
  //   label: '扩增方式',
  //   search: {
  //     el: 'input'
  //   },
  //   width: 120
  // },
  {
    prop: 'labeled',
    label: '是否标注',
    search: {
      el: 'input'
    },
    width: 120
  },
  { prop: 'operation', label: '操作', width: 230, fixed: 'right' }
])
// 表单配置项
let formItems: ProForm.ItemsOptions[] = []
const setFormItems = () => {
  formItems = [
    {
      label: '原图',
      prop: 'url',
      compOptions: {
        elTagName: 'img-upload',
        placeholder: '请选择上传原图'
      }
    },
    {
      label: '批次号',
      prop: 'batchNum',
      rules: [{ required: true, message: '批次号不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入批次号'
      }
    },
    {
      label: '名称',
      prop: 'name',
      rules: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入名称'
      }
    },
    {
      label: '目标类型',
      prop: 'objectType',
      rules: [{ required: true, message: '目标类型不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入目标类型'
      }
    },
    {
      label: '目标子类型',
      prop: 'objectSubtype',
      rules: [{ required: true, message: '目标子类型不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入目标子类型'
      }
    },

    {
      label: '场景',
      prop: 'scene',
      rules: [{ required: true, message: '场景不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入场景'
      }
    },
    {
      label: '数据源',
      prop: 'dataSource',
      rules: [{ required: true, message: '数据源不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入数据源'
      }
    },
    {
      label: '采集地点',
      prop: 'gatherSpot',
      rules: [{ required: true, message: '采集地点不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入采集地点'
      }
    },
    {
      label: '采集时间',
      prop: 'gatherTime',
      rules: [{ required: true, message: '采集时间不能为空', trigger: 'change' }],
      compOptions: {
        elTagName: 'date-picker',
        type: 'datetime',
        valueFormat: 'YYYY-MM-DD HH:mm:ss',
        placeholder: '请选择采集时间'
      }
    },
    {
      label: '数据类型',
      prop: 'dataType',
      rules: [{ required: true, message: '数据类型不能为空', trigger: 'change' }],
      compOptions: {
        elTagName: 'select',
        labelKey: 'dictLabel',
        valueKey: 'dictValue',
        enum: () => getDictsApi('data_type'),
        placeholder: '请选择数据类型'
      }
    },
    {
      label: '是否标注',
      prop: 'labeled',
      rules: [{ required: true, message: '请选择是否标注' }],
      compOptions: {
        elTagName: 'radio-group',
        enum: labeledTypeData
      }
    }
  ]
}
</script>
