<template>
  <main class="flex flex-col flex-1 h-full min-h-0 relative">
    <!-- Welcome / Empty State -->
    <div v-if="!layers.some(l => l.sprites.length)" class="flex-1 flex flex-col items-center justify-center pb-12">
      <div class="w-full max-w-[90rem] px-4 sm:px-6 lg:px-8 flex flex-col gap-8 lg:gap-12 items-start pt-4 sm:pt-8 lg:pt-16">
        <!-- Top Row: Upload Field & Video Side by Side -->
        <div class="w-full grid grid-cols-1 lg:grid-cols-2 gap-6 lg:gap-8">
          <!-- File Uploader Component -->
          <div class="glass-panel p-2 rounded-2xl shadow-xl shadow-indigo-500/10 border border-indigo-50/50 dark:border-gray-700 h-full flex flex-col">
            <file-uploader @upload-sprites="handleSpritesUpload" />
          </div>

          <!-- Video Showcase -->
          <div class="rounded-2xl overflow-hidden shadow-2xl border border-gray-200 dark:border-gray-800 bg-gray-900 relative group h-full min-h-[300px] lg:min-h-0">
            <video autoplay controls loop muted playsinline class="w-full h-full object-cover opacity-90 group-hover:opacity-100 transition-opacity duration-500">
              <source :src="tutVideo" type="video/mp4" />
            </video>
          </div>
        </div>

        <!-- Bottom Section: Hero Text & Features -->
        <div class="w-full grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12">
          <!-- Hero Text -->
          <div class="text-left">
            <h1 class="text-4xl sm:text-5xl md:text-6xl font-extrabold tracking-tight mb-6 text-gray-900 dark:text-gray-50 leading-[1.1]">Welcome to <span class="text-indigo-600 dark:text-indigo-400">Spritesheet generator</span></h1>
            <p class="text-lg text-gray-600 dark:text-gray-300 leading-relaxed">
              Create spritesheets for your game development and animation projects with our completely free, open-source Spritesheet generator. This powerful online tool lets you upload individual sprite images and automatically arrange them into optimized sprite sheets with customizable layouts -
              perfect for indie developers, animators, and studios of any size.
            </p>
          </div>

          <!-- Key Features Grid -->
          <div class="space-y-6">
            <h2 class="text-xl font-bold text-gray-900 dark:text-gray-100 flex items-center gap-2"><i class="fas fa-star text-yellow-500 text-sm"></i> Key features</h2>

            <div class="grid grid-cols-1 sm:grid-cols-2 gap-4 text-left">
              <!-- Features List -->
              <div class="card p-4 hover:border-indigo-500/30 transition-colors flex gap-4 items-start">
                <div class="w-8 h-8 rounded-lg bg-indigo-100 dark:bg-indigo-900/30 flex items-center justify-center text-indigo-600 dark:text-indigo-400 shrink-0">
                  <i class="fas fa-edit text-sm"></i>
                </div>
                <div>
                  <h3 class="font-bold text-sm text-gray-900 dark:text-gray-100 mb-0.5">Free sprite editor</h3>
                  <p class="text-xs text-gray-500 dark:text-gray-400 leading-snug">Edit, organize, and optimize directly in browser.</p>
                </div>
              </div>

              <div class="card p-4 hover:border-indigo-500/30 transition-colors flex gap-4 items-start">
                <div class="w-8 h-8 rounded-lg bg-indigo-100 dark:bg-indigo-900/30 flex items-center justify-center text-indigo-600 dark:text-indigo-400 shrink-0">
                  <i class="fas fa-magic text-sm"></i>
                </div>
                <div>
                  <h3 class="font-bold text-sm text-gray-900 dark:text-gray-100 mb-0.5">Automatic generation</h3>
                  <p class="text-xs text-gray-500 dark:text-gray-400 leading-snug">Convert images into efficient sprite atlases.</p>
                </div>
              </div>

              <div class="card p-4 hover:border-indigo-500/30 transition-colors flex gap-4 items-start">
                <div class="w-8 h-8 rounded-lg bg-indigo-100 dark:bg-indigo-900/30 flex items-center justify-center text-indigo-600 dark:text-indigo-400 shrink-0">
                  <i class="fas fa-th text-sm"></i>
                </div>
                <div>
                  <h3 class="font-bold text-sm text-gray-900 dark:text-gray-100 mb-0.5">Customizable layouts</h3>
                  <p class="text-xs text-gray-500 dark:text-gray-400 leading-snug">Adjust spacing for pixel-perfect results.</p>
                </div>
              </div>

              <div class="card p-4 hover:border-indigo-500/30 transition-colors flex gap-4 items-start">
                <div class="w-8 h-8 rounded-lg bg-indigo-100 dark:bg-indigo-900/30 flex items-center justify-center text-indigo-600 dark:text-indigo-400 shrink-0">
                  <i class="fas fa-play-circle text-sm"></i>
                </div>
                <div>
                  <h3 class="font-bold text-sm text-gray-900 dark:text-gray-100 mb-0.5">Animation preview</h3>
                  <p class="text-xs text-gray-500 dark:text-gray-400 leading-snug">Test animations before exporting.</p>
                </div>
              </div>

              <div class="card p-4 hover:border-indigo-500/30 transition-colors flex gap-4 items-start">
                <div class="w-8 h-8 rounded-lg bg-indigo-100 dark:bg-indigo-900/30 flex items-center justify-center text-indigo-600 dark:text-indigo-400 shrink-0">
                  <i class="fas fa-gamepad text-sm"></i>
                </div>
                <div>
                  <h3 class="font-bold text-sm text-gray-900 dark:text-gray-100 mb-0.5">Cross-platform</h3>
                  <p class="text-xs text-gray-500 dark:text-gray-400 leading-snug">Works with Unity, Godot, etc.</p>
                </div>
              </div>

              <div class="card p-4 hover:border-indigo-500/30 transition-colors flex gap-4 items-start">
                <div class="w-8 h-8 rounded-lg bg-indigo-100 dark:bg-indigo-900/30 flex items-center justify-center text-indigo-600 dark:text-indigo-400 shrink-0">
                  <i class="fas fa-globe text-sm"></i>
                </div>
                <div>
                  <h3 class="font-bold text-sm text-gray-900 dark:text-gray-100 mb-0.5">No installation</h3>
                  <p class="text-xs text-gray-500 dark:text-gray-400 leading-snug">Use our web-based tool instantly.</p>
                </div>
              </div>

              <div class="card p-4 hover:border-indigo-500/30 transition-colors flex gap-4 items-start">
                <div class="w-8 h-8 rounded-lg bg-indigo-100 dark:bg-indigo-900/30 flex items-center justify-center text-indigo-600 dark:text-indigo-400 shrink-0">
                  <i class="fas fa-layer-group text-sm"></i>
                </div>
                <div>
                  <h3 class="font-bold text-sm text-gray-900 dark:text-gray-100 mb-0.5">Batch processing</h3>
                  <p class="text-xs text-gray-500 dark:text-gray-400 leading-snug">Upload/process multiple sprites.</p>
                </div>
              </div>

              <div class="card p-4 hover:border-indigo-500/30 transition-colors flex gap-4 items-start">
                <div class="w-8 h-8 rounded-lg bg-indigo-100 dark:bg-indigo-900/30 flex items-center justify-center text-indigo-600 dark:text-indigo-400 shrink-0">
                  <i class="fas fa-file-export text-sm"></i>
                </div>
                <div>
                  <h3 class="font-bold text-sm text-gray-900 dark:text-gray-100 mb-0.5">Export options</h3>
                  <p class="text-xs text-gray-500 dark:text-gray-400 leading-snug">Download PNG, JSON, ZIP, or GIF.</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Main Editor Interface -->
    <div v-else class="flex flex-col lg:flex-row gap-6 h-full min-h-[600px] lg:overflow-hidden">
      <!-- Sidebar Controls -->
      <aside class="flex flex-col w-full lg:w-[340px] gap-4 shrink-0 lg:overflow-hidden">
        <div class="glass-panel rounded-xl flex flex-col h-full lg:overflow-hidden border border-gray-200 dark:border-gray-700/60 shadow-lg">
          <!-- Sidebar Header -->
          <div class="px-5 py-4 border-b border-gray-200/50 dark:border-gray-700/50 flex items-center justify-between shrink-0 bg-gray-50/50 dark:bg-gray-800/10">
            <h2 class="text-sm font-bold uppercase tracking-wider text-gray-500 dark:text-gray-400">Editor Tools</h2>
            <button @click="openFileDialog" class="btn btn-primary btn-sm shadow-indigo-500/20" title="Add more sprites"><i class="fas fa-plus mr-1"></i> Add</button>
          </div>

          <!-- Scrollable Content -->
          <div class="flex-1 overflow-y-auto overflow-x-hidden p-5 space-y-6 scrollbar-thin">
            <!-- Layers -->
            <section>
              <div class="flex items-center justify-between mb-3">
                <h3 class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide">Layers</h3>
                <button @click="addLayer()" class="text-xs p-1 text-indigo-600 dark:text-indigo-400 hover:bg-indigo-50 dark:hover:bg-indigo-900/20 rounded transition-colors" title="Add Layer"><i class="fas fa-layer-group mr-1"></i> New</button>
              </div>
              <div class="space-y-2">
                <div
                  v-for="layer in layers"
                  :key="layer.id"
                  class="group flex items-center gap-2 p-2 rounded-lg border transition-all duration-200"
                  :class="activeLayerId === layer.id ? 'bg-white dark:bg-gray-800 border-indigo-500 ring-1 ring-indigo-500 shadow-sm' : 'bg-gray-50 dark:bg-gray-800/40 border-transparent hover:border-gray-200 dark:hover:border-gray-700'"
                >
                  <!-- Visibility Toggle -->
                  <button @click.stop="layer.visible = !layer.visible" class="w-6 h-6 flex items-center justify-center rounded text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors">
                    <i :class="layer.visible ? 'fas fa-eye' : 'fas fa-eye-slash'" class="text-xs"></i>
                  </button>

                  <!-- Layer Name -->
                  <div class="flex-1 min-w-0">
                    <input
                      v-if="editingLayerId === layer.id"
                      v-model="editingLayerName"
                      @blur="finishEditingLayer"
                      @keyup.enter="finishEditingLayer"
                      @keyup.esc="cancelEditingLayer"
                      ref="layerNameInput"
                      class="w-full text-sm bg-transparent border-b border-indigo-500 outline-none p-0 text-gray-900 dark:text-gray-100"
                    />
                    <button v-else @click="activeLayerId = layer.id" class="w-full text-left text-sm font-medium truncate" :class="activeLayerId === layer.id ? 'text-gray-900 dark:text-gray-100' : 'text-gray-600 dark:text-gray-400'">
                      {{ layer.name }} <span class="text-xs opacity-50 font-normal ml-1">({{ layer.sprites.length }})</span>
                    </button>
                  </div>

                  <!-- Actions -->
                  <div class="flex items-center opacity-0 group-hover:opacity-100 transition-opacity">
                    <button @click="startEditingLayer(layer.id, layer.name)" class="p-1.5 text-gray-400 hover:text-indigo-500 transition-colors" title="Rename"><i class="fas fa-pen text-[10px]"></i></button>
                    <button @click="moveLayer(layer.id, 'up')" class="p-1.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors" title="Move Up"><i class="fas fa-chevron-up text-[10px]"></i></button>
                    <button @click="moveLayer(layer.id, 'down')" class="p-1.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors" title="Move Down"><i class="fas fa-chevron-down text-[10px]"></i></button>
                    <button v-if="layers.length > 1" @click="removeLayer(layer.id)" class="p-1.5 text-gray-400 hover:text-red-500 transition-colors" title="Delete"><i class="fas fa-trash text-[10px]"></i></button>
                  </div>
                </div>
              </div>
            </section>

            <!-- Canvas Grid Settings -->
            <section>
              <h3 class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-3">Grid Layout</h3>
              <div class="card p-3 bg-gray-50/50 dark:bg-gray-800/40 space-y-3">
                <div class="flex items-center justify-between">
                  <label class="text-sm text-gray-600 dark:text-gray-300">Columns</label>
                  <input type="number" v-model.number="columns" min="1" max="20" class="input-field w-16 text-center" />
                </div>
                <div class="flex items-center justify-between">
                  <div class="flex items-center gap-2">
                    <label class="text-sm text-gray-600 dark:text-gray-300">Force Size</label>
                    <input type="checkbox" v-model="settingsStore.manualCellSizeEnabled" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
                  </div>
                  <div v-if="settingsStore.manualCellSizeEnabled" class="flex items-center gap-1">
                    <input v-model.number="settingsStore.manualCellWidth" class="input-field w-14 text-center px-1" placeholder="W" />
                    <span class="text-gray-400 text-xs">x</span>
                    <input v-model.number="settingsStore.manualCellHeight" class="input-field w-14 text-center px-1" placeholder="H" />
                  </div>
                  <span v-else class="text-xs font-mono text-gray-400 bg-gray-100 dark:bg-gray-700 px-2 py-1 rounded">{{ cellSize.width }}×{{ cellSize.height }}px</span>
                </div>
              </div>
            </section>

            <!-- View Options -->
            <section>
              <h3 class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-3">View Options</h3>
              <div class="card p-2 bg-gray-50/50 dark:bg-gray-800/40 grid grid-cols-2 gap-2">
                <Tooltip text="Disable anti-aliasing for crisp pixel art rendering">
                  <button
                    @click="settingsStore.pixelPerfect = !settingsStore.pixelPerfect"
                    :class="settingsStore.pixelPerfect ? 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300' : 'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700'"
                    class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium transition-colors"
                  >
                    <i class="fas fa-th mr-2"></i>Pixel
                  </button>
                </Tooltip>
                <Tooltip text="Show checkerboard background">
                  <button
                    @click="settingsStore.checkerboardEnabled = !settingsStore.checkerboardEnabled"
                    :class="settingsStore.checkerboardEnabled ? 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300' : 'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700'"
                    class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium transition-colors"
                  >
                    <i class="fas fa-chess-board mr-2"></i>Grid
                  </button>
                </Tooltip>
                <Tooltip text="Show selection borders">
                  <button
                    @click="showActiveBorder = !showActiveBorder"
                    :class="showActiveBorder ? 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300' : 'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700'"
                    class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium transition-colors"
                  >
                    <i class="fas fa-vector-square mr-2"></i>Borders
                  </button>
                </Tooltip>
                <Tooltip text="Show sprite coordinates">
                  <button
                    @click="showOffsetLabels = !showOffsetLabels"
                    :class="showOffsetLabels ? 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300' : 'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700'"
                    class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium transition-colors"
                  >
                    <i class="fas fa-tag mr-2"></i>Labels
                  </button>
                </Tooltip>
                <Tooltip text="Compare with ghost overlays" class="col-span-2">
                  <button
                    @click="showAllSprites = !showAllSprites"
                    :class="showAllSprites ? 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300' : 'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700'"
                    class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium transition-colors"
                  >
                    <i class="fas fa-clone mr-2"></i>Ghost compare
                  </button>
                </Tooltip>
              </div>
            </section>

            <!-- Tools -->
            <section>
              <h3 class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-3">Tools</h3>
              <div class="card p-2 bg-gray-50/50 dark:bg-gray-800/40 space-y-2">
                <div class="flex gap-2">
                  <Tooltip text="Select multiple sprites" class="flex-1">
                    <button
                      @click="isMultiSelectMode = !isMultiSelectMode"
                      :class="isMultiSelectMode ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300' : 'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700'"
                      class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium transition-colors"
                    >
                      <i class="fas fa-object-group mr-2"></i>Multi
                    </button>
                  </Tooltip>
                  <Tooltip text="Swap cell positions" class="flex-1">
                    <button
                      @click="allowCellSwap = !allowCellSwap"
                      :class="allowCellSwap ? 'bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-300' : 'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700'"
                      class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium transition-colors"
                    >
                      <i class="fas fa-exchange-alt mr-2"></i>Swap
                    </button>
                  </Tooltip>
                </div>
                <div class="flex items-center justify-between px-2 pt-1 border-t border-gray-100 dark:border-gray-700/50">
                  <span class="text-xs text-gray-600 dark:text-gray-400">Negative Spacing</span>
                  <button
                    @click="settingsStore.negativeSpacingEnabled = !settingsStore.negativeSpacingEnabled"
                    class="relative inline-flex h-5 w-9 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
                    :class="settingsStore.negativeSpacingEnabled ? 'bg-indigo-600' : 'bg-gray-200 dark:bg-gray-700'"
                  >
                    <span class="inline-block h-3 w-3 transform rounded-full bg-white transition-transform" :class="settingsStore.negativeSpacingEnabled ? 'translate-x-5' : 'translate-x-1'" />
                  </button>
                </div>
              </div>
            </section>

            <!-- Alignment Tools -->
            <section>
              <h3 class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-3">Alignment</h3>
              <div class="card p-2 bg-gray-50/50 dark:bg-gray-800/40 grid grid-cols-3 gap-2">
                <Tooltip text="Align sprites to the left edge">
                  <button @click="alignSprites('left')" class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"><i class="fas fa-arrow-left"></i>Left</button>
                </Tooltip>
                <Tooltip text="Center sprites horizontally">
                  <button @click="alignSprites('center')" class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"><i class="fas fa-arrows-left-right"></i>Center</button>
                </Tooltip>
                <Tooltip text="Align sprites to the right edge">
                  <button @click="alignSprites('right')" class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"><i class="fas fa-arrow-right"></i>Right</button>
                </Tooltip>
                <Tooltip text="Align sprites to the top edge">
                  <button @click="alignSprites('top')" class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"><i class="fas fa-arrow-up"></i>Top</button>
                </Tooltip>
                <Tooltip text="Center sprites vertically">
                  <button @click="alignSprites('middle')" class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"><i class="fas fa-arrows-up-down"></i>Middle</button>
                </Tooltip>
                <Tooltip text="Align sprites to the bottom edge">
                  <button @click="alignSprites('bottom')" class="w-full flex items-center justify-start gap-2 p-2 rounded text-xs font-medium text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"><i class="fas fa-arrow-down"></i>Bottom</button>
                </Tooltip>
              </div>
            </section>
          </div>

          <!-- Sidebar Footer (Export) -->
          <div class="p-4 border-t border-gray-200/50 dark:border-gray-700/50 bg-gray-50/50 dark:bg-gray-800/10 space-y-3 shrink-0">
            <div class="grid grid-cols-2 gap-2">
              <button @click="downloadSpritesheet" class="btn btn-secondary btn-sm justify-start" title="Download PNG"><i class="fas fa-image text-indigo-500 w-4"></i> PNG</button>
              <button @click="exportSpritesheetJSON" class="btn btn-secondary btn-sm justify-start" title="Download JSON"><i class="fas fa-code text-indigo-500 w-4"></i> JSON</button>
              <button @click="openGifFpsModal" class="btn btn-secondary btn-sm justify-start" title="Export GIF"><i class="fas fa-film text-pink-500 w-4"></i> GIF</button>
              <button @click="downloadAsZip" class="btn btn-secondary btn-sm justify-start" title="Download ZIP"><i class="fas fa-file-archive text-yellow-500 w-4"></i> ZIP</button>
            </div>
            <button @click="openShareModal" class="btn btn-secondary w-full justify-start"><i class="fas fa-share-alt mr-2 text-indigo-500"></i> Share Project</button>
          </div>
        </div>
      </aside>

      <!-- Main Canvas Area -->
      <div class="flex-1 flex flex-col min-h-0 glass-panel rounded-xl border border-gray-200 dark:border-gray-700/60 shadow-lg overflow-hidden">
        <!-- Tabs / Toolbar -->
        <div class="flex items-center justify-between px-4 py-2 border-b border-gray-200 dark:border-gray-700 bg-gray-50/30 dark:bg-gray-800/20">
          <div class="flex items-center gap-3">
            <div class="flex p-1 bg-gray-100 dark:bg-gray-800 rounded-lg">
              <button
                @click="activeTab = 'canvas'"
                :class="activeTab === 'canvas' ? 'bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 shadow-sm' : 'text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300'"
                class="px-4 py-1.5 rounded-md text-sm font-medium transition-all duration-200"
              >
                <i class="fas fa-th mr-2"></i>Editor
              </button>
              <button
                @click="activeTab = 'preview'"
                :class="activeTab === 'preview' ? 'bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 shadow-sm' : 'text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300'"
                class="px-4 py-1.5 rounded-md text-sm font-medium transition-all duration-200"
              >
                <i class="fas fa-play mr-2"></i>Preview
              </button>
            </div>

            <!-- Background Color (Compact) -->
            <div class="flex items-center gap-2 pl-3 border-l border-gray-200 dark:border-gray-700">
              <span class="text-xs font-medium text-gray-500 uppercase">Bg</span>
              <div class="flex items-center gap-1">
                <select v-model="bgSelectValue" class="text-xs border-none bg-transparent dark:text-gray-300 focus:ring-0 cursor-pointer pr-8">
                  <option value="transparent">None</option>
                  <option value="#ffffff">White</option>
                  <option value="#000000">Black</option>
                  <option value="#f9fafb">Gray</option>
                  <option value="custom">Custom</option>
                </select>
                <div v-if="bgSelectValue === 'custom'" class="relative w-5 h-5 rounded-full overflow-hidden border border-gray-300 dark:border-gray-600 shadow-sm">
                  <input type="color" v-model="customColor" @input="updateCustomColor" class="absolute -top-1 -left-1 w-8 h-8 cursor-pointer p-0 border-0 opacity-0" />
                  <div class="w-full h-full" :style="{ backgroundColor: customColor }"></div>
                </div>
              </div>
            </div>
          </div>

          <div class="flex items-center gap-2">
            <div class="flex items-center bg-gray-100 dark:bg-gray-800 rounded-lg p-1">
              <button @click="zoomOut" class="p-1.5 hover:bg-white dark:hover:bg-gray-700 rounded text-gray-500 transition-colors"><i class="fas fa-minus text-xs"></i></button>
              <span class="text-xs font-mono w-12 text-center text-gray-600 dark:text-gray-300">{{ Math.round(zoom * 100) }}%</span>
              <button @click="zoomIn" class="p-1.5 hover:bg-white dark:hover:bg-gray-700 rounded text-gray-500 transition-colors"><i class="fas fa-plus text-xs"></i></button>
            </div>
          </div>
        </div>

        <!-- Canvas Content -->
        <div class="flex-1 overflow-hidden relative bg-white dark:bg-gray-900/50">
          <!-- Grid Background Pattern -->
          <div
            class="absolute inset-0 opacity-5 pointer-events-none bg-gray-500"
            style="background-image: url('data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%2220%22 height=%2220%22><circle cx=%2210%22 cy=%2210%22 r=%221%22 fill=%22%236b7280%22/></svg>'); background-size: 20px 20px"
          ></div>

          <div class="h-full overflow-auto custom-scrollbar p-4">
            <div v-if="activeTab === 'canvas'" class="h-full flex flex-col justify-center">
              <sprite-canvas
                :layers="layers"
                :active-layer-id="activeLayerId"
                :columns="columns"
                :zoom="zoom"
                :is-multi-select-mode="isMultiSelectMode"
                :show-active-border="showActiveBorder"
                :allow-cell-swap="allowCellSwap"
                :show-all-sprites="showAllSprites"
                :show-offset-labels="showOffsetLabels"
                @update-sprite="updateSpritePosition"
                @update-sprite-cell="updateSpriteCell"
                @remove-sprite="removeSprite"
                @remove-sprites="removeSprites"
                @replace-sprite="replaceSprite"
                @add-sprite="addSprite"
                @rotate-sprite="rotateSprite"
                @flip-sprite="flipSprite"
                @copy-sprite-to-frame="copySpriteToFrame"
              />
            </div>
            <div v-if="activeTab === 'preview'" class="h-full flex items-center justify-center">
              <sprite-preview
                :layers="layers"
                :active-layer-id="activeLayerId"
                :columns="columns"
                @update-sprite="updateSpritePosition"
                @update-sprite-in-layer="updateSpriteInLayer"
                @drop-sprite="handleDropSprite"
                @rotate-sprite="rotateSprite"
                @flip-sprite="flipSprite"
                @copy-sprite-to-frame="copySpriteToFrame"
                @replace-sprite="replaceSprite"
              />
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Modals & Hidden Inputs -->
    <SpritesheetSplitter :is-open="isSpritesheetSplitterOpen" :image-url="spritesheetImageUrl" :image-file="spritesheetImageFile" @close="closeSpritesheetSplitter" @split="handleSplitSpritesheet" />
    <GifFpsModal :is-open="isGifFpsModalOpen" @close="closeGifFpsModal" @confirm="downloadAsGif" :default-fps="10" />
    <ShareModal :is-open="isShareModalOpen" :share-function="shareFunction" @close="closeShareModal" />

    <input ref="uploadInput" type="file" multiple accept="image/*" class="hidden" @change="handleUploadChange" />
    <input ref="jsonFileInput" type="file" accept=".json,application/json" class="hidden" @change="handleJSONFileChange" />
  </main>
