<!DOCTYPE html>
<html lang="en">
{{template "views/partials/head" .}}

<body class="bg-[var(--color-bg-primary)] text-[var(--color-text-primary)]">
<div class="app-layout">
  {{template "views/partials/navbar" .}}
  
  <main class="main-content">
    <div class="main-content-inner" x-data="indexDashboard()">

    <!-- Notifications -->
    <div class="fixed top-20 right-4 z-50 space-y-2" style="max-width: 400px;">
        <template x-for="notification in notifications" :key="notification.id">
            <div x-show="true" 
                 x-transition:enter="transition ease-out duration-200"
                 x-transition:enter-start="opacity-0"
                 x-transition:enter-end="opacity-100"
                 x-transition:leave="transition ease-in duration-150"
                 x-transition:leave-start="opacity-100"
                 x-transition:leave-end="opacity-0"
                 :class="notification.type === 'error' ? 'bg-red-500' : 'bg-[var(--color-success)]'"
                 class="rounded-lg p-4 text-white flex items-start space-x-3">
                <div class="flex-shrink-0">
                    <i :class="notification.type === 'error' ? 'fas fa-exclamation-circle' : 'fas fa-check-circle'" class="text-xl"></i>
                </div>
                <div class="flex-1 min-w-0">
                    <p class="text-sm font-medium break-words" x-text="notification.message"></p>
                </div>
                <button @click="dismissNotification(notification.id)" class="flex-shrink-0 text-white hover:opacity-80 transition-opacity">
                    <i class="fas fa-times"></i>
                </button>
            </div>
        </template>
    </div>

    <div class="container mx-auto px-4 py-8 flex-grow">
        <!-- Hero Header -->
        <div class="hero-section">
            <div class="hero-content">
                <h1 class="hero-title">
                    Model & Backend Management
                </h1>
                <p class="hero-subtitle">Manage your installed models and backends</p>
            </div>
        </div>

        <!-- Memory Info Section (GPU or RAM) -->
        <div class="mt-8" x-data="resourceMonitor()" x-init="startPolling()">
            <template x-if="resourceData && resourceData.available">
                <div class="bg-[var(--color-bg-secondary)] border border-[var(--color-primary-border)]/20 rounded-lg p-4 mb-6">
                    <div class="flex items-center justify-between mb-3">
                        <h2 class="h3 flex items-center">
                            <i :class="resourceData.type === 'gpu' ? 'fas fa-microchip' : 'fas fa-memory'" class="mr-2 text-[var(--color-primary)] text-sm"></i>
                            <span x-text="resourceData.type === 'gpu' ? 'GPU Status' : 'Memory Status'"></span>
                        </h2>
                        <div class="flex items-center gap-2 text-xs text-[var(--color-text-secondary)]">
                            <template x-if="resourceData.type === 'gpu'">
                                <span x-text="`${resourceData.aggregate.gpu_count} GPU${resourceData.aggregate.gpu_count > 1 ? 's' : ''}`"></span>
                            </template>
                            <template x-if="resourceData.type === 'ram'">
                                <span>System RAM</span>
                            </template>
                            <template x-if="resourceData.reclaimer_enabled">
                                <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--color-primary)]/10 text-[var(--color-primary)]">
                                    <i class="fas fa-shield-alt text-[8px] mr-1"></i>Reclaimer Active
                                </span>
                            </template>
                        </div>
                    </div>
                    
                    <!-- Per-GPU Stats (when GPU available) -->
                    <template x-if="resourceData.type === 'gpu' && resourceData.gpus">
                        <div class="space-y-3">
                            <template x-for="gpu in resourceData.gpus" :key="gpu.index">
                                <div class="bg-[var(--color-bg-primary)] rounded p-3">
                                    <div class="flex items-center justify-between mb-2">
                                        <div class="flex items-center gap-2">
                                            <span class="text-xs font-medium text-[var(--color-text-primary)] truncate max-w-[200px]" x-text="gpu.name"></span>
                                            <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium"
                                                  :class="gpu.vendor === 'nvidia' ? 'bg-green-500/10 text-green-300' : 
                                                          gpu.vendor === 'amd' ? 'bg-red-500/10 text-red-300' : 
                                                          gpu.vendor === 'intel' ? 'bg-blue-500/10 text-blue-300' : 
                                                          'bg-[var(--color-accent-light)] text-[var(--color-accent)]'"
                                                  x-text="gpu.vendor.toUpperCase()">
                                            </span>
                                        </div>
                                        <span class="text-xs font-mono" 
                                              :class="gpu.usage_percent > 90 ? 'text-red-400' : gpu.usage_percent > 70 ? 'text-yellow-400' : 'text-green-400'"
                                              x-text="`${gpu.usage_percent.toFixed(1)}%`"></span>
                                    </div>
                                    <!-- Progress Bar -->
                                    <div class="w-full bg-[var(--color-bg-secondary)] rounded-full h-2 overflow-hidden">
                                        <div class="h-full rounded-full transition-all duration-300"
                                             :class="gpu.usage_percent > 90 ? 'bg-red-500' : gpu.usage_percent > 70 ? 'bg-yellow-500' : 'bg-[var(--color-success)]'"
                                             :style="`width: ${gpu.usage_percent}%`"></div>
                                    </div>
                                    <div class="flex justify-between mt-1 text-[10px] text-[var(--color-text-secondary)]">
                                        <span x-text="`Used: ${formatBytes(gpu.used_vram)}`"></span>
                                        <span x-text="`Total: ${formatBytes(gpu.total_vram)}`"></span>
                                    </div>
                                </div>
                            </template>
                        </div>
                    </template>
                    
                    <!-- RAM Stats (when no GPU) -->
                    <template x-if="resourceData.type === 'ram' && resourceData.ram">
                        <div class="bg-[var(--color-bg-primary)] rounded p-3">
                            <div class="flex items-center justify-between mb-2">
                                <div class="flex items-center gap-2">
                                    <span class="text-xs font-medium text-[var(--color-text-primary)]">System RAM</span>
                                    <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--color-accent-light)] text-[var(--color-accent)]">
                                        RAM
                                    </span>
                                </div>
                                <span class="text-xs font-mono" 
                                      :class="resourceData.ram.usage_percent > 90 ? 'text-red-400' : resourceData.ram.usage_percent > 70 ? 'text-yellow-400' : 'text-green-400'"
                                      x-text="`${resourceData.ram.usage_percent.toFixed(1)}%`"></span>
                            </div>
                            <!-- Progress Bar -->
                            <div class="w-full bg-[var(--color-bg-secondary)] rounded-full h-2 overflow-hidden">
                                <div class="h-full rounded-full transition-all duration-300"
                                     :class="resourceData.ram.usage_percent > 90 ? 'bg-red-500' : resourceData.ram.usage_percent > 70 ? 'bg-yellow-500' : 'bg-[var(--color-success)]'"
                                     :style="`width: ${resourceData.ram.usage_percent}%`"></div>
                            </div>
                            <div class="flex justify-between mt-1 text-[10px] text-[var(--color-text-secondary)]">
                                <span x-text="`Used: ${formatBytes(resourceData.ram.used)}`"></span>
                                <span x-text="`Total: ${formatBytes(resourceData.ram.total)}`"></span>
                            </div>
                        </div>
                    </template>
                    
                    <!-- Aggregate Stats (if multiple GPUs) -->
                    <template x-if="resourceData.type === 'gpu' && resourceData.aggregate.gpu_count > 1">
                        <div class="mt-3 pt-3 border-t border-[var(--color-primary-border)]/20">
                            <div class="flex items-center justify-between text-xs">
                                <span class="text-[var(--color-text-secondary)]">Total VRAM:</span>
                                <span class="font-mono text-[var(--color-text-primary)]" 
                                      x-text="`${formatBytes(resourceData.aggregate.used_memory)} / ${formatBytes(resourceData.aggregate.total_memory)} (${resourceData.aggregate.usage_percent.toFixed(1)}%)`"></span>
                            </div>
                        </div>
                    </template>
                    <!-- Models storage (disk usage) -->
                    <template x-if="resourceData.storage_size != null">
                        <div class="mt-3 pt-3 border-t border-[var(--color-primary-border)]/20">
                            <div class="flex justify-between text-xs">
                                <span class="text-[var(--color-text-secondary)]">Models storage</span>
                                <span class="font-mono text-[var(--color-text-primary)]" x-text="formatBytes(resourceData.storage_size)"></span>
                            </div>
                        </div>
                    </template>
                </div>
            </template>
        </div>

        <!-- Models Section -->
        <div class="models mt-8">
            {{template "views/partials/inprogress" .}}
            
            {{ if eq (len .ModelsConfig) 0 }}
            <!-- No Models State -->
            <div class="card p-8">
                <div class="text-center max-w-4xl mx-auto">
                    <div class="inline-flex items-center justify-center w-12 h-12 rounded-full bg-yellow-500/10 border border-yellow-500/20 mb-4">
                        <i class="text-yellow-400 text-xl fas fa-robot"></i>
                    </div>
                    <h2 class="h2 mb-2">No models installed yet</h2>
                    <p class="text-sm text-[var(--color-text-secondary)] mb-6">Get started by installing a model from the gallery or importing it</p>
                    
                    <div class="flex flex-wrap justify-center gap-2 mb-6">
                        <a href="browse" class="inline-flex items-center gap-1.5 text-xs text-[var(--color-text-secondary)] hover:text-[var(--color-primary)] bg-transparent hover:bg-[var(--color-primary)]/10 border border-[var(--color-border-subtle)] hover:border-[var(--color-primary)]/30 rounded-md py-1.5 px-2.5 transition-colors">
                            <i class="fas fa-images text-[10px]"></i>
                            <span>Browse Model Gallery</span>
                        </a>
                        <a href="/import-model" class="inline-flex items-center gap-1.5 text-xs text-[var(--color-text-secondary)] hover:text-[var(--color-primary)] bg-transparent hover:bg-[var(--color-primary)]/10 border border-[var(--color-border-subtle)] hover:border-[var(--color-primary)]/30 rounded-md py-1.5 px-2.5 transition-colors">
                            <i class="fas fa-upload text-[10px]"></i>
                            <span>Import Model</span>
                        </a>
                        <a href="https://localai.io/basics/getting_started/" target="_blank" class="inline-flex items-center gap-1.5 text-xs text-[var(--color-text-secondary)] hover:text-[var(--color-primary)] bg-transparent hover:bg-[var(--color-primary)]/10 border border-[var(--color-border-subtle)] hover:border-[var(--color-primary)]/30 rounded-md py-1.5 px-2.5 transition-colors">
                            <i class="fas fa-book text-[10px]"></i>
                            <span>Documentation</span>
                        </a>
                    </div>

                    {{ if ne (len .Models) 0 }}
                    <div class="mt-8 pt-6 border-t border-[var(--color-primary-border)]/20">
                        <h3 class="text-lg font-semibold text-[var(--color-text-primary)] mb-2 flex items-center">
                            <i class="fas fa-file-alt mr-2 text-[var(--color-primary)] text-sm"></i>
                            Detected Model Files
                        </h3>
                        <p class="text-xs text-[var(--color-text-secondary)] mb-4">These models were found but don't have configuration files yet</p>
                        <div class="flex flex-wrap gap-2 justify-center">
                            {{ range .Models }}
                            <div class="bg-[var(--color-bg-primary)] border border-[var(--color-primary-border)]/20 rounded px-2 py-1 flex items-center gap-2">
                                <i class="fas fa-brain text-xs text-[var(--color-primary)]"></i>
                                <span class="text-xs text-[var(--color-text-primary)] font-medium">{{.}}</span>
                            </div>              
                            {{end}}
                        </div>
                    </div>
                    {{end}}
                </div>
            </div>
            {{ else }}
            <!-- Models Table -->
            {{ $modelsN := len .ModelsConfig}}
            {{ $modelsN = add $modelsN (len .Models)}}
            <div class="mb-6">
                <div class="flex items-center justify-between gap-3 mb-1">
                    <div>
                        <h2 class="h3 flex items-center">
                            <i class="fas fa-brain mr-2 text-[var(--color-primary)] text-sm"></i>
                            Installed Models
                        </h2>
                        <p class="text-sm text-[var(--color-text-secondary)] mt-0.5">
                            <span class="text-[var(--color-primary)] font-medium">{{$modelsN}}</span> model{{if gt $modelsN 1}}s{{end}} ready to use
                        </p>
                    </div>
                    <button id="reload-models-btn" type="button" title="Update models list from disk"
                        class="inline-flex items-center gap-1.5 text-xs text-[var(--color-text-secondary)] hover:text-[var(--color-primary)] bg-transparent hover:bg-[var(--color-primary)]/10 border border-[var(--color-border-subtle)] hover:border-[var(--color-primary)]/30 rounded-md py-1.5 px-2.5 transition-colors">
                        <i class="fas fa-sync-alt text-[10px]"></i>
                        <span>Update</span>
                    </button>
                </div>
            </div>
            
            <div class="overflow-x-auto mb-8">
                <table class="w-full border-collapse">
                    <thead>
                        <tr class="border-b border-[var(--color-bg-secondary)]">
                            <th class="text-left p-2 text-xs font-semibold text-[var(--color-text-secondary)]">Name</th>
                            <th class="text-left p-2 text-xs font-semibold text-[var(--color-text-secondary)]">Status</th>
                            <th class="text-left p-2 text-xs font-semibold text-[var(--color-text-secondary)]">Backend</th>
                            <th class="text-left p-2 text-xs font-semibold text-[var(--color-text-secondary)]">Use Cases</th>
                            <th class="text-right p-2 text-xs font-semibold text-[var(--color-text-secondary)]">Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        {{$galleryConfig:=.GalleryConfig}}
                        {{ $loadedModels := .LoadedModels }}
                        
                        {{ range .ModelsConfig }}
                        {{ $backendCfg := . }}
                        {{ $cfg:= index $galleryConfig .Name}}
                        <tr class="hover:bg-[var(--color-bg-secondary)]/50 border-b border-[var(--color-bg-secondary)] transition-colors">
                            <!-- Name Column -->
                            <td class="p-2">
                                <div class="flex items-center gap-2">
                                    <div class="relative flex-shrink-0">
                                        {{ if and $cfg $cfg.Icon }}
                                        <img src="{{$cfg.Icon}}" class="w-4 h-4 object-contain" alt="{{.Name}} icon">
                                        {{ else }}
                                        <i class="fas fa-brain text-xs text-[var(--color-primary)]"></i>
                                        {{ end }}
                                        {{ if index $loadedModels .Name }}
                                        <div class="absolute -top-0.5 -right-0.5 w-2 h-2 bg-[var(--color-success)] rounded-full border border-[var(--color-bg-secondary)]"></div>
                                        {{ end }}
                                    </div>
                                    <span class="text-xs text-[var(--color-text-primary)] font-medium truncate">{{.Name}}</span>
                                    <a href="/models/edit/{{.Name}}" 
                                       class="text-[var(--color-primary)]/60 hover:text-[var(--color-primary)] hover:bg-[var(--color-primary)]/10 rounded p-0.5 transition-colors ml-1 flex-shrink-0"
                                       title="Edit {{.Name}}">
                                        <i class="fas fa-edit text-[10px]"></i>
                                    </a>
                                </div>
                            </td>
                            
                            <!-- Status Column -->
                            <td class="p-2">
                                <div class="flex flex-wrap gap-1">
                                    {{ if index $loadedModels .Name }}
                                    <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--color-success)]/10 text-green-300">
                                        <i class="fas fa-circle text-[8px] mr-1"></i>Running
                                    </span>
                                    {{ end }}
                                    {{ if and $backendCfg (or (ne $backendCfg.MCP.Servers "") (ne $backendCfg.MCP.Stdio ""))  }}
                                    <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--color-accent-light)] text-[var(--color-accent)]">
                                        <i class="fas fa-plug text-[8px] mr-1"></i>MCP
                                    </span>
                                    {{ end }}
                                </div>
                            </td>
                            
                            <!-- Backend Column -->
                            <td class="p-2">
                                {{ if .Backend }}
                                <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--color-primary)]/10 text-[var(--color-primary)]">
                                    <i class="fas fa-cog text-[8px] mr-1"></i>{{.Backend}}
                                </span>
                                {{ else }}
                                <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-yellow-500/10 text-yellow-300">
                                    <i class="fas fa-magic text-[8px] mr-1"></i>Auto
                                </span>
                                {{ end }}
                            </td>
                            
                            <!-- Use Cases Column -->
                            <td class="p-2">
                                <div class="flex flex-wrap gap-1">
                                    {{ range .KnownUsecaseStrings }}
                                    {{ if eq . "FLAG_CHAT" }}
                                    <a href="chat/{{$backendCfg.Name}}" onclick="sessionStorage.setItem('localai_create_new_chat', 'true');" class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--color-primary)]/10 text-[var(--color-primary)] hover:bg-[var(--color-primary)]/20 transition-colors" title="Chat">
                                        <i class="fas fa-comment-alt text-[8px] mr-1"></i>Chat
                                    </a>
                                    {{ end }}
                                    {{ if eq . "FLAG_IMAGE" }}
                                    <a href="image/{{$backendCfg.Name}}" class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--color-success)]/10 text-green-300 hover:bg-[var(--color-success)]/20 transition-colors" title="Image">
                                        <i class="fas fa-image text-[8px] mr-1"></i>Image
                                    </a>
                                    {{ end }}
                                    {{ if eq . "FLAG_TTS" }}
                                    <a href="tts/{{$backendCfg.Name}}" class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--color-accent-light)] text-[var(--color-accent)] hover:bg-[var(--color-accent-light)] transition-colors" title="TTS">
                                        <i class="fas fa-microphone text-[8px] mr-1"></i>TTS
                                    </a>
                                    {{ end }}
                                    {{ if eq . "FLAG_SOUND_GENERATION" }}
                                    <a href="sound/{{$backendCfg.Name}}" class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--color-primary)]/10 text-[var(--color-primary)] hover:bg-[var(--color-primary)]/20 transition-colors" title="Sound">
                                        <i class="fas fa-waveform-lines text-[8px] mr-1"></i>Sound
                                    </a>
                                    {{ end }}
                                    {{ end }}
                                </div>
                            </td>
                            
                            <!-- Actions Column -->
                            <td class="p-2">
                                <div class="flex items-center justify-end gap-1">
                                    {{ if index $loadedModels .Name }}
                                    <button type="button" class="text-red-400/60 hover:text-red-400 hover:bg-red-500/10 rounded p-1 transition-colors"
                                        onclick="handleStopModel('{{.Name}}')"
                                        title="Stop {{.Name}}">
                                        <i class="fas fa-stop text-xs"></i>
                                    </button>
                                    {{ end }}
                                    <button type="button" class="text-red-400/60 hover:text-red-400 hover:bg-red-500/10 rounded p-1 transition-colors"
                                        onclick="handleDeleteModel('{{.Name}}')"
                                        title="Delete {{.Name}}">
                                        <i class="fas fa-trash-alt text-xs"></i>
                                    </button>
                                </div>
                            </td>
                        </tr>
                        {{ end }}
                        
                        <!-- Models without config -->
                        {{ range .Models }}
                        <tr class="hover:bg-[var(--color-bg-secondary)]/50 border-b border-[var(--color-bg-secondary)] transition-colors">
                            <td class="p-2">
                                <div class="flex items-center gap-2">
                                    <i class="fas fa-brain text-xs text-[var(--color-text-secondary)]"></i>
                                    <span class="text-xs text-[var(--color-text-primary)] font-medium truncate">{{.}}</span>
                                </div>
                            </td>
                            <td class="p-2">
                                <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-orange-500/10 text-orange-300">
                                    <i class="fas fa-exclamation-triangle text-[8px] mr-1"></i>No Config
                                </span>
                            </td>
                            <td class="p-2">
                                <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-yellow-500/10 text-yellow-300">
                                    <i class="fas fa-magic text-[8px] mr-1"></i>Auto
                                </span>
                            </td>
                            <td class="p-2">
                                <span class="text-xs text-[var(--color-text-secondary)]">—</span>
                            </td>
                            <td class="p-2">
                                <span class="text-xs text-[var(--color-text-secondary)]">—</span>
                            </td>
                        </tr>
                        {{end}}
                    </tbody>
                </table>
            </div>
            {{ end }}
        </div>

        <!-- Backends Section -->
        <div class="mt-8">
            <div class="mb-6">
                <div class="flex items-center justify-between mb-1">
                    <h2 class="h3 flex items-center">
                        <i class="fas fa-cogs mr-2 text-[var(--color-accent)] text-sm"></i>
                        Installed Backends
                    </h2>
                    {{ if gt (len .InstalledBackends) 0 }}
                    <button type="button"
                        @click="reinstallAllBackends()"
                        :disabled="reinstallingAll"
                        class="inline-flex items-center gap-1.5 text-xs text-[var(--color-text-secondary)] hover:text-[var(--color-primary)] bg-transparent hover:bg-[var(--color-primary)]/10 border border-[var(--color-border-subtle)] hover:border-[var(--color-primary)]/30 rounded-md py-1.5 px-2.5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:border-[var(--color-border-subtle)]"
                        title="Reinstall all backends">
                        <i class="fas fa-arrow-rotate-right text-[10px]" :class="reinstallingAll ? 'fa-spin' : ''"></i>
                        <span x-text="reinstallingAll ? 'Reinstalling...' : 'Reinstall All'"></span>
                    </button>
                    {{ end }}
                </div>
                <p class="text-sm text-[var(--color-text-secondary)] mb-4">
                    <span class="text-[var(--color-accent)] font-medium">{{len .InstalledBackends}}</span> backend{{if gt (len .InstalledBackends) 1}}s{{end}} ready to use
                </p>
            </div>

            {{ if eq (len .InstalledBackends) 0 }}
            <!-- No backends state -->
            <div class="card p-8">
                <div class="text-center max-w-4xl mx-auto">
                    <div class="inline-flex items-center justify-center w-12 h-12 rounded-full bg-[var(--color-accent-light)] border border-[var(--color-accent-border)] mb-4">
                        <i class="text-[var(--color-accent)] text-xl fas fa-cogs"></i>
                    </div>
                    <h2 class="h2 mb-2">No backends installed yet</h2>
                    <p class="text-sm text-[var(--color-text-secondary)] mb-6">Backends power your AI models. Install them from the backend gallery to get started</p>
                    
                    <div class="flex flex-wrap justify-center gap-2">
                        <a href="/browse/backends" class="inline-flex items-center gap-1.5 text-xs text-[var(--color-text-secondary)] hover:text-[var(--color-primary)] bg-transparent hover:bg-[var(--color-primary)]/10 border border-[var(--color-border-subtle)] hover:border-[var(--color-primary)]/30 rounded-md py-1.5 px-2.5 transition-colors">
                            <i class="fas fa-cogs text-[10px]"></i>
                            <span>Browse Backend Gallery</span>
                        </a>
                        <a href="https://localai.io/backends/" target="_blank" class="inline-flex items-center gap-1.5 text-xs text-[var(--color-text-secondary)] hover:text-[var(--color-primary)] bg-transparent hover:bg-[var(--color-primary)]/10 border border-[var(--color-border-subtle)] hover:border-[var(--color-primary)]/30 rounded-md py-1.5 px-2.5 transition-colors">
                            <i class="fas fa-book text-[10px]"></i>
                            <span>Documentation</span>
                        </a>
                    </div>
                </div>
            </div>
            {{ else }}
            <!-- Backends Table -->
            <div class="overflow-x-auto mb-8">
                <table class="w-full border-collapse">
                    <thead>
                        <tr class="border-b border-[var(--color-bg-secondary)]">
                            <th class="text-left p-2 text-xs font-semibold text-[var(--color-text-secondary)]">Name</th>
                            <th class="text-left p-2 text-xs font-semibold text-[var(--color-text-secondary)]">Type</th>
                            <th class="text-left p-2 text-xs font-semibold text-[var(--color-text-secondary)]">Metadata</th>
                            <th class="text-right p-2 text-xs font-semibold text-[var(--color-text-secondary)]">Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        {{ range .InstalledBackends }}
                        <tr class="hover:bg-[var(--color-bg-secondary)]/50 border-b border-[var(--color-bg-secondary)] transition-colors" data-backend-name="{{.Name}}" data-is-system="{{.IsSystem}}">
                            <!-- Name Column -->
                            <td class="p-2">
                                <div class="flex items-center gap-2">
                                    <i class="fas fa-cog text-xs text-[var(--color-accent)]"></i>
                                    <span class="text-xs text-[var(--color-text-primary)] font-medium truncate">{{.Name}}</span>
                                </div>
                            </td>
                            
                            <!-- Type Column -->
                            <td class="p-2">
                                <div class="flex flex-wrap gap-1">
                                    {{ if .IsSystem }}
                                    <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-blue-500/10 text-blue-300">
                                        <i class="fas fa-shield-alt text-[8px] mr-1"></i>System
                                    </span>
                                    {{ else }}
                                    <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--color-success)]/10 text-green-300">
                                        <i class="fas fa-download text-[8px] mr-1"></i>User
                                    </span>
                                    {{ end }}
                                    {{ if .IsMeta }}
                                    <span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-[var(--color-accent-light)] text-[var(--color-accent)]">
                                        <i class="fas fa-layer-group text-[8px] mr-1"></i>Meta
                                    </span>
                                    {{ end }}
                                </div>
                            </td>
                            
                            <!-- Metadata Column -->
                            <td class="p-2">
                                <div class="flex flex-col gap-1">
                                    {{ if and .Metadata .Metadata.Alias }}
                                    <span class="text-xs text-[var(--color-text-secondary)]">
                                        <i class="fas fa-tag text-[8px] mr-1"></i>Alias: <span class="text-[var(--color-text-primary)]">{{.Metadata.Alias}}</span>
                                    </span>
                                    {{ end }}
                                    {{ if and .Metadata .Metadata.MetaBackendFor }}
                                    <span class="text-xs text-[var(--color-text-secondary)]">
                                        <i class="fas fa-link text-[8px] mr-1"></i>For: <span class="text-[var(--color-accent)]">{{.Metadata.MetaBackendFor}}</span>
                                    </span>
                                    {{ end }}
                                    {{ if and .Metadata .Metadata.InstalledAt }}
                                    <span class="text-xs text-[var(--color-text-secondary)]">
                                        <i class="fas fa-calendar text-[8px] mr-1"></i>{{.Metadata.InstalledAt}}
                                    </span>
                                    {{ end }}
                                </div>
                            </td>
                            
                            <!-- Actions Column -->
                            <td class="p-2">
                                <div class="flex items-center justify-end gap-1">
                                    {{ if not .IsSystem }}
                                    <button type="button"
                                        @click="reinstallBackend('{{.Name}}')"
                                        :disabled="reinstallingBackends['{{.Name}}']"
                                        class="text-[var(--color-primary)]/60 hover:text-[var(--color-primary)] hover:bg-[var(--color-primary)]/10 disabled:opacity-50 disabled:cursor-not-allowed rounded p-1 transition-colors"
                                        title="Reinstall {{.Name}}">
                                        <i class="fas fa-arrow-rotate-right text-xs" :class="reinstallingBackends['{{.Name}}'] ? 'fa-spin' : ''"></i>
                                    </button>
                                    <button type="button"
                                        @click="deleteBackend('{{.Name}}')"
                                        class="text-red-400/60 hover:text-red-400 hover:bg-red-500/10 rounded p-1 transition-colors"
                                        title="Delete {{.Name}}">
                                        <i class="fas fa-trash-alt text-xs"></i>
                                    </button>
                                    {{ else }}
                                    <span class="text-xs text-[var(--color-text-secondary)]">—</span>
                                    {{ end }}
                                </div>
                            </td>
                        </tr>
                        {{end}}
                    </tbody>
                </table>
            </div>
            {{ end }}
        </div>
    </div>

