<template>
  <div class="w-full h-full bg-white p-4">
    <p class="font-bold text-lg leading-10 border-b-2">解析列表</p>
    <el-form class="pt-4" :inline="true" :model="queryParams">
      <el-form-item label="excelOrderId">
        <el-input v-model="queryParams.excelOrderId" placeholder="" clearable />
      </el-form-item>
      <el-form-item label="templateFileId">
        <el-input v-model="queryParams.templateFileId" placeholder="" clearable />
      </el-form-item>

      <el-form-item>
        <el-button type="default" @click="onReset">重置</el-button>
        <el-button type="primary" @click="onQuery">查询</el-button>
      </el-form-item>
    </el-form>

    <div class="">
      <vxe-toolbar>
        <template #buttons>
          <el-button type="danger" @click="removeRows">删除</el-button>
        </template>
      </vxe-toolbar>
      <vxe-table
        ref="xTable"
        size="small"
        min-height="460"
        border
        :loading="loading"
        :data="tableData"
      >
        <vxe-column type="checkbox" width="50"></vxe-column>
        <vxe-column field="fileId_dictText" title="文件名称"></vxe-column>
        <vxe-column field="status_dictText" title="订单状态" width="200"></vxe-column>
        <vxe-column field="createTime" title="创建时间" width="180"></vxe-column>
        <vxe-column field="action" title="操作" width="120">
          <template #default="{ row }">
            <el-link style="font-size: 12px" type="primary" @click="toDetail(row)">查看</el-link>
            <el-link
              class="ml-1"
              style="font-size: 12px"
              v-if="row.status == 'un_confirm' || row.status == 'converted'"
              type="primary"
              @click="confirmOrderStatus(row)"
              >确认</el-link
            >
          </template>
        </vxe-column>
      </vxe-table>

      <vxe-pager
        size="small"
        background
        v-model:current-page="queryParams.currentPage"
        v-model:page-size="queryParams.pageSize"
        :total="queryParams.total"
        @page-change="onQuery"
        :layouts="['PrevPage', 'JumpNumber', 'NextPage', 'Sizes', 'FullJump', 'Total']"
      >
      </vxe-pager>
    </div>
  </div>

  <vxe-modal v-model="detailVisible" title="解析详情" width="80%" show-footer>
    <vxe-table
      size="mini"
      show-overflow="tooltip"
      show-header-overflow="tooltip"
      :data="detailTable"
      border
      :expand-config="expandConfig"
      height="500"
    >
      <vxe-column title="行号" type="expand" width="120">
        <template #default="{ row }">{{ row.sortNum }}</template>
        <template #content="{ row, rowIndex }">
          <div style="padding: 10px">
            <template v-for="attchName of filterObjKeys(row.expendData)" :key="attchName">
              <p>{{ attchName }}</p>
              <vxe-table
                :data="row.expendData[attchName]"
                :header-row-style="{ background: '#f9f8f9' }"
                min-height="120"
                height="120"
                size="mini"
                show-overflow="tooltip"
                show-header-overflow="tooltip"
                style="width: 70vw"
                border
              >
                <vxe-colgroup
                  v-for="key in filterObjKeys(row.expendData[attchName][0])"
                  :key="key"
                  :title="key"
                >
                  <vxe-column :title="key" :field="key" width="200">
                    <template #header>
                      <div class="header-cell" @click="(e) => showPopover(e, key, attchName)">
                        <span>{{
                          allMapConfigs[attchName + '__' + key]?.orderFiled.fliedTitle || ''
                        }}</span>
                        <el-icon><Setting /></el-icon>
                      </div>
                    </template>
                  </vxe-column>
                </vxe-colgroup>
              </vxe-table>
            </template>
          </div>
        </template>
      </vxe-column>
      <vxe-column title="数据区" width="120">
        <template #default="{ row }">{{ row['数据区'] }}</template>
      </vxe-column>
      <template v-for="item in tableTitle" :key="item">
        <vxe-colgroup :title="item">
          <vxe-column :title="item" :field="item" width="200">
            <template #header>
              <div class="header-cell" @click="(e) => showPopover(e, item)">
                <span>{{ allMapConfigs[item]?.orderFiled.fliedTitle || '' }}</span>
                <el-icon><Setting /></el-icon>
              </div>
            </template>
          </vxe-column>
        </vxe-colgroup>
      </template>
    </vxe-table>

    <el-popover
      ref="popoverRef"
      placement="bottom"
      :virtual-ref="buttonRef"
      trigger="click"
      :title="currentConfigTitle"
      :visible="popoverVisible"
      virtual-triggering
      width="360"
      transition=""
    >
      <el-form size="small" label-width="7em" inline :model="currentConfigColumn">
        <el-row>
          <el-col :span="24">
            <el-form-item label="对应字段" prop="mapField">
              <el-select v-model="currentConfigColumn.mapField" :teleported="false" clearable>
                <el-option
                  v-for="item in orderFieldList"
                  :key="item.filedName"
                  :value="item.filedName"
                  :label="item.fliedTitle"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24" v-if="currentConfigColumn.mapField">
            <el-form-item label="脚本">
              <el-select v-model="currentConfigColumn.scriptName" :teleported="false" clearable>
                <el-option
                  v-for="item in scriptList"
                  :key="item.srciptName"
                  :value="item.srciptName"
                  :label="item.srciptName"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>

          <template v-for="params in currentScriptParamsList">
            <el-col :span="24">
              <el-form-item :label="params.fliedTitle">
                <el-input v-model="scriptPs[params.filedName]" />
              </el-form-item>
            </el-col>
          </template>
          <el-col :span="24" v-if="currentConfigColumn.scriptName">
            <el-form-item label="脚本语句">
              <el-input
                rows="3"
                type="textarea"
                v-model.trim="currentConfigColumn.content"
              ></el-input>
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item>
          <el-button type="primary" @click="confirmConfig">确认</el-button>
          <el-button type="primary" @click="popoverVisible = false">取消</el-button>
        </el-form-item>
      </el-form>
    </el-popover>

    <template #footer>
      <el-button @click="confirmChange">确认转换</el-button>
    </template>
  </vxe-modal>
