<template>
  <div class="app-details-container pb-16 md:pb-16">
    <!-- Desktop Back Button -->
    <button @click="goBack" class="hidden md:flex mb-6 items-center gap-2 text-white/70 hover:text-white transition-colors">
      <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
      </svg>
      {{ backButtonText }}
    </button>

    <!-- Mobile Full-Width Back Button (teleported to escape CSS transform containing block) -->
    <Teleport to="body">
      <button
        @click="goBack"
        class="md:hidden mobile-back-btn glass-button px-6 py-3 rounded-lg font-medium shadow-2xl flex items-center justify-center gap-2"
      >
        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
        </svg>
        <span>{{ backButtonText }}</span>
      </button>
    </Teleport>

    <div v-if="pkg">
      <!-- Compact Hero Section -->
      <div class="glass-card p-6 mb-6">
        <!-- Desktop: Single Row Layout -->
        <div class="hidden md:flex items-center gap-6">
          <!-- App Icon -->
      <img
        :src="pkg['static-files'].icon"
        :alt="pkg.manifest.title"
            class="w-20 h-20 rounded-xl shadow-xl flex-shrink-0"
            @error="handleImageError"
          />
          
          <!-- App Info (grows to fill space) -->
          <div class="flex-1 min-w-0">
            <h1 class="text-2xl font-bold text-white mb-1">{{ pkg.manifest.title }}</h1>
            <p class="text-white/70 text-sm mb-2">{{ pkg.manifest.description.short }}</p>
            <div class="flex items-center gap-2">
      <span
                class="inline-flex items-center px-2.5 py-1 rounded-lg text-xs font-medium"
        :class="getStatusClass(pkg.state)"
      >
                <span class="w-1.5 h-1.5 rounded-full mr-1.5" :class="getStatusDotClass(pkg.state)"></span>
        {{ pkg.state }}
      </span>
              <span class="text-white/50 text-xs">v{{ pkg.manifest.version }}</span>
            </div>
          </div>

          <!-- Action Buttons -->
          <div class="flex items-center gap-2 flex-shrink-0">
        <button
              v-if="canLaunch"
          @click="launchApp"
              class="glass-button glass-button-sm px-6 py-2.5 rounded-lg text-sm font-semibold flex items-center gap-2"
            >
              <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
              </svg>
              Launch
            </button>
            <button
              v-if="pkg.state === 'stopped'"
              @click="startApp"
              class="px-4 py-2.5 bg-green-500/20 border border-green-500/40 rounded-lg text-green-200 text-sm font-medium hover:bg-green-500/30 transition-colors flex items-center gap-2"
            >
              <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
              </svg>
              Start
            </button>
            <button
              @click="restartApp"
              class="px-4 py-2.5 glass-button rounded-lg text-sm font-medium hover:bg-white/15 transition-colors flex items-center gap-2"
            >
              <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
              </svg>
              Restart
            </button>
            <button
              v-if="pkg.state === 'running'"
              @click="stopApp"
              class="px-4 py-2.5 bg-yellow-500/20 border border-yellow-500/40 rounded-lg text-yellow-200 text-sm font-medium hover:bg-yellow-500/30 transition-colors flex items-center gap-2"
            >
              <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 10a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z" />
              </svg>
              Stop
            </button>
            <button
              @click="uninstallApp"
              class="px-4 py-2.5 bg-red-600/20 border border-red-600/40 rounded-lg text-red-300 text-sm font-medium hover:bg-red-600/30 transition-colors flex items-center gap-2"
            >
              <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
              </svg>
              Uninstall
            </button>
          </div>
        </div>

        <!-- Mobile: Two Column Grid Layout -->
        <div class="md:hidden">
          <!-- Header: Icon + Info + Delete -->
          <div class="flex items-start gap-4 mb-4">
            <!-- App Icon -->
            <img
              :src="pkg['static-files'].icon"
              :alt="pkg.manifest.title"
              class="w-20 h-20 rounded-xl shadow-xl flex-shrink-0"
              @error="handleImageError"
            />
            
            <!-- App Info -->
            <div class="flex-1 min-w-0">
              <h1 class="text-xl font-bold text-white mb-1">{{ pkg.manifest.title }}</h1>
              <p class="text-white/70 text-xs mb-2 line-clamp-2">{{ pkg.manifest.description.short }}</p>
              <div class="flex flex-wrap items-center gap-2">
                <span
                  class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium"
                  :class="getStatusClass(pkg.state)"
                >
                  <span class="w-1.5 h-1.5 rounded-full mr-1" :class="getStatusDotClass(pkg.state)"></span>
                  {{ pkg.state }}
                </span>
                <span class="text-white/50 text-xs">v{{ pkg.manifest.version }}</span>
              </div>
            </div>

            <!-- Uninstall Icon Button -->
            <button
              @click="uninstallApp"
              class="flex-shrink-0 w-9 h-9 rounded-lg bg-red-600/20 border border-red-600/40 text-red-300 hover:bg-red-600/30 transition-colors flex items-center justify-center"
              title="Uninstall"
            >
              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
              </svg>
        </button>
      </div>

          <!-- Action Buttons (Auto Grid) -->
          <div class="grid grid-cols-2 gap-2">
            <button
              v-if="canLaunch"
              @click="launchApp"
              class="glass-button glass-button-sm px-4 py-2.5 rounded-lg text-sm font-semibold flex items-center justify-center gap-2"
            >
              <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
              </svg>
              Launch
            </button>
        <button
          v-if="pkg.state === 'stopped'"
          @click="startApp"
              class="px-4 py-2.5 bg-green-500/20 border border-green-500/40 rounded-lg text-green-200 text-sm font-medium hover:bg-green-500/30 transition-colors flex items-center justify-center gap-2"
        >
              <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
              </svg>
          Start
        </button>
        <button
          v-if="pkg.state === 'running'"
          @click="stopApp"
              class="px-4 py-2.5 bg-yellow-500/20 border border-yellow-500/40 rounded-lg text-yellow-200 text-sm font-medium hover:bg-yellow-500/30 transition-colors flex items-center justify-center gap-2"
        >
              <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 10a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z" />
              </svg>
          Stop
        </button>
        <button
          @click="restartApp"
              :class="[canLaunch && (pkg.state === 'stopped' || pkg.state === 'running') ? 'col-span-2' : '']"
              class="px-4 py-2.5 glass-button rounded-lg text-sm font-medium hover:bg-white/15 transition-colors flex items-center justify-center gap-2"
        >
              <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
              </svg>
          Restart
        </button>
          </div>
        </div>
      </div>

      <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
        <!-- Main Content -->
        <div class="lg:col-span-2 space-y-6">
          <!-- Screenshots Gallery -->
          <div class="glass-card p-6">
            <h2 class="text-2xl font-bold text-white mb-4">Screenshots</h2>
            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div
                v-for="i in 4"
                :key="i"
                class="aspect-video rounded-xl bg-white/5 border border-white/10 flex items-center justify-center hover:bg-white/10 transition-colors cursor-pointer"
              >
                <svg class="w-16 h-16 text-white/20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
                </svg>
              </div>
            </div>
            <p class="text-white/60 text-sm mt-3 text-center">Screenshot placeholders - images coming soon</p>
          </div>

          <!-- Description -->
          <div class="glass-card p-6">
            <h2 class="text-2xl font-bold text-white mb-4">About {{ pkg.manifest.title }}</h2>
            <p class="text-white/80 leading-relaxed whitespace-pre-line">
              {{ pkg.manifest.description.long }}
            </p>
          </div>

          <!-- Features (if available) -->
          <div v-if="features.length > 0" class="glass-card p-6">
            <h2 class="text-2xl font-bold text-white mb-4">Features</h2>
            <ul class="space-y-3">
              <li
                v-for="(feature, index) in features"
                :key="index"
                class="flex items-start gap-3 text-white/80"
              >
                <svg class="w-6 h-6 text-green-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
                <span>{{ feature }}</span>
              </li>
            </ul>
          </div>
        </div>

        <!-- Sidebar -->
        <div class="space-y-6">
          <!-- App Info Card -->
          <div class="glass-card p-6">
            <h3 class="text-lg font-bold text-white mb-4">Information</h3>
            <div class="space-y-3">
              <div class="flex items-center justify-between py-2 border-b border-white/10">
                <span class="text-white/60 text-sm">Version</span>
                <span class="text-white font-medium">{{ pkg.manifest.version }}</span>
              </div>
              <div v-if="pkg.manifest.author" class="flex items-center justify-between py-2 border-b border-white/10">
                <span class="text-white/60 text-sm">Developer</span>
                <span class="text-white font-medium">{{ pkg.manifest.author }}</span>
              </div>
              <div class="flex items-center justify-between py-2 border-b border-white/10">
                <span class="text-white/60 text-sm">Status</span>
                <span class="text-white font-medium capitalize">{{ pkg.state }}</span>
              </div>
              <div v-if="pkg.manifest.license" class="flex items-center justify-between py-2 border-b border-white/10">
                <span class="text-white/60 text-sm">License</span>
                <span class="text-white font-medium">{{ pkg.manifest.license }}</span>
              </div>
              <div class="flex items-center justify-between py-2">
                <span class="text-white/60 text-sm">Category</span>
                <span class="text-white font-medium">App</span>
              </div>
            </div>
          </div>

          <!-- Access (LAN + Tor) Card -->
          <div v-if="interfaceAddresses" class="glass-card p-6">
            <h3 class="text-lg font-bold text-white mb-4">Access</h3>
            <div class="space-y-3">
              <div v-if="interfaceAddresses['lan-address']" class="flex items-start gap-3">
                <svg class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
                </svg>
                <div class="flex-1 min-w-0">
                  <p class="text-white/80 font-medium">LAN</p>
                  <a
                    :href="lanUrl"
                    target="_blank"
                    rel="noopener noreferrer"
                    class="text-blue-400 hover:text-blue-300 text-sm break-all"
                  >
                    {{ interfaceAddresses['lan-address'] }}
                  </a>
                </div>
              </div>
              <div v-if="isRealOnionAddress(interfaceAddresses['tor-address'])" class="flex items-start gap-3">
                <svg class="w-5 h-5 text-amber-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
                </svg>
                <div class="flex-1 min-w-0">
                  <p class="text-white/80 font-medium">Tor</p>
                  <span class="text-amber-300/90 text-sm font-mono break-all">{{ torUrl }}</span>
                  <p class="text-white/50 text-xs mt-1">Requires Tor Browser</p>
                </div>
              </div>
            </div>
          </div>

          <!-- Requirements Card -->
          <div class="glass-card p-6">
            <h3 class="text-lg font-bold text-white mb-4">Requirements</h3>
            <div class="space-y-3">
              <div class="flex items-start gap-3">
                <svg class="w-5 h-5 text-blue-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" />
                </svg>
                <div class="flex-1">
                  <p class="text-white/80 font-medium">RAM</p>
                  <p class="text-white/60 text-sm">Minimum 512MB</p>
                </div>
              </div>
              <div class="flex items-start gap-3">
                <svg class="w-5 h-5 text-purple-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4" />
                </svg>
                <div class="flex-1">
                  <p class="text-white/80 font-medium">Storage</p>
                  <p class="text-white/60 text-sm">~100MB</p>
                </div>
              </div>
            </div>
          </div>

          <!-- Links Card -->
          <div class="glass-card p-6">
            <h3 class="text-lg font-bold text-white mb-4">Links</h3>
            <div class="space-y-2">
              <a
                v-if="pkg.manifest.website"
                :href="pkg.manifest.website"
                target="_blank"
                rel="noopener noreferrer"
                class="flex items-center gap-2 text-blue-400 hover:text-blue-300 transition-colors"
              >
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
                </svg>
                Website
              </a>
              <a
                href="#"
                class="flex items-center gap-2 text-blue-400 hover:text-blue-300 transition-colors"
              >
                <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
                  <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.840 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
                </svg>
                Source Code
              </a>
              <a
                href="#"
                class="flex items-center gap-2 text-blue-400 hover:text-blue-300 transition-colors"
              >
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
                </svg>
                Documentation
              </a>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- App Not Found -->
    <div v-else class="glass-card p-12 text-center">
      <svg class="w-24 h-24 text-white/20 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
      </svg>
      <h3 class="text-2xl font-semibold text-white mb-2">App Not Found</h3>
      <p class="text-white/70">The requested application could not be found</p>
    </div>

    <!-- Uninstall Confirmation Modal -->
    <Transition name="modal">
      <div
        v-if="uninstallModal.show"
        class="fixed inset-0 z-50 flex items-center justify-center p-4"
        @click="closeUninstallModal()"
      >
        <div class="absolute inset-0 bg-black/60 backdrop-blur-sm"></div>
        <div
          ref="uninstallModalRef"
          @click.stop
          class="glass-card p-6 md:p-8 max-w-md w-full relative z-10"
        >
          <div class="flex items-start gap-4 mb-6">
            <div class="p-3 bg-red-500/20 rounded-lg flex-shrink-0">
              <svg class="w-6 h-6 text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
              </svg>
            </div>
            <div class="flex-1 min-w-0">
              <h3 class="text-xl font-semibold text-white mb-2">Uninstall App?</h3>
              <p class="text-white/70 text-sm">
                Are you sure you want to uninstall <span class="text-white font-medium">{{ uninstallModal.appTitle }}</span>?
                This will remove the app and stop its container.
              </p>
            </div>
          </div>

          <div class="flex flex-col-reverse md:flex-row gap-3 md:justify-end">
            <button
              @click="closeUninstallModal()"
              class="w-full md:w-auto px-6 py-3 glass-button rounded-lg text-sm font-medium"
            >
              Cancel
            </button>
            <button
              @click="confirmUninstall"
              class="w-full md:w-auto px-6 py-3 bg-red-600/80 hover:bg-red-600 rounded-lg text-white text-sm font-medium transition-colors"
            >
              Uninstall
            </button>
          </div>
        </div>
      </div>
    </Transition>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useAppStore } from '../stores/app'
