<template>
  <div class="el-table-page">
    <el-table :data="TASK_TEMPLATE_HEADER" :show-header="false" border>
      <el-table-column prop="title" align="center" width="110" />
      <el-table-column prop="content" align="center" />
    </el-table>
    <el-table :data="mergedTableData" :span-method="handleSpanMethod" border class="custom-table">
      <el-table-column v-for="column in TASK_TEMPLATE_MAIN_COLUMNS" :key="column.prop" v-bind="column" align="center">
        <template #default="scope">
          <!-- 底部表格内容 - 第一列 -->
          <template v-if="scope.row.rowType === 'footer' && column.prop === 'inspectItem'">
            <div v-if="scope.row.footerType === 'inspectionAndSelftest'" class="inspection-result--div">
              <span class="inspection-result--title">检查结论及存在问题：</span>
              <el-input
                v-model="resultData.executeResult"
                maxlength="200"
                style="width: 100%"
                placeholder="必填，输入检查结论及存在问题，1-200字"
                type="textarea"
                :rows="3"
                v-if="props.operationType === 'check'"
              />
              <div
                class="inspection-result-approve"
                v-else-if="props.operationType === 'approve' || props.operationType === 'view'"
              >
                <div class="execute-result">{{ resultData.executeResult }}</div>
                <div class="execute-person">
                  <span v-if="resultData.executeName">检查人员：{{ resultData.executeName }}</span>
                  <span v-if="resultData.inspectTime">时间：{{ resultData.inspectTime }}</span>
                  <div
                    class="execute-images"
                    v-if="resultData.executeImages && safetyJsonParse(resultData.executeImages).length > 0"
                  >
                    <el-tooltip content="图片查看" effect="light">
                      <el-image
                        :src="ImageIcon"
                        :zoom-rate="1.2"
                        :max-scale="7"
                        :min-scale="0.2"
                        :preview-src-list="safetyJsonParse(resultData.executeImages)"
                        :initial-index="0"
                        show-progress
                        preview-teleported
                        fit="cover"
                      />
                    </el-tooltip>
                  </div>
                </div>
              </div>
            </div>
          </template>

          <!-- 底部表格内容 - 第二列 -->
          <template v-else-if="scope.row.rowType === 'footer' && column.prop === 'inspectStandard'">
            <div v-if="scope.row.footerType === 'inspectionAndSelftest'" class="inspection-result--div">
              <span class="inspection-result--title">被检查（自查）所/部/中心意见：</span>
              <el-input
                v-model="opinionData.executeResult"
                maxlength="200"
                style="width: 100%"
                placeholder="必填，输入被检查（自查）所/部/中心意见，1-200字"
                type="textarea"
                :rows="3"
                v-if="props.operationType === 'approve'"
              />
              <div class="inspection-result-approve" v-else-if="props.operationType === 'view'">
                <div class="execute-result">{{ opinionData.executeResult }}</div>
                <div class="execute-person">
                  <span v-if="opinionData.executeName">审批人员：{{ opinionData.executeName }}</span>
                  <span v-if="opinionData.inspectTime">时间：{{ opinionData.inspectTime }}</span>
                  <div
                    class="execute-images"
                    v-if="opinionData.executeImages && safetyJsonParse(opinionData.executeImages).length > 0"
                  >
                    <el-tooltip content="图片查看" effect="light">
                      <el-image
                        :src="ImageIcon"
                        :zoom-rate="1.2"
                        :max-scale="7"
                        :min-scale="0.2"
                        :preview-src-list="safetyJsonParse(opinionData.executeImages)"
                        :initial-index="0"
                        show-progress
                        preview-teleported
                        fit="cover"
                      />
                    </el-tooltip>
                  </div>
                </div>
              </div>
            </div>
          </template>
        </template>
      </el-table-column>

      <!-- 自检检查结果列 -->
      <el-table-column label="自检检查结果" align="center" fixed="right">
        <el-table-column prop="compliance" label="符合" align="center" width="150">
          <template #default="scope">
            <Compliance
              v-model:radio-value="scope.row.compliance"
              @update:radio-value="triggerValidate()"
              :disabled="operationType !== 'check'"
            />
          </template>
        </el-table-column>
        <el-table-column prop="actualSituation" label="实际情况" align="center" width="410">
          <template #default="scope">
            <ActualSituation
              v-model:actual-situation="scope.row.actualSituation"
              @update:actual-situation="triggerValidate()"
              :disabled="operationType !== 'check'"
              v-if="props.operationType !== 'template'"
            />
            <div
              v-if="props.operationType !== 'template' && safetyJsonParse(scope.row.inspectImages).length > 0"
              class="image-icon"
            >
              <el-tooltip content="图片查看" effect="light">
                <el-image
                  :src="ImageIcon"
                  :zoom-rate="1.2"
                  :max-scale="7"
                  :min-scale="0.2"
                  :preview-src-list="safetyJsonParse(scope.row.inspectImages)"
                  :initial-index="0"
                  show-progress
                  preview-teleported
                  fit="cover"
                />
              </el-tooltip>
            </div>
          </template>
        </el-table-column>
      </el-table-column>
    </el-table>
  </div>
