<script lang="ts" setup>
import { computed, h, nextTick, onMounted, reactive, ref, unref } from 'vue'
import { NDataTable, useDialog, useMessage } from 'naive-ui'
import type { DataTableColumns, DataTableRowKey, PaginationProps } from 'naive-ui'
import { Action, CustomTabelModal, ImportExcelModal, RepeatModal, RepeatTaskTableModal } from '../comp'
import ConfrimModal from '@/views/task/modal/ConfrimModal.vue'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { getViewportOffset } from '@/utils/domUtils'
import type { RowData } from '@/config/final'
import { findKey, headRules } from '@/config/final'
import { getFinalList } from '@/api/final'
import { isBoolean } from '@/utils/is'
import { useUser } from '@/store/modules/user'
import type { ApprovalParam } from '/#/api'
import { audit } from '@/api/task/task'
import SvgIcon from '@/components/Icon/SvgIcon.vue'

const columns: DataTableColumns<RowData> = [
  {
    type: 'selection',
    fixed: 'left',
    width: 50,
  },
  {
    title: '任务Id',
    key: 'id',
    fixed: 'left',
    width: 100,
  },
  {
    title: '任务名称',
    key: 'fromtaskname',
    fixed: 'left',
    width: 150,
  },
  {
    title: '审批节点',
    key: 'approvalnode',
    width: 100,
  },
  {
    title: '审批状态',
    key: 'states',
    width: 100,
    sorter: 'default',
    renderSorterIcon: ({ order }) => {
      if (order === false)
        return h(SvgIcon, { name: 'sort-2' })
      if (order === 'ascend')
        return h(SvgIcon, { name: 'sort-1' })
      if (order === 'descend')
        return h(SvgIcon, { name: 'sort-3' })
    },
  },
  {
    title: '图片相似度',
    key: 'similarity',
    width: 150,
    sorter: 'default',
    renderSorterIcon: ({ order }) => {
      if (order === false)
        return h(SvgIcon, { name: 'sort-2' })
      if (order === 'ascend')
        return h(SvgIcon, { name: 'sort-1' })
      if (order === 'descend')
        return h(SvgIcon, { name: 'sort-3' })
    },
  },
  {
    title: '提报时间',
    key: 'fromuptime',
    width: 200,
    sorter: 'default',
    renderSorterIcon: ({ order }) => {
      if (order === false)
        return h(SvgIcon, { name: 'sort-2' })
      if (order === 'ascend')
        return h(SvgIcon, { name: 'sort-1' })
      if (order === 'descend')
        return h(SvgIcon, { name: 'sort-3' })
    },
  },
  {
    title: '更新时间',
    key: 'updatetime',
    width: 200,
  },
  {
    title: '操作',
    key: 'actions',
    width: 200,
    fixed: 'right',
    render(row) {
      return h(
        Action,
        {
          id: row.id,
          status: row.states,
          trigger: actionHandler,
        },
      )
    },
  },
]

const deviceHeight = ref(600)

onMounted(() => {
  nextTick(() => {
    computeListHeight()
  })
})

const columnsRef = ref(columns)
const tableRef = ref<InstanceType<typeof NDataTable>>()
const rowKey = (row: RowData) => row.id
const loading = ref(true)
const pagination = reactive({
  page: 1,
  pageCount: 1,
  pageSize: 10,
})
const tableData = ref<Array<RowData>>([])
const selectionIds = ref<DataTableRowKey[]>([])
const userStore = useUser()
const dialog = useDialog()
const message = useMessage()

async function query(page: number, pageSize: number) {
  const result = await getFinalList({ sortorder: 'asc', pageSize, currPage: page, sortname: '' })
  const { data, pageCount } = result
  tableData.value = data
  pagination.page = page
  pagination.pageCount = pageCount
  loading.value = false
}

async function handlePageChange(currentPage) {
  if (loading.value)
    return

  const { pageSize } = pagination
  await query(currentPage, pageSize)
}

function handleCheck(rowKeys: DataTableRowKey[]) {
  selectionIds.value = rowKeys
}

async function computeListHeight() {
  const table = unref(tableRef)
  if (!table)
    return
  const tableEl: any = table?.$el
  const headEl = tableEl.querySelector('.n-data-table-thead ')
  const { bottomIncludeBody } = getViewportOffset(headEl)
  const headerH = 64
  let paginationH = 2
  const marginH = 60
  if (!isBoolean(unref(pagination))) {
    const paginationEl = tableEl.querySelector('.n-data-table__pagination') as HTMLElement
    if (paginationEl) {
      const offsetHeight = paginationEl.offsetHeight
      paginationH += offsetHeight || 0
    }
    else {
      paginationH += 28
    }
  }
  let height
    = bottomIncludeBody - (headerH + paginationH + marginH)
  const maxHeight = 800
  height = maxHeight && maxHeight < height ? maxHeight : height
  deviceHeight.value = height
}

useWindowSizeFn(computeListHeight)