import { useAppLauncherStore } from '../stores/appLauncher'
import { PackageState } from '../types/api'
import { useModalKeyboard } from '@/composables/useModalKeyboard'
import { dummyApps } from '../utils/dummyApps'

const router = useRouter()
const route = useRoute()
const store = useAppStore()

const appId = computed(() => route.params.id as string)

/** Map route/marketplace app IDs to backend package keys (container names). */
const ROUTE_TO_PACKAGE_KEY: Record<string, string> = {
  mempool: 'mempool-web',
  'mempool-electrs': 'mempool-electrs',
  electrs: 'mempool-electrs',
  btcpay: 'btcpay-server',
  'btcpay-server': 'btcpay-server',
  fedimint: 'fedimint',
  lnd: 'lnd',
  'lnd-ui': 'lnd',
  bitcoin: 'bitcoin-knots',
  'bitcoin-knots': 'bitcoin-knots',
  homeassistant: 'homeassistant',
  'home-assistant': 'homeassistant',
  grafana: 'grafana',
  searxng: 'searxng',
  ollama: 'ollama',
  onlyoffice: 'onlyoffice',
  penpot: 'penpot',
  nextcloud: 'nextcloud',
  vaultwarden: 'vaultwarden',
  jellyfin: 'jellyfin',
  photoprism: 'photoprism',
  immich: 'immich',
  filebrowser: 'filebrowser',
  'nginx-proxy-manager': 'nginx-proxy-manager',
  portainer: 'portainer',
  'uptime-kuma': 'uptime-kuma',
  tailscale: 'tailscale',
}

