<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: 150px">
          <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: 150px">
          <vxe-button mode="text" status="primary" @click="showProject()">返回项目列表</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>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, nextTick } from 'vue';
  import { VxeGridProps, VXETable } from 'vxe-table';
  import { defHttp } from '/@/utils/http/axios';
  import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-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 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: true,
      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) {
    if (!project || !project.id) {
      console.error('Invalid project data:', project);
      return;
    }
    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);
  };

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