const maxHeight = computed(() => {
  return tableData.value.length ? `${unref(deviceHeight)}px` : 'auto'
})

query(pagination.page, pagination.pageSize)

const customTabelRef = ref(null)
const importExcelRef = ref(null)
const rejectModalRef = ref(null)
const repeatModalRef = ref(null)
const repeatTaskTableModalRef = ref(null)

function showModal(modalRef: any) {
  const modal = unref(modalRef)! as any
  modal.showModal()
}

const popover = ref<ComponentRef | null>(null)

function importHandler() {
  (popover.value as any).setShow(false)
  showModal(importExcelRef)
}

function exportHandler() {
  loading.value = true
  import('@/utils/exportExcel').then((excel) => {
    const tHeader = ['任务Id', '任务名称', '审批节点', '审批状态', '图片相似度', '提报时间', '更新时间']
    const filterVal = ['id', 'name', 'approvalnode', 'approvalstatus', 'similarity', 'uptime', 'updatetime']
    const list = tableData.value
    const data = formatJson(filterVal, list)
    excel.export_json_to_excel({
      header: tHeader,
      data,
      filename: 'data',
      autoWidth: true,
      bookType: 'xlsx',
    })
    loading.value = false
  })
}

function formatJson(filterVal, jsonDataList) {
  return jsonDataList.map(v => filterVal.map((j) => {
    return v[j]
  }))
}

function sucessHandler(excelData) {
  const data = excelData.content.map((item) => {
    const obj = {}
    Object.keys(item).forEach((key) => {
      const k = findKey(columns, key)
      obj[k] = item[key]
    })
    return obj
  })

  tableData.value = data
}

function commitHandler(columns) {
  columnsRef.value = columns
}

function actionHandler(action: any) {
  const { key } = action
  switch (key) {
    case 'view':
      break
    case 'reset':
      resetHandler()
      break
    case 'approval':
      approvalHandler()
      break
    case 'reject':
      rejectHandler()
      break
    default:
      break
  }
}

// states:1未提交，2待审批，3通过，4不通过
function validate(items: any[]) {
  if (items.length === 0)
    return '至少选中一个任务'

  const useInfo = userStore.getUserInfo
  const username = useInfo.loginname

  for (const item of items) {
    const { iztrueorfalse, states, assignee } = item
    if (iztrueorfalse === null)
      return '未判别真假'

    else if (states !== 2)
      return '审批状态不合法'

    else if (assignee !== username)
      return '审批人不一致'
  }

  return null
}

function resetHandler() {
  dialog.info({
    title: '确认提示',
    content: '确认重置当前选中的任务的审批吗?',
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick: async () => {
      // TODO：需要支持重置
      // const result = await resetApproval()
    },
    onNegativeClick: () => { },
  })
}

function getSelectItems() {
  return tableData.value.filter(item => selectionIds.value.includes(item.id))
}

function approvalHandler() {
  const items = getSelectItems()
  const msg = validate(items)

  if (msg !== null) {
    message.error(msg)
    return
  }

  dialog.info({
    title: '确认提示',
    content: '确认给该任务审批为【通过】吗?',
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick: () => {
      approval(items)
    },
    onNegativeClick: () => { },
  })
}

function approval(items) {
  const formIds: string[] = items.map(item => item.id)
  const taskIds: string[] = items.map(item => item.taskId)
  const tasknames: string[] = items.map(item => item.taskname)

  const param: ApprovalParam = {
    formid: formIds,
    taskId: taskIds,
    approvd: true,
    taskComment: 'approval',
    taskname: tasknames,
  }

  doAudit(param)
}

function rejectHandler() {
  const items = getSelectItems()
  const msg = validate(items)

  if (msg !== null) {
    message.error(msg)
    return
  }

  const modal = unref(rejectModalRef)! as any
  modal.showModal()
}

function reject(idOrDesc: string, backId: string, isOther: boolean) {
  const items = getSelectItems()
  const formIds: string[] = items.map(item => item.id)
  const taskIds: string[] = items.map(item => item.fromtaskid)
  const tasknames: string[] = items.map(item => item.fromtaskname)

  const param: ApprovalParam = {
    formid: formIds,
    taskId: taskIds,
    approvd: false,
    taskComment: idOrDesc,
    taskname: isOther ? tasknames : ['其他'],
  }

  doAudit(param)
}

function doAudit(param: any) {
  audit(param).then((res) => {
    const { code } = res
    if (code === 'OK')
      reload()
    else message.error(res.message)
  })
}

function reload() {
  const { page, pageSize } = unref(tableRef.value?.pagination) as PaginationProps
  query(page!, pageSize!)
}
</script>

