<template>
  <div style="height: 100%; margin: 0px 0px; background: #f2f2f2">
    <a-row :gutter="1">
      <a-col class="gutter-row" :span="leftWidth">
        <div class="layout">
          <TaskLeft ref="refTaskLeft" @showProject="showProject" @fileCallback="fileCallback" @actCallback="actCallback" @clearFilter="clearFilter" />
        </div>
      </a-col>
      <a-col class="gutter-row" :span="24 - leftWidth">
        <div class="layout">
          <vxe-grid ref="tableRef" @filter-change="filterChangeEvent" :row-config="{ isCurrent: true, isHover: true }" v-bind="gridOptions">
            <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: 0px 10px">
                <span style="line-height: 30px">全表搜索：</span>
                <vxe-input v-model="searchText" placeholder="搜索" style="width: 300px" />
                <vxe-button status="primary" @click="searchEvent()">搜索</vxe-button>
                <vxe-button @click="refreshEvent()">刷新</vxe-button>
              </div>
              <a-radio-group v-model:value="libValue" @change="handleChange">
                <a-radio-button value="2" @click="reloadRuleLib">合规库</a-radio-button>
                <a-radio-button value="3" @click="reloadInnerLib">内控库</a-radio-button>
              </a-radio-group>
            </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 #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>
      </a-col>
    </a-row>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, nextTick } from 'vue';
  import { VxeGridProps } from 'vxe-table';
  import { defHttp } from '/@/utils/http/axios';
  import TaskLeft from './TaskLeft.vue';
  import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue';

  const checkUrl = '/audit/auditCheckMethod/findAllChecks';
  const checInnerUrl = '/audit/auditInnerCheckmethod/findAllInnerOrderChecks';

  const tableRef = ref();
  const emit = defineEmits(['callback', 'setLeftWidth', 'addProjectCheck', 'setFileList']);
  const libValue = ref("2");
  const tableData = ref([]);
  const oldData = ref([]);
  const searchText = ref();
  const fileList = ref([]);
  const cgrpList = ref([]);
  const curProject = ref();
  const collapsed = ref(false);

  const actList = ref([]);
  const isShowProject = ref(true);
  const leftWidth = ref(6);
  const refTaskLeft = ref();
  const existCheckIds = ref([]);

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

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

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

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

  const gridOptions = reactive<VxeGridProps>({
    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,
      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: 'item',
        title: '合规条目',
        showOverflow: 'title',
        sortable: true,
        filters: [{ data: '' }],
        filterMethod: textFilterMethod,
        filterRender: nameFilterRender,
        width: 200,
        visible: true,
        type: 'html',
      },
      {
        field: 'complineContent',
        title: '合规内容',
        width: 400,
        visible: false,
        type: 'html',
        filters: [{ data: '' }],
        filterMethod: textFilterMethod,
        filterRender: nameFilterRender,
      },
      {
        field: 'cgrpPath',
        title: '分组',
        sortable: true,
        width: 200,
        visible: true,
        type: 'html',
        filters: [],
        filterMethod: cgrpPathFilterMethod,
        filterMultiple: true,
      },
      {
        field: 'actNames',
        title: '控制项',
        sortable: true,
        width: 200,
        visible: true,
        type: 'html',
        slots: { default: 'caName_default' },
        filters: [{ data: '' }],
        filterMethod: textFilterMethod,
        filterRender: nameFilterRender,
      },
      {
        field: 'fileName',
        title: '参考文件',
        sortable: true,
        width: 200,
        visible: true,
        type: 'html',
        filters: [],
        filterMethod: fileFilterMethod,
        filterMultiple: true,
      },
    ],
    data: [],
    loading: false,
  });

  const refreshEvent = async () => {
    await iniData(curProject.value, existCheckIds.value);
    nextTick(async () => {
      await setExistRecord();
    });
  };

  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);
    await setExistRecord();
  };

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


    searchText.value = '';
    const $grid = tableRef.value;
    $grid?.clearFilter();

    await nextTick(async () => {

      let check = {};
      let curUrl = libValue.value=="2"?checkUrl:checInnerUrl;
      oldData.value = tableData.value = await defHttp.get({ url: curUrl, params: check });
      gridOptions.loading = false;
      await handlePageChange({ currentPage: 1, pageSize: 10 });

      await setFileList();
      await setCgrpList();
      await setActList();

      const $table = tableRef.value;
      if ($table) {
        $table.setFilter('fileName', fileList.value);
        $table.setFilter('cgrpPath', cgrpList.value);
      }
      await refTaskLeft.value.iniData(curProject.value, fileList.value, actList.value);
    });
  }

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

  const setCgrpList = async () => {
    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);
    }
  };

  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 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 });
  };

  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());
    }

    // if (field === "actNames") {
    //   promises.push(setFileList());
    // }
    await Promise.all(promises);
  }

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

  const showProject = async () => {
    isShowProject.value = true;
  };

  const fileCallback = async (fileData) => {
    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 === fileData.value);
        if (option) {
          option.checked = true;
        }
        await $table.updateData();
        await filterChangeEvent({ field: 'fileName', datas: [], values: [fileData.value] });
      }
    }
  };

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

  function handleChangeLeftWidth() {
    collapsed.value = !collapsed.value;
    leftWidth.value = collapsed.value ? 0 : 6;
  }

  async function searchEventByAct(actName) {
    searchText.value = actName;
    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 curPageExist = ref([]);

  const setExistRecord = async () => {
    const $table = tableRef.value;
    if (existCheckIds.value.length == 0) return;
    if (gridOptions.data.length == 0) return;

    if ($table) {
      curPageExist.value = existCheckIds.value.map((checkId) => gridOptions.data.find((data) => data.checkid === checkId)).filter(Boolean);
      nextTick(() => {
        $table.setCheckboxRow(curPageExist.value, true);
      });
    }
  };

  async function getSelectIds() {
    let checkids = [];
    const $table = tableRef.value;
    if ($table) {
      const selRecords = $table.getCheckboxRecords();
      selRecords.forEach(function (ele) {
        if (!ele.isPublic) {
          checkids.push(ele.checkid);
        }
      });
    }

    let exitCheckIds = curPageExist.value.map((item) => item.checkid);
    const delIds = exitCheckIds.filter((item) => !checkids.includes(item));
    const newIds = checkids.filter((item) => !exitCheckIds.includes(item));
    const comeFrom = libValue.value*1;
    return { delIds: delIds, newIds: newIds,comeFrom:comeFrom};
  }
  // 增加从内控库添加
  function handleChange(e) {
    libValue.value = e.target.value;
    if (libValue.value == 'a') {
      console.log('合规库');
    } else {
      console.log('内控库');
    }
  }


  async function reloadRuleLib() {
    libValue.value = "2"
    await iniData(curProject.value, existCheckIds.value) 
  }

  async function reloadInnerLib() {
    libValue.value = "3"
    await iniData(curProject.value,existCheckIds.value) 
  }

  defineExpose({
    iniData,
    getSelectIds,
  });
</script>

<style scope>
  .layout {
    background: #fff;
    margin: 5px;
    overflow: hidden;
    height: 85vh;
  }
</style>