</template>

<script lang="ts" setup>
  import { ref, computed, watch } from 'vue';
  import Compliance from './Compliance.vue';
  import ActualSituation from './ActualSituation.vue';
  import { useUserInfoHook } from '@/views/disaster/hooks';
  import { formatSpanTableData } from '../utils';
  import type { SpanTableData, MainRow, MergedRow } from '../type';
  import type { ContentItem } from '@/types/disaster-precaution';
  import { TASK_TEMPLATE_HEADER, TASK_TEMPLATE_MAIN_COLUMNS, MERGE_FIELDS } from '../constants/template-detail';
  import { COMPLIANCE } from '../constants/template-detail';
  import ImageIcon from '../svg/image.svg';

  const { realname } = useUserInfoHook();

  const props = defineProps<{
    operationType: 'view' | 'approve' | 'check' | 'template';
    mainTable: SpanTableData[];
    opinionData: ContentItem;
    resultData: ContentItem;
  }>();

  // 定义事件
  const emit = defineEmits(['validate-change']);

  // 表单是否有效
  const isValid = ref(false);

  // 创建一个合并的数据源
  const mergedTableData = computed<MergedRow[]>(() => {
    const formattedMainData = formatSpanTableData(props.mainTable).map((item) => ({
      ...item,
      rowType: 'main' as const,
    }));

    // 为底部添加类型标记
    const footerData = [
      {
        rowType: 'footer' as const,
        footerType: 'inspectionAndSelftest' as const, // 合并为一行
        inspectItem: '检查结论及存在问题',
        inspectStandard: '被检查（自查）所/部/中心意见',
        // 这些字段仅用于保持布局，实际输入通过直接绑定props进行
        inspectionResult: '',
        reviewResult: '',
      },
    ];

    return [...formattedMainData, ...footerData];
  });

  // 存储每列的合并状态
  const spanMaps = ref<{ [key: string]: number[][] }>({});

  // 根据列索引获取对应的属性名
  const getPropNameByColumnIndex = (columnIndex: number) => {
    return TASK_TEMPLATE_MAIN_COLUMNS[columnIndex]?.prop || '';
  };

  // 初始化合并信息
  const initSpanMaps = () => {
    const mainData = mergedTableData.value.filter((item): item is MainRow => item.rowType === 'main');
    if (!mainData.length) return;

    MERGE_FIELDS.forEach((field) => {
      // 每个字段用于存储 [行的起始位置, 合并的行数] 的二维数组
      const cellSpans: number[][] = [];
      let currentValue = mainData[0][field];
      let currentIndex = mainData[0].index;
      let startIndex = 0;
      let spanCount = 1;

      for (let i = 1; i < mainData.length; i++) {
        // 只有当当前值与前一个值相同，且index也相同时才合并
        if (mainData[i][field] === currentValue && mainData[i].index === currentIndex) {
          spanCount++;
        } else {
          cellSpans.push([startIndex, spanCount]);
          currentValue = mainData[i][field];
          currentIndex = mainData[i].index;
          startIndex = i;
          spanCount = 1;
        }
      }
      // 处理最后一组数据
      cellSpans.push([startIndex, spanCount]);
      spanMaps.value[field] = cellSpans;
    });
  };

  // 自定义合并方法
  const handleSpanMethod = ({
    row,
    column,
    rowIndex,
    columnIndex,
  }: {
    row: MergedRow;
    column: { property: string };
    rowIndex: number;
    columnIndex: number;
  }) => {
    // 处理底部行
    if (row.rowType === 'footer') {
      if (column.property === 'inspectItem') {
        if (row.footerType === 'inspectionAndSelftest') {
          // 第一个单元格占据左半部分
          return { rowspan: 1, colspan: 3 };
        }
      } else if (column.property === 'inspectStandard' && row.footerType === 'inspectionAndSelftest') {
        // 第二个单元格占据右半部分
        return { rowspan: 1, colspan: 3 };
      }
      // 隐藏其余单元格
      return { rowspan: 0, colspan: 0 };
    }

    // 处理主表数据的合并
    if (row.rowType === 'main') {
      const mainDataStartIndex = mergedTableData.value.findIndex((item) => item.rowType === 'main');
      const adjustedRowIndex = rowIndex - mainDataStartIndex;

      const propName = getPropNameByColumnIndex(columnIndex);

      // 如果不在需要合并的字段列表中，直接返回不合并
      if (!MERGE_FIELDS.includes(propName)) {
        return { rowspan: 1, colspan: 1 };
      }

      // 获取当前字段的合并信息
      const cellSpans = spanMaps.value[propName];
      if (!cellSpans) return { rowspan: 1, colspan: 1 };

      // 查找当前行是否是需要合并的起始行
      for (const [startIndex, spanCount] of cellSpans) {
        if (adjustedRowIndex === startIndex) {
          // 是起始行，显示并合并
          return { rowspan: spanCount, colspan: 1 };
        } else if (adjustedRowIndex > startIndex && adjustedRowIndex < startIndex + spanCount) {
          // 不是起始行，隐藏
          return { rowspan: 0, colspan: 0 };
        }
      }
    }

    return { rowspan: 1, colspan: 1 };
  };

  // 校验规则
  const checkRule = (): boolean => {
    const mainData = mergedTableData.value.filter((item): item is MainRow => item.rowType === 'main');

    // 检查所有行是否都选择了符合项
    const allComplianceSelected = mainData.every((item) => item.compliance !== null && item.compliance !== undefined);

    // 检查所有行是否都填写了实际情况
    const allActualSituationFilled = mainData
      .filter((item) => item.compliance === COMPLIANCE.NOT_ACCORDANCE)
      .every((item) => item.actualSituation && item.actualSituation.trim() !== '');

    // 检查结论是否已填写
    const resultFilled = props.resultData.executeResult && props.resultData.executeResult.trim() !== '';

    // 检查意见是否已填写（如果需要填写的话）
    const opinionFilled =
      props.operationType === 'check' ||
      (props.opinionData.executeResult && props.opinionData.executeResult.trim() !== '');

    // 所有条件都满足时返回true
    return Boolean(allComplianceSelected && allActualSituationFilled && resultFilled && opinionFilled);
  };

  // 触发校验的函数
  const triggerValidate = () => {
    const valid = checkRule();
    isValid.value = valid;
    emit('validate-change', valid);
  };

  const safetyJsonParse = (value: string | string[]) => {
    if (Array.isArray(value)) {
      return value;
    }
    try {
      return JSON.parse(value);
    } catch (error) {
      return [];
    }
  };

  // 监听主表数据变化
  watch(
    () => props.mainTable,
    () => {
      initSpanMaps();
      triggerValidate();
    },
    { immediate: true, deep: true },
  );

  // 监听结论和意见数据变化
  watch(
    () => props.resultData.executeResult,
    () => {
      triggerValidate();
    },
    { immediate: true },
  );

  // 监听意见数据变化
  watch(
    () => props.opinionData.executeResult,
    () => {
      triggerValidate();
    },
    { immediate: true },
  );

  // 获取表格数据的方法，用于父组件通过ref调用
  const getOpinionData = (operationType: 'view' | 'approve' | 'check' | 'template') => {
    if (operationType !== 'approve') {
      return props.opinionData;
    }
    const time = new Date().toLocaleString();
    return {
      executeResult: props.opinionData.executeResult || '',
      inspectTime: time,
      executeName: realname,
    };
  };

  const getResultData = (operationType: 'view' | 'approve' | 'check' | 'template') => {
    if (operationType !== 'check') {
      return props.resultData;
    }
    const time = new Date().toLocaleString();
    return {
      executeResult: props.resultData.executeResult || '',
      inspectTime: time,
      executeName: realname,
    };
  };

  const getTableData = () => {
    // 获取主表数据
    const mainData = mergedTableData.value
      .filter((item): item is MainRow => item.rowType === 'main')
      .map((item) => ({
        id: item.id,
        inspectItem: item.inspectItem,
        inspectStandard: item.inspectStandard,
        inspectMethod: item.inspectMethod,
        compliance: item.compliance,
        actualSituation: item.actualSituation,
        inspectImages: item.inspectImages,
        index: item.index,
      }));

    return {
      mainTable: mainData,
      opinionData: getOpinionData(props.operationType),
      resultData: getResultData(props.operationType),
    };
  };

  // 暴露方法给父组件，使其可以通过ref调用
  defineExpose({
    getTableData,
  });
</script>

<style lang="scss" scoped>
  .el-table-page {
    width: 100%;
    height: 100%;
  }

  .inspection-result--div {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 5px;
    padding: 5px;
    height: 120px;
  }

  .inspection-result--title {
    font-weight: 600;
    color: $text-color;
  }

  :deep(.custom-table th) {
    background-color: $white-color !important;
    font-weight: 400 !important;
  }
  .inspection-result-approve {
    width: 100%;
    height: 80px;
    .execute-result {
      text-align: left;
      width: 100%;
      height: 60%;
      max-height: 60%;
      overflow: auto;
    }
    .execute-person {
      @include flex-center;
      justify-content: space-between;
      width: 100%;
      flex: 1;
    }
    :deep(.el-tooltip__trigger) {
      display: flex;
      align-items: center;
    }
  }
  .image-icon {
    margin-top: 10px;
    cursor: pointer;
  }
</style>