/** Backend may register under variant container names */
const PACKAGE_ALIASES: Record<string, string[]> = {
  immich: ['immich_server', 'immich-server'],
  nextcloud: ['nextcloud-aio', 'nextcloud-server'],
}

function resolvePackageKey(routeId: string): string {
  return ROUTE_TO_PACKAGE_KEY[routeId] ?? routeId
}

// Check both store.packages and dummyApps; resolve route ID to package key for backend data
const pkg = computed(() => {
  const routeId = appId.value
  const packageKey = resolvePackageKey(routeId)
  // First check real packages (try both route id and resolved key)
  if (store.packages[packageKey]) {
    return store.packages[packageKey]
  }
  if (store.packages[routeId]) {
    return store.packages[routeId]
  }
  // Check known aliases (backend may use variant container names)
  const aliases = PACKAGE_ALIASES[routeId]
  if (aliases) {
    for (const alias of aliases) {
      if (store.packages[alias]) {
        return store.packages[alias]
      }
    }
  }
  // Fall back to dummy apps
  if (dummyApps[routeId]) {
    return dummyApps[routeId]
  }
  return null
})

const interfaceAddresses = computed(() => {
  const main = pkg.value?.installed?.['interface-addresses']?.main
  if (!main) return null
  if (!main['lan-address'] && !isRealOnionAddress(main['tor-address'])) return null
  return main
})