</template>

<script setup lang="ts">
  import { ref, toRef, computed, watch, nextTick } from 'vue';
  import FileUploader from '@/components/FileUploader.vue';
  import SpriteCanvas from '@/components/SpriteCanvas.vue';
  import SpritePreview from '@/components/SpritePreview.vue';
  import SpritesheetSplitter from '@/components/SpritesheetSplitter.vue';
  import GifFpsModal from '@/components/GifFpsModal.vue';
  import ShareModal from '@/components/ShareModal.vue';
  import Tooltip from '@/components/utilities/Tooltip.vue';
  import { useExportLayers } from '@/composables/useExportLayers';
  import { useShare } from '@/composables/useShare';
  import { useLayers } from '@/composables/useLayers';
  import { getMaxDimensionsAcrossLayers } from '@/composables/useLayers';
  import { useSettingsStore } from '@/stores/useSettingsStore';
  import { calculateNegativeSpacing } from '@/composables/useNegativeSpacing';
  import { useHomeViewSEO } from './HomeView.seo';
  import { useZoom } from '@/composables/useZoom';
  import type { SpriteFile } from '@/types/sprites';
  import tutVideo from '@/assets/tut2.mp4';

  useHomeViewSEO();

  const settingsStore = useSettingsStore();
  const { layers, visibleLayers, activeLayer, activeLayerId, columns, updateSpritePosition, updateSpriteInLayer, updateSpriteCell, removeSprite, removeSprites, replaceSprite, addSprite, processImageFiles, alignSprites, addLayer, removeLayer, moveLayer, rotateSprite, flipSprite, copySpriteToFrame } =
    useLayers();

  const { downloadSpritesheet, exportSpritesheetJSON, importSpritesheetJSON, downloadAsGif, downloadAsZip } = useExportLayers(
    layers,
    columns,
    toRef(settingsStore, 'negativeSpacingEnabled'),
    activeLayerId,
    toRef(settingsStore, 'backgroundColor'),
    toRef(settingsStore, 'manualCellSizeEnabled'),
    toRef(settingsStore, 'manualCellWidth'),
    toRef(settingsStore, 'manualCellHeight')
  );

  // Zoom Control
  const {
    zoom,
    increase: zoomIn,
    decrease: zoomOut,
    reset: resetZoom,
  } = useZoom({
    min: 0.5,
    max: 3,
    step: 0.25,
    initial: 1,
  });

  // View Options & Tools
  const isMultiSelectMode = ref(false);
  const showActiveBorder = ref(true);
  const allowCellSwap = ref(false);
  const showAllSprites = ref(false);
  const showOffsetLabels = ref(false);
  const customColor = ref('#ffffff');
  const isCustomMode = ref(false);

  // Background Color Logic
  const presetBgColors = ['transparent', '#ffffff', '#000000', '#f9fafb'] as const;
  const isHexColor = (val: string) => /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(val);

  if (isHexColor(settingsStore.backgroundColor) && !presetBgColors.includes(settingsStore.backgroundColor as any)) {
    customColor.value = settingsStore.backgroundColor;
    isCustomMode.value = true;
  }

  const bgSelectValue = computed<string>({
    get() {
      if (isCustomMode.value) return 'custom';
      const val = settingsStore.backgroundColor;
      if (presetBgColors.includes(val as any)) return val;
      if (isHexColor(val)) {
        customColor.value = val;
        isCustomMode.value = true;
        return 'custom';
      }
      return 'transparent';
    },
    set(v: string) {
      if (v === 'custom') {
        isCustomMode.value = true;
        settingsStore.setBackgroundColor(customColor.value);
      } else {
        isCustomMode.value = false;
        settingsStore.setBackgroundColor(v);
      }
    },
  });

  const updateCustomColor = () => {
    settingsStore.setBackgroundColor(customColor.value);
  };

  const getCellSize = () => {
    if (!visibleLayers.value.length) return { width: 0, height: 0 };
    if (settingsStore.manualCellSizeEnabled) {
      return { width: settingsStore.manualCellWidth, height: settingsStore.manualCellHeight };
    }
    const { maxWidth, maxHeight } = getMaxDimensionsAcrossLayers(visibleLayers.value);
    const allSprites = visibleLayers.value.flatMap(l => l.sprites);
    const negativeSpacing = calculateNegativeSpacing(allSprites, settingsStore.negativeSpacingEnabled);
    return { width: maxWidth + negativeSpacing, height: maxHeight + negativeSpacing };
  };

  const cellSize = computed(getCellSize);
  const activeTab = ref<'canvas' | 'preview'>('canvas');

  const isSpritesheetSplitterOpen = ref(false);
  const isGifFpsModalOpen = ref(false);
  const isShareModalOpen = ref(false);

  const uploadInput = ref<HTMLInputElement | null>(null);
  const jsonFileInput = ref<HTMLInputElement | null>(null);
  const spritesheetImageUrl = ref('');
  const spritesheetImageFile = ref<File | null>(null);

  const editingLayerId = ref<string | null>(null);
  const editingLayerName = ref('');
  const layerNameInput = ref<HTMLInputElement | null>(null);

  // Upload Handlers
  const handleSpritesUpload = async (files: File[]) => {
    const jsonFile = files.find(file => file.type === 'application/json' || file.name.endsWith('.json'));

    if (jsonFile) {
      await handleJSONImport(jsonFile);
      return;
    }

    if (files.length === 1 && files[0].type.startsWith('image/')) {
      const file = files[0];
      const reader = new FileReader();
      reader.onload = e => {
        const url = e.target?.result as string;
        const img = new Image();
        img.onload = () => {
          if (confirm('This looks like it might be a spritesheet. Would you like to split it into individual sprites?')) {
            spritesheetImageUrl.value = url;
            spritesheetImageFile.value = file;
            isSpritesheetSplitterOpen.value = true;
            return;
          }
          processImageFiles([file]);
        };
        img.onerror = () => {
          console.error('Failed to load image:', file.name);
        };
        img.src = url;
      };
      reader.readAsDataURL(file);
      return;
    }

    processImageFiles(files);
  };

  const handleJSONImport = async (jsonFile: File) => {
    try {
      await importSpritesheetJSON(jsonFile);
    } catch (error) {
      console.error('Error importing JSON:', error);
      alert('Failed to import JSON file. Please check the file format.');
    }
  };

  const closeSpritesheetSplitter = () => {
    isSpritesheetSplitterOpen.value = false;
    if (spritesheetImageUrl.value && spritesheetImageUrl.value.startsWith('blob:')) {
      try {
        URL.revokeObjectURL(spritesheetImageUrl.value);
      } catch {}
    }
    spritesheetImageUrl.value = '';
    spritesheetImageFile.value = null;
  };

  const openGifFpsModal = () => {
    if (!visibleLayers.value.some(l => l.sprites.length > 0)) {
      alert('Please upload or import sprites before generating a GIF.');
      return;
    }
    isGifFpsModalOpen.value = true;
  };

  const closeGifFpsModal = () => (isGifFpsModalOpen.value = false);

  const { share } = useShare(layers, columns, toRef(settingsStore, 'negativeSpacingEnabled'), toRef(settingsStore, 'backgroundColor'), toRef(settingsStore, 'manualCellSizeEnabled'), toRef(settingsStore, 'manualCellWidth'), toRef(settingsStore, 'manualCellHeight'));
  const shareFunction = () => share();

  const openShareModal = () => {
    if (!visibleLayers.value.some(l => l.sprites.length > 0)) {
      alert('Please upload or import sprites before sharing.');
      return;
    }
    isShareModalOpen.value = true;
  };

  const closeShareModal = () => (isShareModalOpen.value = false);

  const handleSplitSpritesheet = (spriteFiles: SpriteFile[]) => {
    processImageFiles(spriteFiles.map(s => s.file));
  };

  const openFileDialog = () => uploadInput.value?.click();

  const handleJSONFileChange = async (event: Event) => {
    const input = event.target as HTMLInputElement;
    if (input.files && input.files.length > 0) {
      await handleJSONImport(input.files[0]);
      input.value = '';
    }
  };

  const handleUploadChange = async (event: Event) => {
    const input = event.target as HTMLInputElement;
    if (input.files && input.files.length > 0) {
      await handleSpritesUpload(Array.from(input.files));
      input.value = '';
    }
  };

  // Layer Editing
  const startEditingLayer = (layerId: string, currentName: string) => {
    editingLayerId.value = layerId;
    editingLayerName.value = currentName;
    setTimeout(() => {
      layerNameInput.value?.focus();
      layerNameInput.value?.select();
    }, 0);
  };

  const finishEditingLayer = () => {
    if (editingLayerId.value && editingLayerName.value.trim()) {
      const layer = layers.value.find(l => l.id === editingLayerId.value);
      if (layer) layer.name = editingLayerName.value.trim();
    }
    editingLayerId.value = null;
    editingLayerName.value = '';
  };

  const cancelEditingLayer = () => {
    editingLayerId.value = null;
    editingLayerName.value = '';
  };

  const handleDropSprite = (layerId: string, frameIndex: number, files: File[]) => {
    const layer = layers.value.find(l => l.id === layerId);
    if (!layer) return;

    files.forEach((file, fileIdx) => {
      const reader = new FileReader();
      reader.onload = e => {
        const url = e.target?.result as string;
        const img = new Image();
        img.onload = () => {
          const sprite = {
            id: crypto.randomUUID(),
            file,
            img,
            url,
            width: img.width,
            height: img.height,
            x: 0,
            y: 0,
            rotation: 0,
            flipX: false,
            flipY: false,
          };
          const insertIndex = frameIndex + fileIdx;
          if (insertIndex < layer.sprites.length) {
            layer.sprites = [...layer.sprites.slice(0, insertIndex), sprite, ...layer.sprites.slice(insertIndex + 1)];
          } else {
            while (layer.sprites.length < insertIndex) {
              layer.sprites.push({
                id: crypto.randomUUID(),
                file: new File([], 'empty'),
                img: new Image(),
                url: '',
                width: 0,
                height: 0,
                x: 0,
                y: 0,
                rotation: 0,
                flipX: false,
                flipY: false,
              });
            }
            layer.sprites = [...layer.sprites, sprite];
          }
        };
        img.src = url;
      };
      reader.readAsDataURL(file);
    });
  };
</script>

<style scoped></style>
