<template>
  <div class="file-manager">
    <div class="file-manager__toolbar">
      <input class="file-manager__search" type="search" placeholder="search" v-model="search">
      <button
        @click="buildIndex"
        :disabled="buildingIndex"
      >
        <template v-if="buildingIndex">building {{ indexCounter }}</template>
        <template v-else>Build Index</template>
      </button>
    </div>
    <div class="file-manager__files">
      <ul
        v-if="searchResults.length > 0"
        class="file-manager-dir"
      >
        <FileManagerFile
          v-for="file in searchResults"
          :key="file.name"
          :file="file"
          @openFile="$emit('openFile', $event)"
          @filePreview="onFilePreview"
        />
      </ul>
      <ul
        v-else
        class="file-manager-dir"
      >
        <FileManagerDir
          v-for="dir in fs.root"
          :key="dir.name"
          :fs="fs"
          :dir="dir"
          @openFile="$emit('openFile', $event)"
          @filePreview="onFilePreview"
        />
      </ul>
    </div>
    <div class="file-manager__preview">
      <FilePreview :file="filePreview" />
    </div>
  </div>
</template>
<script setup lang="ts">
import {inject, ref, watch} from 'vue';
import {MountedFsSymbol} from '../../model/injectionSymbols';
import FileManagerDir from './FileManagerDir.vue';
import {VirtualFile} from '../../model/FileSystem/types';
import FileManagerFile from './FileManagerFile.vue';
import FilePreview from './FilePreview.vue';

const fs = inject(MountedFsSymbol)!;
const emit = defineEmits<{
  'openFile': [value: VirtualFile]
  'filePreview': [value: VirtualFile]
}>();

const search = ref('');
let searchAbort: AbortController;
const searchResults = ref<VirtualFile[]>([]);

const filePreview = ref<VirtualFile>();

function onFilePreview(file: VirtualFile) {
  filePreview.value = file;
  emit('filePreview', file)
}

watch(search, async (value) => {
  searchResults.value = [];
  if (value.length < 3) {
    return;
  }
  if (searchAbort) {
    searchAbort.abort();
  }
  searchAbort = new AbortController();
  let numberOfResults = 0;
  for await (let result of fs.search(value, searchAbort.signal)) {
    searchResults.value.push(result);
    if (numberOfResults++ > 100) {
      break;
    }
  }
});

const buildingIndex = ref(false);
const indexCounter = ref(0);

async function buildIndex() {
  buildingIndex.value = true;
  for await(let counter of fs.buildIndex()) {
    indexCounter.value = counter;
  }
}

</script>
<style>
.file-manager {
  display: grid;
  height: 100%;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
  gap: 0.5rem;
  padding: 0.5rem 0.25rem;
}

.file-manager__search {
  flex: 1;
  border-radius: 4px;
  border:none;
  padding: 2px 8px;
}

.file-manager__toolbar {
  padding: 4px;
  display: flex;
  flex-direction: row;
  grid-gap: 4px;
}

.file-manager-dir {
  list-style-type: none;
  padding-left: 1rem;
}

.file-manager__files {
  overflow: auto;
}

.file-manager-dir__label {
  cursor: pointer;
}

.file-manager-dir__label::before {
  content: '📁';
  margin-right: 0.5rem;
  display: inline-block;
}

.file-manager-dir__label--open::before {
  content: '📂';
}


</style>