<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>
        </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>
</template>

<script setup>
import { h } from 'vue'
import userStore from '@/store/modules/user'
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
  }
})
const emit = defineEmits(['getTableList', 'updateShowSearch'])

/*************** 工具栏 ***************/
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 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">
/* 表格弹窗 */
.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>