<template>
  <div class="flex-container">
    <!-- 操作类型 -->
    <el-row>
      <el-form-item>
        <el-radio-group v-model="operation">
          <el-radio-button label="展示模式"
            value="展示模式" />
          <el-radio-button label="填报模式"
            value="填报模式"
            v-if="showFill" />
        </el-radio-group>
        <!-- 提示文字 -->
        <span class="tip-title">请真实，及时，准确填写！</span>
      </el-form-item>
      <right-toolbar v-model:showSearch="showSearch"
        @queryTable="getTableList()"
        :columns="chooseColumns"
        :showColumnsType="operation === '展示模式' ? 'tree' : 'checkbox'"
        :defaultCheckedKeys="visibleProps">
        <!-- 添加自定义工具栏插槽 -->
        <template #default>
          <!-- 默认插槽内容，父组件可以覆盖 -->
          <el-tooltip class="item"
            effect="dark"
            content="放大表格"
            placement="top">
            <el-button circle
              icon="Rank"
              @click="openTableDialog" />
          </el-tooltip>
          <el-tooltip class="item"
            effect="dark"
            content="下载表格"
            placement="top"
            v-if="tabsType === '常规陈列'">
            <el-button @click="downloadTable"
              type="primary"
              v-hasPermi="['display_downExcel']">
              下载表格
            </el-button>
          </el-tooltip>
          <el-tooltip class="item"
            effect="dark"
            content="上传表格"
            placement="top"
            v-if="tabsType === '常规陈列'">
            <el-button @click="uploadExcel"
              type="success"
              v-hasPermi="['display_upExcel']">
              上传表格
            </el-button>
          </el-tooltip>
        </template>
      </right-toolbar>
    </el-row>
    <!-- 表格容器 - 用于DOM移动 -->
    <div ref="tableContainer"
      class="table-container">
      <!-- 数据表格 -->
      <el-table :data="tableData"
        border
        ref="tableRef"
        class="auto-fit-header-table"
        v-loading="isLoading"
        show-overflow-tooltip
        :class="{ 'cell-no-padding': operation === '填报模式' }"
        :row-style="tableRowStyle">
        <template v-for="col in tableColumns">
          <el-table-column v-if="col.visible"
            :label="col.label"
            :prop="col.prop"
            :key="col.prop"
            align="center"
            class-name="column-style"
            :width="col.width"
            :fixed="operation === '填报模式' && col.fixed">
            <template #header="{ column }">
              <!-- 只为特定公式列添加问号图标 -->
              <span class="formula-column">
                <div class="column">
                  <p>{{ column.label }}</p>
                  <p v-if="col.subLabel">{{ col.subLabel }}</p>
                </div>
                <el-tooltip v-if="col.type === 'formula'"
                  :content="col.formulaStr"
                  placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
              </span>
            </template>
            <template #default="{ row }">
              <!-- 填报模式 -->
              <div v-if="operation === '填报模式'">
                <!-- 自定义渲染内容单元格 -->
                <div v-if="col.render"
                  class="cell-style">
                  <component :is="col.render(h, row, col, !isCurrentMonth(row.salesMonth))" />
                </div>
                <!-- 公式计算 -->
                <div v-else-if="col.type === 'formula'">
                  {{ row[col.prop] || '-' }}
                </div>
                <!-- 其他类型内容（正常显示文字） -->
                <div class="fill-span-wrap"
                  v-else>{{ row[col.prop] || '-' }}
                </div>
              </div>
              <!-- 展示模式 -->
              <div class="show-cell-style"
                v-else>{{ formatter(row, col, row[col.prop] || '-') }}</div>
            </template>
          </el-table-column>
        </template>
      </el-table>
      <!-- 分页 -->
      <pagination :total="total"
        v-model:page="params.pageNum"
        v-model:limit="params.pageSize"
        :pageSizes="[10, 20, 50, 100]"
        @pagination="getTableList" />
    </div>
  </div>
  <!-- 表格弹窗 - 使用DOM移动而非复制 -->
  <el-dialog v-model="showTableInDialog"
    title="表格详情"
    modal-class="table-dialog-modal"
    fullscreen
    :before-close="handleDialogClose">
    <!-- 弹窗内的表格容器 -->
    <div ref="dialogTableContainer"
      class="dialog-table-container"></div>
  </el-dialog>

  <!-- 上传表格-确认弹窗 -->
  <el-dialog title="上传表格"
    v-model="uploadPlanDialogVisible"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    draggable
    overflow
    body-class="dialog-table-container"
    @close="handleDialogCloseUpload">
    <div class="table-container">
      <!-- 计划表格 -->
      <el-table :data="planTableList"
        border
        class="auto-fit-header-table"
        style="width: 100%"
        show-overflow-tooltip
        :row-class-name="tableRowClassName">
        <el-table-column prop="errorMsg"
          label="错误信息"
          width="450"
          v-if="isHaveErrPlan" />
        <el-table-column v-for="item in fillModeColumns"
          :key="item.label"
          :prop="item.prop"
          :label="item.label"
          :width="item.width"
          class-name="column-style">
          <template #header="{ column }">
            <span class="formula-column">
              <div class="column">
                <p>{{ item.label }}</p>
                <p v-if="item.subLabel">{{ item.subLabel }}</p>
              </div>
            </span>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <p style="color: red; float: left;">如果表格有红色行，请根据错误提示修改本地表格重新上传</p>
        <el-button @click="cancel">取消上传</el-button>
        <el-button type="primary"
          :disabled="isHaveErrPlan"
          @click="confirmPlanBtn">
          确定保存
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { h } from 'vue'
import userStore from '@/store/modules/user'
import { downloadDisplayScheduleTable, uploadDisplayScheduleTable, uploadFileToOSSAPI, confirmUploadDisplayScheduleTable } from '@/api'
import { saveAs } from 'file-saver'
import { parseTime } from '@/utils'
import { v4 as uuidv4 } from 'uuid'