/** V3 onion addresses are 56+ chars + .onion. Placeholders like "btcpay.onion" are not real. */
function isRealOnionAddress(addr: string | undefined): boolean {
  return !!(addr && addr.endsWith('.onion') && addr.length >= 60 && addr.length <= 70)
}

const lanUrl = computed(() => {
  const addr = interfaceAddresses.value?.['lan-address']
  if (!addr) return '#'
  if (addr.includes('localhost')) {
    return addr.replace('localhost', window.location.hostname)
  }
  return addr
})

/** Tor URL with http:// prefix for copy-paste into Tor Browser */
const torUrl = computed(() => {
  const addr = interfaceAddresses.value?.['tor-address']
  if (!addr || !isRealOnionAddress(addr)) return ''
  return addr.startsWith('http') ? addr : `http://${addr}`
})

const uninstallModal = ref({
  show: false,
  appTitle: ''
})
const uninstallModalRef = ref<HTMLElement | null>(null)
const uninstallRestoreFocusRef = ref<HTMLElement | null>(null)
function closeUninstallModal() {
  uninstallRestoreFocusRef.value?.focus?.()
  uninstallModal.value.show = false
}
useModalKeyboard(
  uninstallModalRef,
  computed(() => uninstallModal.value.show),
  closeUninstallModal,
  { restoreFocusRef: uninstallRestoreFocusRef }
)

