<script setup lang="ts">
import type { ModuleType } from '~/composables/module-graph'
import { relative } from 'pathe'
import { computed, ref } from 'vue'
import { config } from '~/composables/client'
import { currentModule } from '~/composables/navigation'
import { formatTime, getDurationClass, getExternalModuleName } from '~/utils/task'

interface ImportEntry {
  importedFile: string
  relativeFile: string
  selfTime: number
  totalTime: number
  formattedSelfTime: string
  formattedTotalTime: string
  selfTimeClass: string | undefined
  totalTimeClass: string | undefined
  external?: boolean
}

const emit = defineEmits<{
  select: [moduleId: string, type: ModuleType]
}>()

const maxAmount = ref(10)

const sortedImports = computed(() => {
  const file = currentModule.value
  const importDurations = file?.importDurations
  if (!importDurations) {
    return []
  }

  const root = config.value.root
  const allImports: ImportEntry[] = []
  for (const filePath in importDurations) {
    const duration = importDurations[filePath]
    const raltiveModule = duration.external
      ? getExternalModuleName(filePath)
      : relative(root, filePath)
    allImports.push({
      importedFile: filePath,
      relativeFile: ellipsisFile(raltiveModule),
      selfTime: duration.selfTime,
      totalTime: duration.totalTime,
      formattedSelfTime: formatTime(duration.selfTime),
      formattedTotalTime: formatTime(duration.totalTime),
      selfTimeClass: getDurationClass(duration.selfTime),
      totalTimeClass: getDurationClass(duration.totalTime),
      external: duration.external,
    })
  }
  const sortedImports = allImports.sort((a, b) => b.totalTime - a.totalTime)
  return sortedImports
})

const imports = computed(() => sortedImports.value.slice(0, maxAmount.value))

function ellipsisFile(moduleId: string) {
  if (moduleId.length <= 45) {
    return moduleId
  }
  return `...${moduleId.slice(-45)}`
}
</script>

<template>
  <div class="overflow-auto max-h-120">
    <h1 my-2 mx-4>
      Import Duration Breakdown <span op-70>(ordered by Total Time) (Top {{ Math.min(maxAmount, imports.length) }})</span>
    </h1>
    <table my-2 mx-4 text-sm font-light op-90>
      <thead>
        <tr>
          <th>
            Module
          </th>
          <th>
            Self
          </th>
          <th>
            Total
          </th>
          <th>
            %
          </th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="row of imports" :key="row.importedFile">
          <td
            class="cursor-pointer pr-2"
            :style="{ color: row.external ? 'var(--color-node-external)' : undefined }"
            @click="emit('select', row.importedFile, row.external ? 'external' : 'inline')"
          >
            {{ row.relativeFile }}
          </td>
          <td pr-2 :class="row.selfTimeClass">
            {{ row.formattedSelfTime }}
          </td>
          <td pr-2 :class="row.totalTimeClass">
            {{ row.formattedTotalTime }}
          </td>
          <td pr-2 :class="row.totalTimeClass">
            {{ Math.round((row.totalTime / sortedImports[0].totalTime) * 100) }}%
          </td>
        </tr>
      </tbody>
    </table>
    <button
      v-if="maxAmount < sortedImports.length"
      class="flex w-full justify-center h-8 text-sm z-10 relative font-light"
      @click="maxAmount += 5"
    >
      Show more
    </button>
  </div>
</template>