const props = defineProps({
  tableData: { // 数据源
    type: Array,
    default: () => []
  },
  baseColumns: { // 表格列
    type: Array,
    default: () => []
  },
  total: { // 总条数
    type: Number,
    default: 0
  },
  params: { // 分页参数
    type: Object,
    default: () => ({
      pageNum: 1,
      pageSize: 10,
    })
  },
  isLoading: { // 表格加载状态
    type: Boolean,
    default: false
  },
  formatter: { // 格式化函数
    type: Function,
    default: (row, col, cellValue) => cellValue
  },
  tabsType: { // 当前 tab 类型
    type: String,
    default: '常规陈列' // 默认常规陈列
  }
})
const emit = defineEmits(['getTableList', 'updateShowSearch'])

const { proxy } = getCurrentInstance()

/*************** 工具栏 ***************/
const showFill = userStore().hasQcMarketEmpInfo // 是否启用填报模式
const operation = ref('展示模式'); // 切换平铺/填报模式
// const operation = ref('填报模式'); // 切换平铺/填报模式
const tableRef = ref(null)
const chooseColumns = ref([]) // 右上角工具显隐列选择

// 使用computed缓存展示列，避免重复创建
const displayModeColumns = computed(() => {
  return props.baseColumns.flatMap(item => {
    if (item.children) {
      return item.children.filter(child => !child.onlyFill);
    }
    return [];
  });
});

// 使用computed缓存填报列，避免重复创建
const fillModeColumns = computed(() => {
  return props.baseColumns.flatMap(item => {
    if (item.children) {
      return item.children.filter(child => child.fill === true)
    }
    return [];
  });
});

// 使用computed动态返回当前模式的列
const tableColumns = computed(() => {
  return operation.value === '展示模式' ? displayModeColumns.value : fillModeColumns.value;
});