</template>

<script lang="ts" setup>
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { Setting } from '@element-plus/icons-vue'
import { cloneDeep } from 'lodash-es'
import {
confirmExcelFileOrderById,
  convertExcelFileOrder,
  deleteExcelFileOrderById,
  getExcelFileOrderPage,
  unconvertExcelFileOrder
} from '@/api/order'
import { ElMessage, ElMessageBox, ClickOutside as vClickOutside } from 'element-plus'
import type { VxeTableInstance } from 'vxe-table'
import type { Recordable } from '@/types/global'
import { filterRunData } from '@/utils/excel'
import { apiGetOrderField, apiGetScript } from '@/api/excel'

const loading = ref(false)
/**查询参数 */
const queryParams = reactive({
  templateFileId: '',
  excelOrderId: '',
  currentPage: 1,
  pageSize: 10,
  total: 0,
  column: 'createTime',
  order: 'desc'
})

/**所有列映射配置 */
const allMapConfigs = reactive<Recordable>({})
/**当前表单映射字段配置 */
const currentConfigColumn = reactive({
  title: '',
  content: '',
  mapField: '',
  scriptName: '',
  groupTitle: '',
  templateFileId: '',
  excelOrderFiledConfId: '',
  params: {},
  orderFiled: {}
})
const currentConfigTitle = ref('')

const scriptPs = ref<Recordable>({})
/**所有脚本 */
const scriptList = ref<Recordable[]>([])
/**所有映射字段 */
const orderFieldList = ref<Recordable[]>([])

const xTable = ref<VxeTableInstance>()
const tableData = ref([])
/**当前选择行 */
const currentRow = reactive<Recordable>({})
/**弹窗显示 */
const detailVisible = ref(false)
/**详情表格数据 */
const detailTable = ref<Recordable[]>([])
/**表格title */
const tableTitle = ref<string[]>([])
const expandConfig = reactive({
  visibleMethod({ row }) {
    if (typeof row.expendData === 'object') {
      return true
    }
    return false
  }
})

const popoverRef = ref()
const buttonRef = ref()
const popoverVisible = ref(false)
const showPopover = (e: any, title: string, groupTitle: string = '') => {
  buttonRef.value = e.target
  const t = groupTitle ? `${groupTitle}-${title}` : title
  // 设置标题
  currentConfigTitle.value = t

  Object.assign(currentConfigColumn, { ...allMapConfigs[t], title, groupTitle })
  // 打开popover
  popoverVisible.value = true
}

/**监听popover和modal显示状态。重置表单信息 */
watch([detailVisible, popoverVisible], (val) => {
  // 关闭弹窗或者关闭popover
  if (val.includes(false)) {
    // 解决关闭弹窗之后，popover未关闭情况
    popoverVisible.value = false
    // 重置表单
    resetConfigForm()
  }
})

/**监听currentConfigColumn.mapField字段，重置/设置 orderFiled */
watch(
  () => currentConfigColumn.mapField,
  (val) => {
    // 如果有值设置 currentConfigColumn.orderFiled字段
    if (val) {
      const item = orderFieldList.value.find((v) => v.filedName == val)
      Reflect.set(currentConfigColumn, 'orderFiled', item)
    } else {
      Reflect.set(currentConfigColumn, 'orderFiled', {})
      Reflect.set(currentConfigColumn, 'scriptName', '')
      Reflect.set(currentConfigColumn, 'content', '')
    }
  }
)