<template>
  <div class="wrapper">
    <div class="wrapper-header">
      <div class="wrapper-header-left">
        <span class="wrapper-header-font">任务管理列表</span>
        <SvgIcon size="32" name="magnifying" />
      </div>
      <div>
        <n-button class="xjcc" text @click="showModal(repeatModalRef)">
          小结查重
        </n-button>
        <div class="btn">
          <SvgIcon style="margin-right: 6px;" size="14" name="tf" />
          批量审批
        </div>
        <n-popover
          ref="popover" :style="{ padding: '0px' }" style="width: 148px" :show-arrow="false"
          placement="bottom-start" trigger="click"
        >
          <template #trigger>
            <SvgIcon style="cursor: pointer;" size="20" name="more-ver" />
          </template>
          <ul class="wrapper-header-action">
            <li @click="importHandler">
              <SvgIcon size="20" name="download" /><span style="margin-left: 5px;">批量导入数据</span>
            </li>
            <li @click="exportHandler">
              <SvgIcon size="20" name="download" /><span style="margin-left: 5px;">导出待审数据</span>
            </li>
            <li>
              <SvgIcon size="20" name="download" /><span style="margin-left: 5px;">导出全部数据</span>
            </li>
          </ul>
        </n-popover>
      </div>
    </div>
    <!-- <div class="wrapper-statistic">
      <div v-for="i in 7" :key="i" class="item">
        <div class="icon" />
        <div class="content">
          <span class="num">6399</span>
          <span class="label">任务总数</span>
        </div>
        <div v-if="i === 7" style="display: flex;align-items: center;">
          <div class="divider" />
          <SvgIcon size="18" name="setting" />
        </div>
      </div>
    </div> -->
    <div class="wrapper-settings">
      <SvgIcon style="cursor: pointer;" size="18" name="setting" @click="showModal(customTabelRef)" />
    </div>
    <div class="wrapper-content">
      <NDataTable
        ref="tableRef" remote :columns="columnsRef" :scroll-x="1250" :max-height="maxHeight" :data="tableData"
        :loading="loading" :pagination="pagination" :row-key="rowKey" @update:page="handlePageChange"
        @update:checked-row-keys="handleCheck"
      />
    </div>

    <CustomTabelModal ref="customTabelRef" @commit="commitHandler" />
    <ImportExcelModal ref="importExcelRef" :on-success="sucessHandler" :header-config="headRules" />
    <ConfrimModal ref="rejectModalRef" @commit="reject" />
    <RepeatModal ref="repeatModalRef" @reject="showModal(rejectModalRef)" @viewrepeat="showModal(repeatTaskTableModalRef)" />
    <RepeatTaskTableModal ref="repeatTaskTableModalRef" />
  </div>
</template>

<style lang="less" scoped>
.wrapper {
  display: flex;
  flex: 1;
  overflow: hidden;
  flex-direction: column;
  box-sizing: border-box;
  margin-left: 16px;
  width: 100%;
  background: #FFF;
  padding: 0px 24px 24px 24px;

  &-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-sizing: border-box;
    height: 64px;
    width: 100%;

    div {
      display: flex;
      align-items: center;
    }

    .xjcc{
      font-weight: bold;
      color:  #6a80fc;
      margin-right: 20px;
    }

    .title {
      color: #507afd;
      font-weight: bold;
      font-size: 14px;
      margin-left: 8px;
    }

    .btn {
      width: 118px;
      height: 36px;
      background: linear-gradient(135deg, #5b85f8, #3c6cf0);
      border-radius: 17px;
      box-shadow: 0px 2px 6px 0px rgba(116, 153, 253, 0.30);
      display: flex;
      align-items: center;
      justify-content: center;
      color: #FFF;
      margin-right: 6px;
      cursor: pointer;
    }

    .more {
      width: 30px;
      height: 30px;
      line-height: 30px;
      opacity: 0.1;
      background: linear-gradient(144deg, #73a7f9 0%, #3e6ef1 96%);
      border-radius: 8px;
    }

    &-font {
      font-size: 18px;
      font-weight: bold;
      color: #333333;
      line-height: 25px;
      margin-right: 8px;
    }

    &-action {
      padding: 8px;

      li {
        height: 32px;
        line-height: 32px;
        cursor: pointer;

        &:hover {
          background-color: #f3f8ff;
        }
      }
    }
  }

  &-settings {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: 12px 0px;
  }

  &-statistic {
    width: 100%;
    height: 76px;
    background: #f9fafb;
    border-radius: 4px;
    display: flex;
    padding: 0px 10px;
    justify-content: space-between;

    .item {
      display: flex;
      align-items: center;
      padding: 20px 0;

      .icon {
        background-color: #ecf2fe;
        width: 50px;
        height: 50px;
        border-radius: 50px;
      }

      .content {
        text-align: center;
        margin-left: 12px;

        .num {
          font-weight: bold;
          color: #202020;
          font-size: 18px;
        }

        .label {
          color: #202020;
          opacity: 0.6;
        }

        span {
          display: block;
        }
      }

      .divider {
        background-color: #e8e8e8;
        margin: 0px 10px;
        width: 3px;
        height: 20px;
      }
    }
  }

  &-content {
    flex: auto;
    background: #FFF;
  }
}
</style>