// 监听operation变化，更新chooseColumns并触发布局调整
watch(operation, () => {
  chooseColumns.value = operation.value === '展示模式' ? props.baseColumns : fillModeColumns.value;

  // 强制表格立即应用所有宽度设置
  nextTick(() => {
    if (tableRef.value) {
      tableRef.value.doLayout()
    }
  });
}, { immediate: true });

const visibleProps = computed(() => {
  return props.baseColumns.flatMap(item => {
    if (item.children) {
      return item.children.filter(child => child.visible).map(child => child.prop);
    }
    return item.prop;
  });
});

// 控制搜索框显隐
const showSearch = ref(true)
watch(showSearch, (newVal) => {
  emit('updateShowSearch', newVal)
})
// 刷新数据
const getTableList = () => {
  emit('getTableList')
}

// 下载表格
const typeObj = {
  '常规陈列': 'NORMAL_DISPLAY_EXPORT',
  '档期计划': 'PROMOTION_PLAN_EXPORT',
  '档期陈列': 'PROMOTION_DISPLAY_EXPORT',
  '零食陈列': 'SNACK_DISPLAY_EXPORT',
  '三米两秒': 'THREE_METER_TWO_SECONDS_EXPORT',
  '六小金刚': 'SIX_KINGkONG_EXPORT'
}
const downloadTable = async () => {
  proxy.$modal.loading('正在下载表格，请稍候...')
  try {
    const res = await downloadDisplayScheduleTable({
      ...props.params,
      salesMonth: parseTime(props.params.salesMonth, '{y}-{m}'),
      rqStatus: props.params.rqStatus === '全部' ? null : props.params.rqStatus,
      pageNum: null,
      pageSize: null,
      pageType: typeObj[props.tabsType]
    })
    if (res.type === 'application/json') {
      // 本次返回的不是二进制，而是 JSON 被转成了 Blob
      const result = await res.text()
      const response = JSON.parse(result)
      if (response.code === 910) {
        proxy.$modal.closeLoading()
        proxy.$modal.msgError(response.msg || '下载表格失败')
        return
      }
    }

    // 如果 salesMonth 为空，默认当前月
    if (props.params.salesMonth) {
      saveAs(res, `${props.tabsType}计划${parseTime(new Date(), '{y}-{m}-{d} {h}-{i}-{s}')}.xlsx`)
    } else {
      saveAs(res, `${props.tabsType}计划${parseTime(new Date(), '{y}-{m}-{d} {h}-{i}-{s}')}.xlsx`)
    }
    // 下载完成后，执行回调函数
    proxy.$modal.closeLoading()
  } catch (error) {
    proxy.$modal.closeLoading()
  }
}

// 上传表格
const uploadPlanDialogVisible = ref(false)
const planTableList = ref([])
const isHaveErrPlan = computed(() => {
  return planTableList.value.some(item => item.errorMsg)
})
const nowUUID = ref('') // 本次导入的 excel 标记（用于下次保存确定接口使用）
const nowExcelUrl = ref('') // 本次导入的 excel 地址
const importTypeObj = {
  '常规陈列': 'NORMAL_DISPLAY_IMPORT',
  '档期计划': 'PROMOTION_PLAN_IMPORT',
  '档期陈列': 'PROMOTION_DISPLAY_IMPORT',
  '零食陈列': 'SNACK_DISPLAY_IMPORT',
  '三米两秒': 'THREE_METER_TWO_SECONDS_IMPORT',
  '六小金刚': 'SIX_KINGkONG_IMPORT'
}
const uploadExcel = () => {
  proxy.$modal.loading('正在上传表格，请稍候...')
  proxy.chooseFile({
    accept: '.xls, .xlsx'
  }).then(async file => {
    // 先上传阿里云
    const excelUrl = await uploadFileToOSSAPI(`storeReport/${userStore().empInfo.empNo}/${uuidv4()}.${file.name.split('.').pop()}`, file)
    const res = await uploadDisplayScheduleTable({
      importApFilePath: excelUrl,
      importApType: importTypeObj[props.tabsType]
    })
    nowExcelUrl.value = excelUrl
    nowUUID.value = res.data.uuid || ''
    planTableList.value = res.data.table || []
    uploadPlanDialogVisible.value = true
  }).finally(() => {
    proxy.$modal.closeLoading()
  })
}
const tableRowClassName = ({ row }) => {
  if (row.errorMsg) {
    return 'error-row'
  } else {
    return ''
  }
}

