<template>
  <div style="height: 84vh; margin: 0px 0px; background-color: #fff">
    <vxe-grid ref="tableRef" :row-config="{ isCurrent: true, isHover: true }" v-bind="gridOptions" @filter-change="filterChangeEvent">
      <template #toolbar_buttons>
        <a-space wrap>
          <a-button type="link" block @click="handleChangeLeftWidth">
            <menuUnfoldOutlined v-if="collapsed" class="trigger" />
            <MenuFoldOutlined v-else class="trigger" />
          </a-button>
        </a-space>
        <div style="margin-left: 50px">
          <span>全表搜索：</span>
          <vxe-input v-model="searchText" placeholder="搜索" style="width: 300px" />
          <vxe-button mode="text" status="primary" @click="searchEvent()">搜索</vxe-button>
          <vxe-button mode="text" status="primary" @click="refreshEvent()">刷新</vxe-button>
        </div>
        <div style="margin-left: 50px">
          <vxe-button mode="text" status="primary" @click="showProject()">返回项目列表</vxe-button>
          <vxe-button mode="text" status="primary" @click="scriptToExcel()">导出底稿</vxe-button>
          <vxe-button mode="text" status="primary" @click="listToExcel()">导出问题清单</vxe-button>
          <vxe-button mode="text" status="primary" @click="showReportDrawer()">报告管理</vxe-button>
        </div>
      </template>

      <template #caName_default="{ row }">
        <template v-for="(item, ind) in row.actNames?.split(',')" :key="ind">
          <div v-html="item" @click="searchEventByAct(item)"></div>
        </template>
      </template>

      <template #cgrpPath_default="{ row }">
        <template v-for="(item, ind) in row.cgrpPath?.split('/')" :key="ind">
          <div v-html="item"></div>
        </template>
      </template>

      <template #operate="{ row }">
        <vxe-button status="primary" mode="text" size="small" content="查看详情" @click="setProjectItem(row)" />
      </template>

      <template #pager>
        <vxe-pager
          v-show="gridOptions.pagerConfig.enabled"
          :layouts="['Sizes', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'FullJump', 'Total']"
          v-model:current-page="tablePage.currentPage"
          v-model:page-size="tablePage.pageSize"
          v-model:page-sizes="tablePage.pageSizes"
          :total="tablePage.total"
          @page-change="handlePageChange"
        />
      </template>
    </vxe-grid>

    <ProjectReportDrawer
      v-model:visible="drawerVisible"
      :check-data="checkData"
      :project="curProject"
      @update:visible="(val) => (drawerVisible = val)"
    />
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, nextTick, computed } from 'vue';
  import { VxeGridProps } from 'vxe-table';
  import { message } from 'ant-design-vue';
  import { defHttp } from '/@/utils/http/axios';
  import { useModal } from '/@/components/Modal';
  import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue';
  import { getDictItemsByCode } from '/@/utils/dict/index';
  import { getProjectItems } from '../AuditProjectItem.api';
  import { queryAllReports } from '/@/views/newlib/components/api/AuditTaskReport.api';
  import { exportCheckDataToExcel } from './script-export';
  import { exportListDataToExcel } from './problem-export';
  import ProjectReportDrawer from './ProjectReportDrawer.vue';

  const getProjectChecksForUser = '/audit/auditProject/getProjectChecksForUser';
  const tableRef = ref();
  const collapsed = ref(false);
  const tableData = ref([]);
  const oldData = ref([]);
  const curProject = ref();
  const fileList = ref();
  const cgrpList = ref();
  const actList = ref([]);
  const searchText = ref();
  const drawerVisible = ref(false);
  const checkData = ref([]);

  const emit = defineEmits(['callback', 'setLeftWidth', 'setFileList', 'showProject']);

  interface RowVO {
    id: number;
    item: string;
    fileName: string;
    realname: string;
    itemNum: number;
    caNames: string;
  }

  const nameFilterRender = {
    name: 'VxeInput',
  };

  function textFilterMethod({ option, row, column }) {
    if (option.data) {
      return `${row[column.field]}`.indexOf(option.data) > -1;
    }
    return true;
  }

  const fileFilterMethod = ({ value, row }) => {
    return row['fileId'] == value;
  };

  const cgrpPathFilterMethod = ({ value, row }) => {
    return row['cgrp'] == value;
  };

  const gridOptions = reactive<VxeGridProps<RowVO>>({
    border: true,
    stripe: true,
    showFooter: true,
    height: 'auto',
    tooltipConfig: {},
    exportConfig: {},
    menuConfig: {},
    columnConfig: {
      resizable: true,
      useKey: true,
    },
    rowConfig: {
      resizable: true,
      useKey: true,
    },
    checkboxConfig: {
      highlight: true,
      checkStrictly: false,
    },
    pagerConfig: {
      enabled: true,
      pageSize: 10,
    },
    toolbarConfig: {
      zoom: true,
      custom: true,
      export: false,
      slots: {
        buttons: 'toolbar_buttons',
      },
    },
    columns: [
      { type: 'checkbox', visible: true, width: '50', showOverflow: false },
      {
        field: 'content',
        title: '检查项',
        sortable: true,
        filters: [{ data: '' }],
        filterMethod: textFilterMethod,
        filterRender: nameFilterRender,
        type: 'html',
      },
      {
        field: 'actNames',
        title: '控制项',
        sortable: true,
        width: '15%',
        visible: true,
        type: 'html',
        slots: { default: 'caName_default' },
        filters: [{ data: '' }],
        filterMethod: textFilterMethod,
        filterRender: nameFilterRender,
      },
      {
        field: 'item',
        title: '合规条目',
        showOverflow: 'title',
        sortable: true,
        filters: [{ data: '' }],
        filterMethod: textFilterMethod,
        filterRender: nameFilterRender,
        width: '15%',
        visible: true,

        type: 'html',
      },
      {
        field: 'cgrpPath',
        title: '分组',
        sortable: true,
        width: '12%',
        visible: true,
        type: 'html',
        filters: [],
        slots: { default: 'cgrpPath_default' },
        filterMethod: cgrpPathFilterMethod,
        filterMultiple: true,
      },
      {
        field: 'fileName',
        title: '参考文件',
        showOverflow: 'title',
        sortable: true,
        width: '13%',
        type: 'html',
        filters: [],
        filterMethod: fileFilterMethod,
        filterMultiple: true,
      },
      { title: '操作', align: 'center', width: '10%', visible: true, fixed: 'right', slots: { default: 'operate' } },
    ],
    data: [],
  });

  const tablePage = reactive({
    total: 0,
    currentPage: 1,
    pageSize: 10,
    pageSizes: [10, 30, 50, 100, 300, 500, 1000],
  });

  const handlePageChange = async ({ currentPage, pageSize }) => {
    tablePage.currentPage = currentPage || 1;
    tablePage.pageSize = pageSize || 10;
    tablePage.total = tableData.value.length;
    let st = (tablePage.currentPage - 1) * tablePage.pageSize;
    let end = st + tablePage.pageSize;
    gridOptions.data = tableData.value.slice(st, end);
  };

  const refreshEvent = async () => {
    await iniData(curProject.value, '');
    searchText.value = '';
    const $grid = tableRef.value;
    if ($grid) {
      $grid.clearFilter();
    }
  };

  async function iniData(project, srhName) {
    curProject.value = project;
    gridOptions.loading = true;

    searchText.value = '';
    const $grid = tableRef.value;
    $grid?.clearFilter();
    oldData.value = tableData.value = await defHttp.get({ url: getProjectChecksForUser, params: { id: project?.id, itemName: srhName } });
    gridOptions.loading = false;
    await Promise.all([setCgrpList(), setFileList(), updatePage(), setActList()]);
    emit('setFileList', fileList.value, actList.value);
  }

  async function setCgrpList() {
    cgrpList.value = [...new Set(tableData.value.map((item) => item.cgrp))].map((cgrp) => ({
      value: cgrp,
      label: tableData.value.find((item) => item.cgrp === cgrp).cgrpPath, // 提取对应的 cgrpPath
    }));
    const $table = tableRef.value;
    if ($table) {
      $table.setFilter('cgrpPath', cgrpList.value);
    }
  }

  function handleChangeLeftWidth() {
    collapsed.value = !collapsed.value;
    emit('setLeftWidth', collapsed.value);
  }

  // async function onAllocTask(user) {
  //   let params = { userid: user.id,projectid:curProject.value.id};
  //   params['ids'] = await getSelectIds();
  //   if (params['ids'].length == 0) {
  //     VXETable.modal.message({ content: '请选择记录', status: 'warning' });
  //     return;
  //   }

  //   await defHttp.post({url:saveProjectAssign,params});
  //   await iniData(curProject.value,"");
  // }

  async function getSelectIds() {
    let ids = [];
    const $table = tableRef.value;
    if ($table) {
      const selRecords = $table.getCheckboxRecords();
      selRecords.forEach(function (ele) {
        ids.push(ele.id);
      });
    }
    return ids;
  }

  async function filterChangeEvent({ field, values, datas }) {
    if (values.length == 0 && datas.length === 0) {
      gridOptions.data = tableData.value = oldData.value;
      await updatePage();
      return;
    }

    field = field === 'cgrpPath' ? 'cgrp' : field === 'fileName' ? 'fileId' : field;

    if (field == 'fileId' || field == 'cgrp') {
      tableData.value = oldData.value.filter((item) => values.includes(item[field]));
    } else {
      tableData.value = oldData.value.filter((item) =>
        datas.some((data) => {
          const itemField = item[field];
          return itemField && typeof itemField === 'string' ? itemField.includes(data) : itemField === null && data === null;
        })
      );
    }
    const promises = [updatePage()];
    if (field === 'fileId') {
      promises.push(setCgrpList());
    }
    await Promise.all(promises);
  }

  async function updatePage() {
    await handlePageChange({ currentPage: 1, pageSize: tablePage.pageSize });
  }

  const searchEvent = async () => {
    const filterSrhTxt = searchText.value.trim().toLowerCase();
    if (filterSrhTxt) {
      const filterRE = new RegExp(filterSrhTxt, 'gi');
      const searchProps = ['content', 'fileName', 'item', 'cgrpPath', 'complineContent', 'actNames'];
      tableData.value = oldData.value
        .filter((item) => searchProps.some((key) => String(item[key]).toLowerCase().includes(filterSrhTxt)))
        .map((row) => {
          const item = { ...row }; // Shallow copy
          searchProps.forEach((key) => {
            item[key] = String(item[key]).replace(filterRE, (match) => `<span class="keyword-lighten" style="color:red">${match}</span>`);
          });
          return item;
        });
    } else {
      tableData.value = [...oldData.value]; // Reset to old data
    }
    await handlePageChange({ currentPage: 1, pageSize: tablePage.pageSize });
  };

  function setProjectItem(row) {
    emit('callback', row);
  }

  const setFileList = async () => {
    const uniqueFileList = Array.from(new Map(tableData.value.map((item) => [item.fileId, { value: item.fileId, label: item.fileName }])).values());
    fileList.value = uniqueFileList;
    const $table = tableRef.value;
    if ($table) {
      $table.setFilter('fileName', fileList.value);
    }
  };

  const setActList = async () => {
    const actMap = {};
    actList.value = [];
    tableData.value.forEach((item) => {
      if (item.actIds && item.actNames) {
        const ids = item.actIds.split(',').map((id) => id.trim());
        const names = item.actNames.split(',').map((name) => name.trim());
        ids.forEach((id, index) => {
          const name = names[index];
          if (!actMap[id]) {
            actMap[id] = true;
            actList.value.push({ id: id, name: name });
          }
        });
      }
    });
  };

  const shwoFileData = async (data) => {
    const $table = tableRef.value;
    if ($table) {
      const column = $table.getColumnByField('fileName');
      if (column) {
        column.filters.forEach((element) => {
          element.checked = false;
        });
        const option = column.filters.find((item) => item.value === data.value);
        if (option) {
          option.checked = true;
        }
        await $table.updateData();
        await filterChangeEvent({ field: 'fileName', datas: [], values: [data.value] });
      }
    }
  };

  const shwoActData = async (data) => {
    const $table = tableRef.value;
    if ($table) {
      const column = $table.getColumnByField('actNames');
      if (column) {
        column.filters[0].data = data.name;
        column.filters[0].checked = true;
        await $table.updateData();
        await filterChangeEvent({ field: 'actNames', datas: [data.name], values: [] });
      }
    }
  };

  function showProject() {
    fileList.value = [];
    actList.value = [];
    emit('showProject', true);
  }

  async function searchEventByAct(actName) {
    const textOnly = actName.replace(/<[^>]*>/g, '');
    searchText.value = textOnly;
    await searchEvent();
  }

  const clearFilter = async () => {
    try {
      searchText.value = '';
      const $table = tableRef.value;
      if ($table) {
        await $table.clearFilter();
      }
      gridOptions.data = tableData.value = oldData.value || [];
      await updatePage();
    } catch (error) {
      console.error('Error during clearing filter: ', error);
    }
  };

  const searchByItemName = async (srhName) => {
    await iniData(curProject.value, srhName);
  };

  //导出数据格式化
  function mergeData(allData, groupedData, reps, tpOptions) {
    // 创建tp值到中文的映射
    const tpMap = {};
    tpOptions.forEach((option) => {
      tpMap[option.value] = option.text;
    });

    return allData.map((item) => {
      const checkid = item.checkid;
      const matchedChecks = groupedData[checkid] || [];
      const checkItems = matchedChecks.map((check) => {
        const repKey = Object.keys(reps).find((key) => reps[key].checkid === checkid && reps[key].checkItemId === check.id);
        const rep = repKey ? reps[repKey] : null;

        // 将tp转换为中文分类
        const tpText = tpMap[check.tp.toString()] || check.tp.toString();

        return {
          name: check.name,
          tp: tpText, // 使用转换后的中文分类
          issues: rep ? rep.issues || '' : '',
          situation: rep ? rep.situation || '' : '',
        };
      });

      return {
        cgrpPath: item.cgrpPath,
        content: item.content,
        item: item.item,
        checkid: checkItems,
      };
    });
  }

  //导出审计底稿
  const scriptToExcel = async () => {
    try {
      gridOptions.loading = true;
      const allData = tableData.value;
      const ids = allData.map((item) => {
        return {
          pid: item.projectid,
          checkid: item.checkid,
        };
      });
      const pid = { pid: ids[0].pid };
      const pitems = await getProjectItems(pid);

      // 按checkid分组数据
      const groupedData = pitems.reduce((acc, item) => {
        if (!acc[item.checkid]) {
          acc[item.checkid] = [];
        }
        acc[item.checkid].push(item);
        return acc;
      }, {});

      //问题和现状
      const reports = await queryAllReports(pid);
      //分类
      const tpOptions = await getDictItemsByCode('check_item_tp');
      const mergedData = mergeData(allData, groupedData, reports, tpOptions);
      //导出
      exportCheckDataToExcel(mergedData, `${curProject.value.name}底稿.xlsx`);
      message.success('导出成功');
    } catch (error) {
      message.error('导出失败:');
    } finally {
      gridOptions.loading = false;
    }
  };

  //导出问题清单
  const listToExcel = async () => {
    try {
      gridOptions.loading = true;
      const allData = tableData.value;
      const ids = allData.map((item) => {
        return {
          pid: item.projectid,
          checkid: item.checkid,
        };
      });
      const pid = { pid: ids[0].pid };
      const pitems = await getProjectItems(pid);

      // 按checkid分组数据
      const groupedData = pitems.reduce((acc, item) => {
        if (!acc[item.checkid]) {
          acc[item.checkid] = [];
        }
        acc[item.checkid].push(item);
        return acc;
      }, {});

      //问题和现状
      const reports = await queryAllReports(pid);
      //分类
      const tpOptions = [];
      const mergedData = mergeData(allData, groupedData, reports, tpOptions);
      //导出
      exportListDataToExcel(mergedData, `${curProject.value.name}问题清单.xlsx`);
      message.success('导出成功');
    } catch (error) {
      message.error('导出失败:');
    } finally {
      gridOptions.loading = false;
    }
  };

  // 报告管理
  async function fetchAndFlattenData() {
    try {
      // 获取三组数据
      const allData = tableData.value;
      const ids = allData.map((item) => {
        return {
          pid: item.projectid,
          checkid: item.checkid,
        };
      });
      const pid = { pid: ids[0].pid };
    
      const group2 = await getProjectItems(pid); // 第二组数据：子检查项信息

      const group3 = await queryAllReports(pid); // 第三组数据：实际情况、问题等

      console.log(group2,"group2")
      console.log(group3,"group3")

      const tpOptions = await getDictItemsByCode('check_item_tp');
      const tpMap = {};
      tpOptions.forEach((option) => {
        tpMap[option.value] = option.text;
      });
      // 扁平化处理数据

      const flatList: { [key: string]: any }[] = [];

      for (const row of allData) {
        // 过滤出与当前 checkid 匹配的子检查项（第二组数据）
        const subChecks = group2.filter((sub) => sub.checkid === row.checkid);

        for (const sub of subChecks) {
          const subId = String(sub.id); // group3 中是字符串 key
          const extra = group3[subId] || {}; // 获取第三组数据中的详细信息

          const tpText = tpMap[sub.tp.toString()] || '其他';
          flatList.push({
            id: extra.id,
            cgrpPath: row.cgrpPath,
            content: row.content,
            item: row.item,
            name: sub.name,
            tp: tpText,
            projectid:pid.pid,
            checkItemId:sub.id,
            checkItemTp:sub.tp,
            issues: extra.issues || '',
            situation: extra.situation || '',
            checkid:sub.checkid
          });
        }
      }
      return flatList;
    } catch (error) {
      console.error('数据获取或处理失败:', error);
      return [];
    }
  }
  const showReportDrawer = async () => {
    drawerVisible.value = true;
    const result = await fetchAndFlattenData(); // 请求数据
    checkData.value = result;
  };

  defineExpose({
    iniData,
    shwoFileData,
    shwoActData,
    clearFilter,
    searchByItemName,
  });
</script>
