<template>
  <div style="height:100%; 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-button type="link" block @click="handleAssinTask()">分配任务</a-button>
          <a-button type="link" block @click="handleDeleteAssinTask()">清除分配</a-button>
        </a-space>

        <div style="margin-left: 50px">
          <span>全表搜索：</span>
          <vxe-input v-model="searchText" placeholder="搜索" style="width: 250px" />
          <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()">返回项目列表[{{curProject?.name}}]</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 #filluser_default="{ row }">
          <div style="color:blue" v-html="row.realname"></div>
      </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>
    <UserList ref="refUserList" @callBack="onAllocTask" />
  </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 UserList from './UserList.vue';
  import { useMessage } from "/@/hooks/web/useMessage";
  import { MenuUnfoldOutlined, MenuFoldOutlined} from '@ant-design/icons-vue';

  const saveProjectAssign = '/audit/auditTask/saveProjectAssign';
  const getProjectChecks = '/audit/auditProject/getProjectChecks';
  const deleteAssignBatch = '/audit/auditTask/deleteAssignBatch';

  const { createConfirm } = useMessage();

  const collapsed = ref(false);  
  const tableRef = ref();
  const refUserList = ref();

  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: '14%',
        visible: true,
        type: 'html',
      },
      {
        field: 'cgrpPath', 
        title: '分组', 
        sortable: true, 
        width: '13%',
        visible: true,
        type:'html',
        slots: { default: 'cgrpPath_default' },
        filters:  [],
        filterMethod: cgrpPathFilterMethod,
        filterMultiple: true,
      },
      {
        field: 'fileName',
        title: '参考文件',
        showOverflow: 'title',
        sortable: true,
        width: '13%',
        type:"html",
        filters:  [],
        filterMethod: fileFilterMethod,
        filterMultiple: true,
      },
      { 
        field: 'realname', 
        title: '填报人', 
        sortable: true, 
        width: '8%', 
        visible: true, 
        filterMultiple: true,
        slots: { default: 'filluser_default' },
      },
    ],
    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,"");
  };

  async function iniData(project,srhName) {

    curProject.value = project;
    gridOptions.loading = true;

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

  async function setFileList() {  
    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);  
    }  
  }

  async function setActList() {  
    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 });  
              }  
          });
        }  
    }) 
  }

  
  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 handleAssinTask() {
    refUserList.value.iniData();
  }

  const handleDeleteAssinTask = async () => {
    let idsAry = await getSelectIds();
    if (idsAry.length == 0) {
      VXETable.modal.message({ content: '请选择记录', status: 'warning' });
      return;
    }

    let params = { ids: idsAry.join(',') };
    createConfirm({
      iconType: 'warning',
      title: '确认删除分配',
      content: '是否删除分配',
      okText: '确认',
      cancelText: '取消',
      onOk: () => {
        return defHttp.get({ url: deleteAssignBatch, params }).then(() => {
          iniData(curProject.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,null);
  }

  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 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 }; 
        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]; 
    }  
    await handlePageChange({ currentPage: 1, pageSize: tablePage.pageSize });  
  }

  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: []});  
      }
    }
  }


  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 searchEventByAct(actName) {
    const textOnly = actName.replace(/<[^>]*>/g, ''); 
    searchText.value = textOnly
    await searchEvent()
  }

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

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


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>