// 取消
const cancel = () => {
  uploadPlanDialogVisible.value = false
  proxy.$modal.closeLoading()
}
// 确定上传
const confirmPlanBtn = async () => {
  const res = await confirmUploadDisplayScheduleTable({
    uuid: nowUUID.value,
    importApFilePath: nowExcelUrl.value,
    importApType: importTypeObj[props.tabsType]
  })
  if (res.code === 200) {
    proxy.$modal.msgSuccess('导入成功')
    getTableList()
    uploadPlanDialogVisible.value = false
  } else {
    proxy.$modal.msgError(res.msg || '导入失败')
  }
}

const handleDialogCloseUpload = () => {
  uploadPlanDialogVisible.value = false
  proxy.$modal.closeLoading()
}

/************** 弹框控制 ***************/
// 控制表格弹框显隐
const tableContainer = ref(null) // 原始表格容器引用
const dialogTableContainer = ref(null) // 弹窗内表格容器引用
const showTableInDialog = ref(false)

// DOM移动需要的引用
let containerElement = null // 保存整个可移动容器
let originalParent = null // 保存原始父容器

// 打开表格弹窗并移动DOM
const openTableDialog = async () => {
  // 保存容器元素和原始父容器引用
  if (tableContainer.value) {
    containerElement = tableContainer.value
    originalParent = containerElement.parentElement
  }

  // 显示弹窗
  showTableInDialog.value = true

  // 等待弹窗渲染完成后移动DOM
  await nextTick()
  moveContentToDialog()
}

// 移动内容到弹窗
const moveContentToDialog = () => {
  if (containerElement && dialogTableContainer.value) {
    // 关键DOM移动操作 - 现在会移动整个容器（包含表格和分页器）
    dialogTableContainer.value.appendChild(containerElement)

    // 调整表格布局
    nextTick(() => {
      if (tableRef.value) {
        tableRef.value.doLayout()
      }
    })
  }
}

// 移动内容回原位
const moveContentBack = () => {
  if (containerElement && originalParent) {
    // 关键DOM移动操作
    originalParent.appendChild(containerElement)

    // 调整表格布局
    nextTick(() => {
      if (tableRef.value) {
        tableRef.value.doLayout()
      }
    })
  }
}

// 关闭弹窗
const handleDialogClose = () => {
  // 先移动内容回原位
  moveContentBack()
  // 然后关闭弹窗
  showTableInDialog.value = false
}

/*************** 非当月置灰行 ***************/
// 获取当前月份的函数
const getCurrentMonth = () => {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, '0');
  return `${year}-${month}`;
};

// 检查是否为当前月的函数
const isCurrentMonth = (salesMonth) => {
  return salesMonth === getCurrentMonth();
};

// 行样式函数
const tableRowStyle = ({ row }) => {
  if (!isCurrentMonth(row.salesMonth)) {
    return { backgroundColor: '#f5f7fa' }; // 灰色背景
  }
  return {};
};
</script>