</div>

<script>
// Resource Monitor component (GPU if available, otherwise RAM)
function resourceMonitor() {
    return {
        resourceData: null,
        pollInterval: null,
        
        async fetchResourceData() {
            try {
                const response = await fetch('/api/resources');
                if (response.ok) {
                    this.resourceData = await response.json();
                }
            } catch (error) {
                console.error('Error fetching resource data:', error);
            }
        },
        
        startPolling() {
            // Initial fetch
            this.fetchResourceData();
            // Poll every 5 seconds
            this.pollInterval = setInterval(() => this.fetchResourceData(), 5000);
        },
        
        stopPolling() {
            if (this.pollInterval) {
                clearInterval(this.pollInterval);
            }
        }
    }
}

// Helper function to format bytes
function formatBytes(bytes) {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
}

// Alpine.js component for index dashboard
function indexDashboard() {
    return {
        notifications: [],
        reinstallingBackends: {},
        reinstallingAll: false,
        backendJobs: {},
        
        init() {
            // Poll for job progress every 600ms
            setInterval(() => this.pollJobs(), 600);
        },
        
        addNotification(message, type = 'success') {
            const id = Date.now();
            this.notifications.push({ id, message, type });
            // Auto-dismiss after 5 seconds
            setTimeout(() => this.dismissNotification(id), 5000);
        },
        
        dismissNotification(id) {
            this.notifications = this.notifications.filter(n => n.id !== id);
        },
        
        async reinstallBackend(backendName) {
            if (this.reinstallingBackends[backendName]) {
                return; // Already reinstalling
            }
            
            try {
                this.reinstallingBackends[backendName] = true;
                const response = await fetch(`/api/backends/install/${encodeURIComponent(backendName)}`, {
                    method: 'POST'
                });
                
                const data = await response.json();
                
                if (response.ok && data.jobID) {
                    this.backendJobs[backendName] = data.jobID;
                    this.addNotification(`Reinstalling backend "${backendName}"...`, 'success');
                } else {
                    this.reinstallingBackends[backendName] = false;
                    this.addNotification(`Failed to start reinstall: ${data.error || 'Unknown error'}`, 'error');
                }
            } catch (error) {
                console.error('Error reinstalling backend:', error);
                this.reinstallingBackends[backendName] = false;
                this.addNotification(`Failed to reinstall backend: ${error.message}`, 'error');
            }
        },
        
        async reinstallAllBackends() {
            if (this.reinstallingAll) {
                return; // Already reinstalling
            }
            
            if (!confirm('Are you sure you want to reinstall all backends? This may take some time.')) {
                return;
            }
            
            this.reinstallingAll = true;
            
            // Get all non-system backends from the page using data attributes
            const backendRows = document.querySelectorAll('tr[data-backend-name]');
            const backendsToReinstall = [];
            
            backendRows.forEach(row => {
                const backendName = row.getAttribute('data-backend-name');
                const isSystem = row.getAttribute('data-is-system') === 'true';
                if (backendName && !isSystem && !this.reinstallingBackends[backendName]) {
                    backendsToReinstall.push(backendName);
                }
            });
            
            if (backendsToReinstall.length === 0) {
                this.reinstallingAll = false;
                this.addNotification('No backends available to reinstall', 'error');
                return;
            }
            
            this.addNotification(`Starting reinstall of ${backendsToReinstall.length} backend(s)...`, 'success');
            
            // Reinstall all backends sequentially to avoid overwhelming the system
            for (const backendName of backendsToReinstall) {
                await this.reinstallBackend(backendName);
                // Small delay between installations
                await new Promise(resolve => setTimeout(resolve, 500));
            }
            
            // Don't set reinstallingAll to false here - let pollJobs handle it when all jobs complete
            // This allows the UI to show the batch operation is in progress
        },
        
        async pollJobs() {
            for (const [backendName, jobID] of Object.entries(this.backendJobs)) {
                try {
                    const response = await fetch(`/api/backends/job/${jobID}`);
                    const jobData = await response.json();
                    
                    if (jobData.completed) {
                        delete this.backendJobs[backendName];
                        this.reinstallingBackends[backendName] = false;
                        this.addNotification(`Backend "${backendName}" reinstalled successfully!`, 'success');
                        
                        // Only reload if not in batch mode and no other jobs are running
                        if (!this.reinstallingAll && Object.keys(this.backendJobs).length === 0) {
                            setTimeout(() => {
                                window.location.reload();
                            }, 1500);
                        }
                    }
                    
                    if (jobData.error || (jobData.message && jobData.message.startsWith('error:'))) {
                        delete this.backendJobs[backendName];
                        this.reinstallingBackends[backendName] = false;
                        let errorMessage = 'Unknown error';
                        if (typeof jobData.error === 'string') {
                            errorMessage = jobData.error;
                        } else if (jobData.error && typeof jobData.error === 'object') {
                            const errorKeys = Object.keys(jobData.error);
                            if (errorKeys.length > 0) {
                                errorMessage = jobData.error.message || jobData.error.error || jobData.error.Error || JSON.stringify(jobData.error);
                            } else {
                                errorMessage = jobData.message || 'Unknown error';
                            }
                        } else if (jobData.message) {
                            errorMessage = jobData.message;
                        }
                        if (errorMessage.startsWith('error: ')) {
                            errorMessage = errorMessage.substring(7);
                        }
                        this.addNotification(`Error reinstalling backend "${backendName}": ${errorMessage}`, 'error');
                        
                        // If batch mode and all jobs are done (completed or errored), reload
                        if (this.reinstallingAll && Object.keys(this.backendJobs).length === 0) {
                            this.reinstallingAll = false;
                            setTimeout(() => {
                                window.location.reload();
                            }, 2000);
                        }
                    }
                } catch (error) {
                    console.error('Error polling job:', error);
                }
            }
            
            // If batch mode completed and no jobs left, reload
            if (this.reinstallingAll && Object.keys(this.backendJobs).length === 0) {
                this.reinstallingAll = false;
                setTimeout(() => {
                    window.location.reload();
                }, 2000);
            }
        },
        
        async deleteBackend(backendName) {
            if (!confirm(`Are you sure you want to delete the backend "${backendName}"?`)) {
                return;
            }
            
            try {
                const response = await fetch(`/api/backends/system/delete/${encodeURIComponent(backendName)}`, {
                    method: 'POST'
                });
                
                const data = await response.json();
                
                if (response.ok && data.success) {
                    this.addNotification(`Backend "${backendName}" deleted successfully!`, 'success');
                    // Reload page after short delay
                    setTimeout(() => {
                        window.location.reload();
                    }, 1500);
                } else {
                    this.addNotification(`Failed to delete backend: ${data.error || 'Unknown error'}`, 'error');
                }
            } catch (error) {
                console.error('Error deleting backend:', error);
                this.addNotification(`Failed to delete backend: ${error.message}`, 'error');
            }
        }
    }
}

