<!--
 * Ag Grid 表格树 文件浏览器例子
 * https://www.ag-grid.com/vue-data-grid/tree-data/#file-browser-example
 -->
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { date } from 'quasar';
import { AgGridVue } from 'ag-grid-vue3';
import { useMessage } from 'src/common/hooks';
import AG_GRID_LOCALE from 'src/config/ag-grid-locale';
import { getData2 } from '../config';

const defaultColDef = {
  flex: 1,
  filter: true,
  sortable: true,
  resizable: true,
  suppressMenu: true,
};

const { warn } = useMessage();

const gridApi = ref<any>(null);
const gridColumnApi = ref<any>(null);

const state = reactive({
  columnDefs: [
    {
      field: 'dateModified',
      headerName: '修改时间',
      minWidth: 250,
      comparator: (d1: any, d2: any) => {
        return new Date(d1).getTime() < new Date(d2).getTime() ? -1 : 1;
      },
      valueFormatter: (params: any) => {
        const timeStamp = new Date(params.value);
        return date.formatDate(timeStamp, 'YYYY-MM-DD HH:mm:ss');
      },
    },
    {
      field: 'size',
      headerName: '大小',
      aggFunc: 'sum',
      valueFormatter: (params: any) => {
        return params.value
          ? Math.round(params.value * 10) / 10 + ' MB'
          : '0 MB';
      },
    },
  ],
  rowData: [] as any,
});

const autoGroupColumnDef = reactive({
  headerName: '文件',
  minWidth: 330,
  cellRendererParams: {
    checkbox: true,
    suppressCount: true,
    innerRenderer: getFileCellRenderer(),
  },
});

onMounted(() => {
  setTimeout(() => {
    state.rowData = getData2();
    console.log('rowData', state.rowData);
  }, 1000);
});

function onGridReady(params: any) {
  gridApi.value = params.api;
  gridColumnApi.value = params.columnApi;
}

function getDataPath(data: any) {
  return data.filePath;
}

function getRowId(params: any) {
  return params.data.id;
}

function addNewGroup() {
  const newGroupData = [
    {
      id: getNextId(),
      filePath: ['Music', 'wav', 'hit_' + new Date().getTime() + '.wav'],
      dateModified: new Date(),
      size: 58.9,
    },
  ];
  gridApi.value.applyTransaction({ add: newGroupData });
}

function moveSelectedNodeToTarget(targetRowId: any) {
  console.log('moveSelectedNodeToTarget', targetRowId);
  let selectedNode = gridApi.value.getSelectedNodes()[0]; // single selection
  if (!selectedNode) {
    warn('没有选择节点！');
    return;
  }
  let targetNode = gridApi.value.getRowNode(targetRowId);
  if (!targetNode) {
    warn('目标文件不存在！');
    return;
  }
  let invalidMove =
    selectedNode.key === targetNode.key ||
    isSelectionParentOfTarget(selectedNode, targetNode);
  if (invalidMove) {
    warn('无效选择 - 不能是父级或与目标相同！');
    return;
  }
  let rowsToUpdate = getRowsToUpdate(selectedNode, targetNode.data.filePath);
  gridApi.value.applyTransaction({ update: rowsToUpdate });
}

function removeSelected() {
  let selectedNode = gridApi.value.getSelectedNodes()[0]; // single selection
  if (!selectedNode) {
    warn('没有选择节点！');
    return;
  }
  gridApi.value.applyTransaction({ remove: getRowsToRemove(selectedNode) });
}

function getFileCellRenderer() {
  class FileCellRenderer {
    init(params: any) {
      let tempDiv = document.createElement('div');
      let value = params.value;
      let icon = getFileIcon(params.value);
      tempDiv.innerHTML = icon
        ? '<span><i class="' +
          icon +
          '" style="font-size: 16px"></i>' +
          '&nbsp;' +
          '<span class="filename"></span>' +
          value +
          '</span>'
        : value;
      const that: any = this;
      that.eGui = tempDiv.firstChild;
    }
    getGui() {
      const that: any = this;
      return that.eGui;
    }
    refresh() {
      return false;
    }
  }
  return FileCellRenderer;
}