<style scoped
  lang="scss">

  /* 根容器设置为flex布局，占据整个可用空间 */
  .flex-container {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;

    /* 工具栏 */
    .el-row {
      .el-form-item {
        .tip-title {
          font-size: 32px;
          color: red;
          margin-left: 50px;
          font-weight: 900;
          margin-top: -5px;
        }
      }
    }
  }

  /* 因为表格会被挪走，所以必须独立样式无法嵌套在别人内 */
  /* 表格样式 */
  .table-container {
    flex: 1;
    /* 这是关键，让表格容器自动占据剩余空间 */
    display: flex;
    flex-direction: column;
    min-height: 0;

    /* 解决flex子项内容溢出问题 */
    .auto-fit-header-table {
      flex: 1;

      /* 列样式 */
      .column-style {

        /* 列头样式 */
        .formula-column {
          display: flex;
          justify-content: center;
          align-items: center;

          .column {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;

            p {
              margin: 0;
              font-size: 12px;
              color: #606266;
            }
          }

          .el-icon {
            margin-left: 2px;
          }
        }

        /* 单元格样式 */
        /* 展示模式单元格（仅展示模式生效） */
        .show-cell-style {
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }

        /* 自定义单元格样式（仅填充模式生效） */
        .cell-style {
          >div {
            display: flex;
            flex-direction: column;
            align-items: center;

            >span {
              text-align: left;
              text-indent: 5px;
              display: inline-block;
              width: 80%;
              background-color: #e1e2e6;
              border-bottom: 1px solid #ebeef5;
            }
          }

          /* 表格内下拉框 */
          .el-select {
            width: 100% !important;
            padding: 10px;

            /* 非 disabled 状态下的背景颜色 */
            &.no-disabled ::v-deep(.el-select__wrapper) {
              border: 4px solid var(--el-background-editor-cell) !important;
            }
          }

          .el-input {
            height: 32px !important;
            /* box-sizing: content-box; */
            padding: 0 10px;
            width: 100%;


            /* 非 disabled 状态下的背景颜色 */
            &.no-disabled ::v-deep(.el-input__wrapper) {
              border: 4px solid var(--el-background-editor-cell) !important;
            }

          }

          .date-picker {
            width: 100%;
            padding: 10px;

            /* 非 disabled 状态下的背景颜色 */
            &.no-disabled ::v-deep(.el-input__wrapper) {
              border: 4px solid var(--el-background-editor-cell) !important;
            }

            ::v-deep(.el-input) {
              width: 100%;
              padding: 0;
            }
          }
        }

        /* 普通文字单元格（仅填充模式生效） */
        .fill-span-wrap {
          /* 超出省略号 */
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          padding: 0 10px;
        }

      }

      /* 填报模式-单元格 */
      &.cell-no-padding {

        /* 无上下内边距 */
        ::v-deep(.el-table__row) {
          .el-table__cell {
            padding-top: 0;
            padding-bottom: 0;

            .cell {
              padding: 0 !important;
            }
          }
        }
      }
    }



    /* 分页器 */
    .pagination-container {
      margin: 10px;
    }
  }



</style>

<style lang="scss">
// 上传表格确认框内表格的样式
.dialog-table-container {
  overflow-y: hidden !important;

  // 消除滚动条
  ::-webkit-scrollbar {
    display: none;
  }

  .table-container {
    height: 100%;
    overflow-y: scroll;

    .el-table {

      ::v-deep(.error-row) {
        --el-table-tr-bg-color: var(--el-color-error-light-9);
      }

      /* 灰色过期行颜色 */
      ::v-deep(.timeout-row) {
        --el-table-tr-bg-color: var(--el-timeout-row);
      }
    }
  }
}

/* 表格弹窗 */
.table-dialog-modal {
  padding: 0;

  /* 关键：覆盖Element Plus对话框的默认最大宽度 */
  .el-dialog {
    width: 100% !important;
    max-width: none !important;
    margin: 0 !important;
    height: 100vh;
    display: flex;
    flex-direction: column;

    .el-dialog__body {
      flex: 1;
      display: flex;
      flex-direction: column;
      overflow: hidden !important;
      padding-bottom: 5px;

      .dialog-table-container {
        flex: 1;
        height: 100%;

        .table-container {
          flex: 1;
          display: flex;
          flex-direction: column;
          height: 100%;

          .pagination-container {
            margin-left: auto;
          }
        }
      }
    }
  }
}

// 不显示数字输入框的 spinner
.no-spinner input::-webkit-inner-spin-button,
.no-spinner input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.no-spinner {
  -moz-appearance: textfield;
}

// 填入数字超过计划值时，红色文字提示
.red-text {
  input {
    color: red !important;
  }
}
</style>