<script setup lang="ts">
import { SEVERITY_LEVELS } from '#shared/types'
import { SEVERITY_COLORS } from '#shared/utils/severity'

const props = defineProps<{
  packageName: string
  version: string
}>()

const { data: vulnTree, status } = useDependencyAnalysis(
  () => props.packageName,
  () => props.version,
)

const isExpanded = shallowRef(false)
const showAllPackages = shallowRef(false)
const showAllVulnerabilities = shallowRef(false)

const hasVulnerabilities = computed(
  () => vulnTree.value && vulnTree.value.vulnerablePackages.length > 0,
)

// Banner - amber for better light mode contrast
const bannerColor = 'border-amber-600/40 bg-amber-500/10 text-amber-800 dark:text-amber-400'

const severityLabels = computed(() => ({
  critical: $t('package.vulnerabilities.severity.critical'),
  high: $t('package.vulnerabilities.severity.high'),
  moderate: $t('package.vulnerabilities.severity.moderate'),
  low: $t('package.vulnerabilities.severity.low'),
}))

function getPackageSeverityLabel(severity: Exclude<OsvSeverityLevel, 'unknown'>) {
  return severityLabels.value[severity]
}

const summaryText = computed(() => {
  if (!vulnTree.value) return ''
  const { totalCounts } = vulnTree.value
  return SEVERITY_LEVELS.filter(s => totalCounts[s] > 0)
    .map(s => `${totalCounts[s]} ${getPackageSeverityLabel(s)}`)
    .join(', ')
})

// Styling for each depth level - using accessible colors for both themes
const depthStyles = {
  root: {
    bg: 'bg-amber-500/5 border-is-2 border-is-amber-600',
    text: 'text-fg',
  },
  direct: {
    bg: 'bg-amber-500/5 border-is-2 border-is-amber-500',
    text: 'text-fg-muted',
  },
  transitive: {
    bg: 'bg-amber-500/5 border-is-2 border-is-amber-400',
    text: 'text-fg-muted',
  },
} as const

// Helper to get depth style with fallback
function getDepthStyle(depth: string | undefined) {
  if (depth && depth in depthStyles) {
    return depthStyles[depth as keyof typeof depthStyles]
  }
  return depthStyles.transitive
}
</script>