// Determine back button text based on where user came from
const backButtonText = computed(() => {
  // Check if we came from marketplace via query parameter
  if (route.query.from === 'marketplace') {
    return 'Back to App Store'
  }
  
  // Default to My Apps
  return 'Back to My Apps'
})

// Check if app has a UI interface and is running
const canLaunch = computed(() => {
  if (!pkg.value) return false
  // For dummy apps, allow launch if running (they have interface addresses)
  // For real apps, check for UI interface
  const hasUI = pkg.value.manifest.interfaces?.main?.ui || pkg.value.installed?.['interface-addresses']?.main
  const isRunning = pkg.value.state === 'running'
  return hasUI && isRunning
})

// Placeholder features - could be extracted from manifest later
const features = computed(() => {
  return [
    'Self-hosted and privacy-focused',
    'Easy installation and updates',
    'Automatic backups',
    'Secure by default'
  ]
})

function handleImageError(e: Event) {
  const target = e.target as HTMLImageElement
  const currentSrc = target.src
  const id = appId.value
  
  // If it's a dummy app, try to get icon from GitHub or use placeholder
  if (dummyApps[id]) {
    // Try alternative icon paths
    const iconPaths = [
      `https://raw.githubusercontent.com/Start9Labs/${id}-startos/main/icon.png`,
      `https://raw.githubusercontent.com/Start9Labs/${id}-startos/main/icon.svg`,
      `/assets/img/app-icons/${id}.png`,
      `/assets/img/app-icons/${id}.svg`,
    ]
    
    // Try next path if available
    const currentIndex = iconPaths.findIndex(path => currentSrc.includes(path))
    if (currentIndex < iconPaths.length - 1) {
      const nextPath = iconPaths[currentIndex + 1]
      if (nextPath !== undefined) {
        target.src = nextPath
        return
      }
    }
  }
  
  // Create a simple placeholder SVG
  const placeholderSvg = `data:image/svg+xml,${encodeURIComponent(`
    <svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
      <rect width="80" height="80" rx="16" fill="rgba(255,255,255,0.1)"/>
      <path d="M40 25L50 35H45V50H35V35H30L40 25Z" fill="rgba(255,255,255,0.6)"/>
      <path d="M25 55H55V60H25V55Z" fill="rgba(255,255,255,0.4)"/>
    </svg>
  `)}`
  
  // Only set fallback if we haven't already tried it
  if (!currentSrc.includes('data:image')) {
    target.src = placeholderSvg
  } else {
    // Ultimate fallback
    target.src = '/assets/img/logo-archipelago.svg'
  }
}