/**重置popover配置表单 */
const resetConfigForm = () => {
  Object.assign(currentConfigColumn, {
    title: '',
    content: '',
    mapField: '',
    scriptName: '',
    groupTitle: '',
    templateFileId: '',
    excelOrderFiledConfId: ''
  })
}

/** 脚本参数List */
const currentScriptParamsList = computed(() => {
  const item: any = scriptList.value.find((v) => v.srciptName == currentConfigColumn.scriptName)
  // 生成脚本参数表单
  gScriptPs(item?.paramsName)
  return item?.paramsName != null ? item.paramsName : []
})

/**通过选中的脚本生成脚本配置表单 */
const gScriptPs = (scriptNames: null | Recordable[] | undefined) => {
  // 如果没有配置参数，清空脚本表单
  if (scriptNames == null && scriptNames == undefined) {
    scriptPs.value = {}
  } else {
    // 查询是否有已经设置过的值
    const { title, groupTitle } = currentConfigColumn
    const t = groupTitle ? `${groupTitle}__${title}` : title
    const params = allMapConfigs[t].params
    scriptNames.forEach((item) => {
      Reflect.set(scriptPs.value, item.filedName, params[item.filedName] || '')
    })
  }
}

/** 保存字段映射及脚本的配置 */
const confirmConfig = () => {
  // 合并脚本参数
  Reflect.set(currentConfigColumn, 'params', scriptPs.value)
  Reflect.set(currentConfigColumn, 'templateFileId', currentRow.templateFileId)
  // 处理标题
  const { title, groupTitle } = currentConfigColumn

  // 保存本地配置
  title &&
    Reflect.set(
      allMapConfigs,
      groupTitle ? `${groupTitle}__${title}` : title,
      cloneDeep(currentConfigColumn)
    )

  // 关闭popover
  popoverVisible.value = false
  console.log('allMapConfigs', allMapConfigs)
}

const getScriptList = async () => {
  const { data } = await apiGetScript()
  scriptList.value = data.result
}
const getOrderFields = async () => {
  const { data } = await apiGetOrderField()
  orderFieldList.value = data.result
}

/**确认解析/转换的订单的状态 */
const confirmOrderStatus = async (row: any) => {
  if (row.status === 'un_confirm') {
    await ElMessageBox.confirm('是否确认解析后的订单？', '提示', {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning'
    })
    const { data } = await unconvertExcelFileOrder(row.excelOrderId)
    if (data.code == 200) {
      ElMessage.success(data.message || '操作成功！')
    }
  } else if (row.status == 'converted') {
    await ElMessageBox.confirm('是否确认转换后的订单？', '提示', {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning'
    })

    const {data} = await confirmExcelFileOrderById(row.excelOrderId)
    if (data.code == 200) {
      ElMessage.success(data.message || '操作成功！')
    } else {
      ElMessage.error(data.message || '操作失败！')
    }
  }

  onQuery()
}

/** 确认订单转换 */
const confirmChange = async () => {
  await ElMessageBox.confirm('是否确认订单转换？', '提示', {
    confirmButtonText: '转换',
    cancelButtonText: '取消',
    type: 'warning'
  })
  const { data } = await convertExcelFileOrder(currentRow.excelOrderId)
  if (data.code == 200) {
    ElMessage.success(data.message || '转换成功！')
    detailVisible.value = false
    return
  }
  ElMessage.error(data.message || '转换失败！')
}

const toDetail = (row: any) => {
  Object.assign(currentRow, row)
  const { res, titles, configs } = filterRunData(row.orders)
  // 排除通过循环不显示的column
  const excludeTitles = ['sortNum', '数据区', 'expendData']
  detailTable.value = res
  tableTitle.value = titles.filter((v) => !excludeTitles.includes(v))
  detailVisible.value = true

  excludeTitles.forEach((key) => {
    Reflect.deleteProperty(configs, key)
  })

  Object.assign(allMapConfigs, configs)
}

const filterObjKeys = (data: any) => {
  return Object.keys(data).filter((v) => v !== '_X_ROW_KEY')
}

/**批量删除行 */
const removeRows = async () => {
  const list = xTable.value?.getCheckboxRecords()
  if (list?.length) {
    const ids = list.map((v) => v.excelOrderId).join(',')
    await deleteExcelFileOrderById(ids)
    ElMessage.success('删除成功')
    onQuery()
  }
}

const onReset = () => {}
const onQuery = async () => {
  loading.value = true
  try {
    const { data } = await getExcelFileOrderPage(queryParams)
    tableData.value = data.result.records
    queryParams.total = +data.result.total
  } catch {}
  loading.value = false
}

onMounted(() => {
  onQuery()
  getOrderFields()
  getScriptList()
})
</script>
<style lang="scss" scoped>
.header-cell {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 178px;
}
.expandTableHeader {
  background: #e8eaec;
}
</style>