<template>
  <section
    v-if="status === 'success' && hasVulnerabilities"
    aria-labelledby="vuln-tree-heading"
    class="relative"
  >
    <!-- Collapsible vulnerability banner -->
    <div role="alert" class="rounded-lg border overflow-hidden" :class="bannerColor">
      <!-- Header -->
      <button
        type="button"
        class="w-full flex items-center justify-between gap-3 px-4 py-3 text-start transition-colors duration-200 hover:bg-white/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent/70"
        :aria-expanded="isExpanded"
        aria-controls="vuln-tree-details"
        @click="isExpanded = !isExpanded"
      >
        <span class="flex items-center gap-2 min-w-0">
          <span class="i-lucide:circle-alert w-4 h-4 shrink-0" aria-hidden="true" />
          <span class="font-mono text-sm font-medium truncate">
            {{
              $t(
                'package.vulnerabilities.tree_found',
                {
                  vulns: vulnTree!.totalCounts.total,
                  packages: vulnTree!.vulnerablePackages.length,
                  total: vulnTree!.totalPackages,
                },
                vulnTree!.totalCounts.total,
              )
            }}
          </span>
        </span>
        <span class="flex items-center gap-2 shrink-0">
          <span class="text-xs op-90 dark:op-80 hidden sm:inline">{{ summaryText }}</span>
          <span
            class="i-lucide:chevron-down w-4 h-4 transition-transform duration-200"
            :class="{ 'rotate-180': isExpanded }"
            aria-hidden="true"
          />
        </span>
      </button>

      <!-- Expandable details -->
      <div v-show="isExpanded" id="vuln-tree-details" class="border-t border-border bg-bg-subtle">
        <ul class="divide-y divide-border list-none m-0 p-0">
          <li
            v-for="pkg in vulnTree!.vulnerablePackages.slice(0, showAllPackages ? undefined : 5)"
            :key="`${pkg.name}@${pkg.version}`"
            class="px-4 py-3"
            :class="getDepthStyle(pkg.depth).bg"
          >
            <div class="flex items-center justify-between gap-2 mb-2">
              <div class="flex items-center gap-2 min-w-0 relative">
                <!-- Path badge - click to show tree popup -->
                <DependencyPathPopup v-if="pkg.path && pkg.path.length > 1" :path="pkg.path" />

                <NuxtLink
                  :to="packageRoute(pkg.name, pkg.version)"
                  class="font-mono text-sm font-medium hover:underline truncate shrink min-w-0"
                  :class="getDepthStyle(pkg.depth).text"
                >
                  {{ pkg.name }}@{{ pkg.version }}
                </NuxtLink>
              </div>
              <div class="flex items-center gap-1 shrink-0">
                <span
                  v-for="s in SEVERITY_LEVELS.filter(s => pkg.counts[s] > 0)"
                  :key="s"
                  class="px-1.5 py-0.5 text-3xs font-mono rounded border"
                  :class="SEVERITY_COLORS[s]"
                >
                  {{ pkg.counts[s] }} {{ getPackageSeverityLabel(s) }}
                </span>
              </div>
            </div>
            <!-- Show first 2 vulnerabilities -->
            <ul class="space-y-1 list-none m-0 p-0">
              <li
                v-for="vuln in pkg.vulnerabilities.slice(0, showAllVulnerabilities ? undefined : 2)"
                :key="vuln.id"
                class="flex items-center gap-2 text-xs text-fg-muted"
              >
                <a
                  :href="vuln.url"
                  target="_blank"
                  rel="noopener noreferrer"
                  class="font-mono hover:underline shrink-0"
                >
                  {{ vuln.id }}
                </a>
                <span class="truncate w-0 flex-1">{{ vuln.summary }}</span>
                <NuxtLink
                  v-if="vuln.fixedIn"
                  :to="packageRoute(pkg.name, vuln.fixedIn)"
                  class="shrink-0 font-mono text-emerald-600 dark:text-emerald-400 hover:underline"
                  :title="$t('package.vulnerabilities.fixed_in_title', { version: vuln.fixedIn })"
                >
                  → {{ vuln.fixedIn }}
                </NuxtLink>
              </li>
              <li
                v-if="pkg.vulnerabilities.length > 2 && !showAllVulnerabilities"
                class="text-xs text-fg-subtle"
              >
                <button type="button" @click="showAllVulnerabilities = true">
                  {{
                    $t('package.vulnerabilities.more', { count: pkg.vulnerabilities.length - 2 })
                  }}
                </button>
              </li>
            </ul>
          </li>
        </ul>

        <button
          v-if="vulnTree!.vulnerablePackages.length > 5 && !showAllPackages"
          type="button"
          class="w-full px-4 py-2 text-xs font-mono text-fg-muted hover:text-fg border-t border-border transition-colors duration-200"
          @click="showAllPackages = true"
        >
          {{
            $t('package.vulnerabilities.show_all_packages', {
              count: vulnTree!.vulnerablePackages.length,
            })
          }}
        </button>

        <!-- Warning if some queries failed -->
        <div
          v-if="vulnTree!.failedQueries"
          class="px-4 py-2 text-xs text-fg-subtle border-t border-border flex items-center gap-2"
        >
          <span class="i-lucide:circle-alert w-3 h-3" aria-hidden="true" />
          <span>{{ $t('package.vulnerabilities.packages_failed', vulnTree!.failedQueries) }}</span>
        </div>
      </div>
    </div>
  </section>

  <!-- Loading state - hidden (loading indicator shown in stats banner) -->

  <!-- No vulnerabilities found - don't show anything (count is shown in stats banner) -->

  <!-- Error state - subtle, not alarming -->
  <section v-else-if="status === 'error'" aria-labelledby="vuln-tree-error">
    <div class="rounded-lg border border-border bg-bg-subtle px-4 py-3">
      <div class="flex items-center gap-2">
        <span class="i-lucide:circle-alert w-4 h-4 text-fg-subtle" aria-hidden="true" />
        <span class="text-sm text-fg-muted">
          {{ $t('package.vulnerabilities.scan_failed') }}
        </span>
      </div>
    </div>
  </section>
</template>