function goBack() {
  router.back()
}


function launchApp() {
  if (!pkg.value) return
  
  const isDev = import.meta.env.DEV
  const id = appId.value
  
  // Special handling for apps with Docker containers
  // TODO: Replace dummy app URLs with real URLs when apps are packaged
  const appUrls: Record<string, { dev: string, prod: string }> = {
    'lorabell': {
      dev: 'http://192.168.1.166',
      prod: 'http://192.168.1.166'
    },
    'atob': {
      dev: 'http://localhost:8102',
      prod: 'https://app.atobitcoin.io'
    },
    'k484': {
      dev: 'http://localhost:8103',
      prod: 'http://localhost:8103' // Self-hosted splash screen
    },
    'indeedhub': {
      dev: 'https://archipelago.indeehub.studio',
      prod: 'https://archipelago.indeehub.studio'
    },
    // Dummy apps - replace with real URLs when packaged
    'bitcoin': {
      dev: 'http://localhost:8332',
      prod: 'http://localhost:8332'
    },
    'btcpay-server': {
      dev: 'http://localhost:23000',
      prod: 'http://localhost:23000'
    },
    'homeassistant': {
      dev: 'http://localhost:8123',
      prod: 'http://localhost:8123'
    },
    'grafana': {
      dev: 'http://localhost:3000',
      prod: 'http://localhost:3000'
    },
    'endurain': {
      dev: 'http://localhost:8080',
      prod: 'http://localhost:8080'
    },
    'fedimint': {
      dev: 'http://localhost:8175',
      prod: 'http://192.168.1.228:8175'
    },
    'morphos-server': {
      dev: 'http://localhost:8081',
      prod: 'http://localhost:8081'
    },
    'lightning-stack': {
      dev: 'http://localhost:9735',
      prod: 'http://localhost:9735'
    },
    'mempool': {
      dev: 'http://localhost:4080',
      prod: 'http://localhost:4080'
    },
    'ollama': {
      dev: 'http://localhost:11434',
      prod: 'http://localhost:11434'
    },
    'searxng': {
      dev: 'http://localhost:8888',
      prod: 'http://localhost:8888'
    },
    'onlyoffice': {
      dev: 'http://localhost:9980',
      prod: 'http://localhost:9980'
    },
    'penpot': {
      dev: 'http://localhost:9001',
      prod: 'http://localhost:9001'
    },
    'nextcloud': { dev: 'http://localhost:8085', prod: 'http://localhost:8085' },
    'vaultwarden': { dev: 'http://localhost:8082', prod: 'http://localhost:8082' },
    'jellyfin': { dev: 'http://localhost:8096', prod: 'http://localhost:8096' },
    'photoprism': { dev: 'http://localhost:2342', prod: 'http://localhost:2342' },
    'immich': { dev: 'http://localhost:2283', prod: 'http://localhost:2283' },
    'filebrowser': { dev: 'http://localhost:8083', prod: 'http://localhost:8083' },
    'nginx-proxy-manager': { dev: 'http://localhost:81', prod: 'http://localhost:81' },
    'portainer': { dev: 'http://localhost:9000', prod: 'http://localhost:9000' },
    'uptime-kuma': { dev: 'http://localhost:3001', prod: 'http://localhost:3001' },
    'tailscale': { dev: 'http://localhost:8240', prod: 'http://localhost:8240' },
    'lnd': { dev: 'http://localhost:8081', prod: 'http://localhost:8081' },
    'bitcoin-knots': { dev: 'http://localhost:8334', prod: 'http://localhost:8334' }
  }
  
  if (appUrls[id]) {
    let url = isDev ? appUrls[id].dev : appUrls[id].prod
    // Replace localhost with current hostname for remote access
    if (url.includes('localhost')) {
      url = url.replace('localhost', window.location.hostname)
    }
    useAppLauncherStore().open({ url, title: pkg.value.manifest.title })
    return
  }
  
  // For other apps, construct the launch URL
  // In a real deployment, this would use the Tor or LAN address from interfaces
  const torAddress = pkg.value.manifest.interfaces?.main?.['tor-config']
  const lanConfig = pkg.value.manifest.interfaces?.main?.['lan-config']
  
  if (torAddress || lanConfig) {
    // In development, just alert - in production would open the actual interface
    alert(`Would launch ${pkg.value.manifest.title} interface`)
  }
}