async function handleStopModel(modelName) {
    if (!confirm('Are you sure you wish to stop this model?')) {
        return;
    }
    
    try {
        const response = await fetch('/backend/shutdown', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ model: modelName })
        });
        
        if (response.ok) {
            window.location.reload();
        } else {
            alert('Failed to stop model');
        }
    } catch (error) {
        console.error('Error stopping model:', error);
        alert('Failed to stop model');
    }
}

async function handleDeleteModel(modelName) {
    if (!confirm('Are you sure you wish to delete this model?')) {
        return;
    }
    
    try {
        const response = await fetch(`/api/models/delete/${encodeURIComponent(modelName)}`, {
            method: 'POST'
        });
        
        if (response.ok) {
            window.location.reload();
        } else {
            alert('Failed to delete model');
        }
    } catch (error) {
        console.error('Error deleting model:', error);
        alert('Failed to delete model');
    }
}

// Handle reload models button
document.addEventListener('DOMContentLoaded', function() {
    const reloadBtn = document.getElementById('reload-models-btn');
    if (reloadBtn) {
        reloadBtn.addEventListener('click', function() {
            const button = this;
            const originalText = button.querySelector('span').textContent;
            const icon = button.querySelector('i');

            // Show loading state
            button.disabled = true;
            button.querySelector('span').textContent = 'Updating...';
            icon.classList.add('fa-spin');

            // Make the API call
            fetch('/models/reload', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                }
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    // Show success state briefly
                    button.querySelector('span').textContent = 'Updated!';
                    icon.classList.remove('fa-spin', 'fa-sync-alt');
                    icon.classList.add('fa-check');

                    // Reload the page after a short delay
                    setTimeout(() => {
                        window.location.reload();
                    }, 1000);
                } else {
                    // Show error state
                    button.querySelector('span').textContent = 'Error!';
                    icon.classList.remove('fa-spin');
                    console.error('Failed to reload models:', data.error);

                    // Reset button after delay
                    setTimeout(() => {
                        button.disabled = false;
                        button.querySelector('span').textContent = originalText;
                        icon.classList.remove('fa-check');
                        icon.classList.add('fa-sync-alt');
                    }, 3000);
                }
            })
            .catch(error => {
                // Show error state
                button.querySelector('span').textContent = 'Error!';
                icon.classList.remove('fa-spin');
                console.error('Error reloading models:', error);

                // Reset button after delay
                setTimeout(() => {
                    button.disabled = false;
                    button.querySelector('span').textContent = originalText;
                    icon.classList.remove('fa-check');
                    icon.classList.add('fa-sync-alt');
                }, 3000);
            });
        });
    }
});
</script>

    {{template "views/partials/footer" .}}
    </div>
  </main>
</div>

</body>
</html>