function getFileIcon(name: any) {
  return endsWith(name, '.mp3') || endsWith(name, '.wav')
    ? 'far fa-file-audio'
    : endsWith(name, '.xls')
    ? 'far fa-file-excel'
    : endsWith(name, '.txt')
    ? 'far fa-file'
    : endsWith(name, '.pdf')
    ? 'far fa-file-pdf'
    : 'far fa-folder';
}

function endsWith(str: any, match: any) {
  let len;
  if (str == null || !str.length || match == null || !match.length) {
    return false;
  }
  len = str.length;
  return str.substring(len - match.length, len) === match;
}

function getNextId() {
  const _window: any = window;
  if (!_window.nextId) {
    _window.nextId = 15;
  } else {
    _window.nextId++;
  }
  return _window.nextId;
}

function isSelectionParentOfTarget(selectedNode: any, targetNode: any) {
  let children = selectedNode.childrenAfterGroup || [];
  for (let i = 0; i < children.length; i++) {
    if (targetNode && children[i].key === targetNode.key) return true;
    isSelectionParentOfTarget(children[i], targetNode);
  }
  return false;
}

function getRowsToUpdate(node: any, parentPath: any) {
  let res: any = [];
  let newPath = parentPath.concat([node.key]);
  if (node.data) {
    // groups without data, i.e. 'filler groups' don't need path updated
    // 没有数据的组，即“填充组”不需要更新路径
    node.data.filePath = newPath;
  }
  let children = node.childrenAfterGroup || [];
  for (let i = 0; i < children.length; i++) {
    let updatedChildRowData = getRowsToUpdate(children[i], newPath);
    res = res.concat(updatedChildRowData);
  }
  // ignore nodes that have no data, i.e. 'filler groups'
  // 忽略没有数据的节点，即“填充组”
  return node.data ? res.concat([node.data]) : res;
}

function getRowsToRemove(node: any) {
  let res: any = [];
  const children = node.childrenAfterGroup || [];
  for (let i = 0; i < children.length; i++) {
    res = res.concat(getRowsToRemove(children[i]));
  }
  // ignore nodes that have no data, i.e. 'filler groups'
  // 忽略没有数据的节点，即“填充组”
  return node.data ? res.concat([node.data]) : res;
}
</script>
<template>
  <div class="box">
    <div class="btns">
      <q-btn
        color="primary"
        label="在Music下添加一个新组"
        no-caps
        @click="addNewGroup"
      />
      <q-btn
        color="primary"
        label="移动到stuff文件夹中"
        no-caps
        @click="moveSelectedNodeToTarget('9')"
      />
      <q-btn
        color="primary"
        label="删除所选组和它的子组"
        no-caps
        @click="removeSelected"
      />
    </div>
    <!-- 
        rowSelection="multiple"：多选，按住control键多选；【control+shift+鼠标点击】可选中多行
        animateRows=true：启用行动画
        :masterDetail="true" 启用展开的细节网格行
        :isRowMaster="isRowMaster" 确定哪一个行该展开
     -->
    <div class="ag-table">
      <ag-grid-vue
        style="height: 500px"
        class="ag-theme-alpine"
        :localeText="AG_GRID_LOCALE"
        :columnDefs="state.columnDefs"
        :rowData="state.rowData"
        :defaultColDef="defaultColDef"
        :animateRows="true"
        :pagination="true"
        :paginationPageSize="5"
        @grid-ready="onGridReady"
        :treeData="true"
        :getDataPath="getDataPath"
        :getRowId="getRowId"
        :autoGroupColumnDef="autoGroupColumnDef"
        :groupDefaultExpanded="-1"
      >
      </ag-grid-vue>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.btns {
  padding: 10px;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  column-gap: 10px;
}
.ag-table {
  padding: 0 10px 10px 10px;
}
</style>