async function startApp() {
  try {
    await store.startPackage(appId.value)
  } catch (err) {
    console.error('Failed to start app:', err)
  }
}

async function stopApp() {
  try {
    await store.stopPackage(appId.value)
  } catch (err) {
    console.error('Failed to stop app:', err)
  }
}

async function restartApp() {
  try {
    await store.restartPackage(appId.value)
  } catch (err) {
    console.error('Failed to restart app:', err)
  }
}

function showUninstallModal() {
  if (!pkg.value) return
  uninstallModal.value = {
    show: true,
    appTitle: pkg.value.manifest.title
  }
}

async function confirmUninstall() {
  uninstallModal.value.show = false
  
  try {
    await store.uninstallPackage(appId.value)
    router.push('/dashboard/apps').catch(() => {})
  } catch (err) {
    console.error('Failed to uninstall app:', err)
    alert('Failed to uninstall app')
  }
}

// Keep for backwards compatibility but redirect to modal
async function uninstallApp() {
  showUninstallModal()
}

function getStatusClass(state: PackageState): string {
  switch (state) {
    case PackageState.Running:
      return 'bg-green-500/20 text-green-200 border border-green-500/30'
    case PackageState.Stopped:
      return 'bg-gray-500/20 text-gray-200 border border-gray-500/30'
    case PackageState.Starting:
    case PackageState.Stopping:
    case PackageState.Restarting:
      return 'bg-yellow-500/20 text-yellow-200 border border-yellow-500/30'
    case PackageState.Installing:
      return 'bg-blue-500/20 text-blue-200 border border-blue-500/30'
    default:
      return 'bg-gray-500/20 text-gray-200 border border-gray-500/30'
  }
}

function getStatusDotClass(state: PackageState): string {
  switch (state) {
    case PackageState.Running:
      return 'bg-green-400'
    case PackageState.Stopped:
      return 'bg-gray-400'
    case PackageState.Starting:
    case PackageState.Stopping:
    case PackageState.Restarting:
      return 'bg-yellow-400 animate-pulse'
    case PackageState.Installing:
      return 'bg-blue-400 animate-pulse'
    default:
      return 'bg-gray-400'
  }
}
</script>

<style scoped>
.modal-enter-active,
.modal-leave-active {
  transition: opacity 0.3s ease;
}

.modal-enter-active .glass-card,
.modal-leave-active .glass-card {
  transition: transform 0.3s ease, opacity 0.3s ease;
}

.modal-enter-from,
.modal-leave-to {
  opacity: 0;
}

.modal-enter-from .glass-card,
.modal-leave-to .glass-card {
  transform: scale(0.95);
  opacity: 0;
}
</style>
