<template>
  <div
    class="fixed inset-0 bg-black/60 flex items-center justify-center z-50"
    @click.self="$emit('close')"
  >
    <div class="border border-border rounded-2xl w-[90%] max-w-3xl max-h-[85vh] flex flex-col shadow-2xl bg-gradient-to-b from-white to-[#f6f9fc]">
      <!-- Header -->
      <div class="flex items-center justify-between px-5 py-4 border-b border-border">
        <h3 class="text-base font-semibold text-[#3a5f88]">
          {{ selectMode ? 'Bild auswaehlen' : 'Datei-Manager' }}
        </h3>
        <button
          class="w-7 h-7 rounded-lg border border-border bg-panel-2 text-text cursor-pointer hover:bg-[#e4ebf2] hover:border-[#b8c4d2]"
          @click="$emit('close')"
        >
          x
        </button>
      </div>

      <!-- Path Navigation -->
      <div class="flex items-center gap-2 px-5 py-3 border-b border-border bg-panel-2">
        <span class="text-xs text-muted">Pfad:</span>
        <div class="flex-1 flex items-center gap-1 overflow-x-auto">
          <button
            v-for="(segment, idx) in pathSegments"
            :key="idx"
            class="text-sm text-[#2f6db8] hover:underline cursor-pointer"
            @click="navigateToSegment(idx)"
          >
            {{ segment || '/' }}
          </button>
          <span v-if="pathSegments.length > 1" class="text-muted">/</span>
        </div>
        <button
          v-if="currentPath !== '/'"
          class="w-7 h-7 rounded-lg border border-border bg-white text-text cursor-pointer hover:bg-[#e4ebf2]"
          @click="navigateUp"
          title="Eine Ebene hoch"
        >
          <span class="text-sm">&#8593;</span>
        </button>
        <button
          v-if="!selectMode"
          class="w-7 h-7 rounded-lg border border-border bg-white text-text cursor-pointer hover:bg-[#e4ebf2]"
          @click="showNewFolderInput = true"
          title="Neuer Ordner"
        >
          +
        </button>
      </div>

      <!-- New Folder Input -->
      <div v-if="showNewFolderInput" class="flex items-center gap-2 px-5 py-2 border-b border-border bg-yellow-50">
        <input
          v-model="newFolderName"
          type="text"
          placeholder="Ordnername..."
          class="flex-1 bg-white border border-border rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:border-[#2f6db8]"
          @keydown.enter="createFolder"
          @keydown.esc="showNewFolderInput = false"
          ref="newFolderInput"
        >
        <button
          class="px-3 py-1.5 rounded-lg border border-[#2b62a5] bg-[#2f6db8] text-white text-sm cursor-pointer hover:bg-[#2b62a5]"
          @click="createFolder"
        >
          Erstellen
        </button>
        <button
          class="px-3 py-1.5 rounded-lg border border-border bg-white text-text text-sm cursor-pointer hover:bg-[#e4ebf2]"
          @click="showNewFolderInput = false"
        >
          Abbrechen
        </button>
      </div>

      <!-- Loading -->
      <div v-if="loading" class="flex-1 flex items-center justify-center py-10">
        <span class="text-muted">Lade...</span>
      </div>

      <!-- Error -->
      <div v-else-if="error" class="flex-1 flex items-center justify-center py-10 text-red-500">
        {{ error }}
      </div>

      <!-- File List -->
      <div v-else class="flex-1 overflow-y-auto">
        <div v-if="filteredFiles.length === 0" class="py-10 text-center text-muted">
          {{ selectMode ? 'Keine Bilder in diesem Ordner' : 'Ordner ist leer' }}
        </div>
        <div v-else class="divide-y divide-border">
          <div
            v-for="file in filteredFiles"
            :key="file.name"
            class="flex items-center gap-3 px-5 py-3 hover:bg-panel-2 cursor-pointer transition-colors"
            :class="{ 'bg-[#2f6db8]/5': selectedFile === file.name }"
            @click="handleFileClick(file)"
          >
            <!-- Icon -->
            <div class="w-10 h-10 rounded-lg bg-panel-2 border border-border flex items-center justify-center flex-shrink-0 overflow-hidden">
              <img
                v-if="isImageFile(file.name) && !file.isDir"
                :src="getImageUrl(file.name)"
                class="w-full h-full object-cover"
                @error="$event.target.style.display='none'"
              >
              <span v-else-if="file.isDir" class="text-lg">&#128193;</span>
              <span v-else class="text-lg">&#128196;</span>
            </div>

            <!-- Name & Size -->
            <div class="flex-1 min-w-0">
              <div class="text-sm font-medium truncate">{{ file.name }}</div>
              <div v-if="!file.isDir" class="text-xs text-muted">{{ formatSize(file.size) }}</div>
            </div>

            <!-- Actions -->
            <div v-if="!selectMode" class="flex items-center gap-1">
              <button
                v-if="!file.isDir"
                class="w-7 h-7 rounded-lg border border-border bg-white text-text cursor-pointer hover:bg-[#e4ebf2]"
                @click.stop="downloadFile(file.name)"
                title="Herunterladen"
              >
                <span class="text-xs">&#8595;</span>
              </button>
              <button
                class="w-7 h-7 rounded-lg border border-red-200 bg-[#f7dede] text-[#b3261e] cursor-pointer hover:bg-[#f2cfcf]"
                @click.stop="deleteFile(file)"
                title="Loeschen"
              >
                x
              </button>
            </div>

            <!-- Select indicator for images -->
            <div v-if="selectMode && isImageFile(file.name) && !file.isDir" class="text-[#2f6db8]">
              <span class="text-sm">Auswaehlen &#8594;</span>
            </div>
          </div>
        </div>
      </div>

      <!-- Footer -->
      <div class="px-5 py-3 border-t border-border flex items-center gap-2">
        <div v-if="!selectMode" class="flex-1">
          <label
            class="inline-flex items-center gap-2 px-4 py-2 rounded-lg border border-[#2b62a5] bg-[#2f6db8] text-white text-sm cursor-pointer hover:bg-[#2b62a5]"
          >
            <span>Datei hochladen</span>
            <input
              type="file"
              class="hidden"
              :accept="selectMode ? 'image/*' : '*'"
              multiple
              @change="handleFileUpload"
            >
          </label>
        </div>
        <div v-if="selectMode" class="flex-1">
          <label
            class="inline-flex items-center gap-2 px-4 py-2 rounded-lg border border-[#2b62a5] bg-[#2f6db8] text-white text-sm cursor-pointer hover:bg-[#2b62a5]"
          >
            <span>Bild hochladen</span>
            <input
              type="file"
              class="hidden"
              accept="image/*"
              @change="handleFileUpload"
            >
          </label>
        </div>
        <span v-if="uploadProgress" class="text-sm text-muted">{{ uploadProgress }}</span>
        <button
          class="px-4 py-2 rounded-lg border border-border bg-panel-2 text-text text-sm cursor-pointer hover:bg-[#e4ebf2]"
          @click="$emit('close')"
        >
          {{ selectMode ? 'Abbrechen' : 'Schliessen' }}
        </button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch, nextTick } from 'vue';

const props = defineProps({
  selectMode: { type: Boolean, default: false },
  initialPath: { type: String, default: '/images' }
});

const emit = defineEmits(['close', 'select']);

const currentPath = ref(props.initialPath);
const files = ref([]);
const loading = ref(false);
const error = ref(null);
const selectedFile = ref(null);
const showNewFolderInput = ref(false);
const newFolderName = ref('');
const newFolderInput = ref(null);
const uploadProgress = ref('');

const pathSegments = computed(() => {
  if (currentPath.value === '/') return ['/'];
  return ['/', ...currentPath.value.split('/').filter(Boolean)];
});

const filteredFiles = computed(() => {
  if (!props.selectMode) return files.value;
  // In select mode, show directories and image files only
  return files.value.filter(f => f.isDir || isImageFile(f.name));
});

const imageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'svg'];

// Image optimization settings for ESP32
const MAX_IMAGE_WIDTH = 1280;   // Display width
const MAX_IMAGE_HEIGHT = 800;   // Display height
const JPEG_QUALITY = 0.80;      // 80% quality - good balance

function isImageFile(name) {
  const ext = name.split('.').pop().toLowerCase();
  return imageExtensions.includes(ext);
}

function getImageUrl(name) {
  const fullPath = currentPath.value === '/' ? `/${name}` : `${currentPath.value}/${name}`;
  return fullPath;
}

function formatSize(bytes) {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

async function loadDirectory() {
  loading.value = true;
  error.value = null;
  files.value = [];

  try {
    const response = await fetch(`/api/files/list?path=${encodeURIComponent(currentPath.value)}`);
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    const data = await response.json();

    // Sort: directories first, then by name
    files.value = (data.files || []).sort((a, b) => {
      if (a.isDir && !b.isDir) return -1;
      if (!a.isDir && b.isDir) return 1;
      return a.name.localeCompare(b.name);
    });
  } catch (e) {
    error.value = `Fehler beim Laden: ${e.message}`;
  } finally {
    loading.value = false;
  }
}

function navigateToSegment(idx) {
  if (idx === 0) {
    currentPath.value = '/';
  } else {
    const segments = currentPath.value.split('/').filter(Boolean);
    currentPath.value = '/' + segments.slice(0, idx).join('/');
  }
}

function navigateUp() {
  const segments = currentPath.value.split('/').filter(Boolean);
  if (segments.length > 0) {
    segments.pop();
    currentPath.value = segments.length > 0 ? '/' + segments.join('/') : '/';
  }
}

function handleFileClick(file) {
  if (file.isDir) {
    currentPath.value = currentPath.value === '/'
      ? `/${file.name}`
      : `${currentPath.value}/${file.name}`;
  } else if (props.selectMode && isImageFile(file.name)) {
    const fullPath = currentPath.value === '/'
      ? `/${file.name}`
      : `${currentPath.value}/${file.name}`;
    emit('select', fullPath);
    emit('close');
  } else {
    selectedFile.value = selectedFile.value === file.name ? null : file.name;
  }
}

async function createFolder() {
  if (!newFolderName.value.trim()) return;

  const path = currentPath.value === '/'
    ? `/${newFolderName.value}`
    : `${currentPath.value}/${newFolderName.value}`;

  try {
    const response = await fetch(`/api/files/mkdir?path=${encodeURIComponent(path)}`, {
      method: 'POST'
    });
    if (!response.ok) throw new Error(`HTTP ${response.status}`);

    showNewFolderInput.value = false;
    newFolderName.value = '';
    await loadDirectory();
  } catch (e) {
    alert(`Fehler beim Erstellen: ${e.message}`);
  }
}

async function deleteFile(file) {
  const typeName = file.isDir ? 'Ordner' : 'Datei';
  if (!confirm(`${typeName} "${file.name}" wirklich loeschen?`)) return;

  const path = currentPath.value === '/'
    ? `/${file.name}`
    : `${currentPath.value}/${file.name}`;

  try {
    const response = await fetch(`/api/files/delete?file=${encodeURIComponent(path)}`, {
      method: 'DELETE'
    });
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    await loadDirectory();
  } catch (e) {
    alert(`Fehler beim Loeschen: ${e.message}`);
  }
}

function downloadFile(name) {
  const path = currentPath.value === '/'
    ? `/${name}`
    : `${currentPath.value}/${name}`;
  window.open(`/api/files/download?file=${encodeURIComponent(path)}`, '_blank');
}

// Optimize image for ESP32: resize and compress
async function optimizeImage(file) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    const url = URL.createObjectURL(file);

    img.onload = () => {
      URL.revokeObjectURL(url);

      let width = img.width;
      let height = img.height;

      // Check if resize is needed
      if (width <= MAX_IMAGE_WIDTH && height <= MAX_IMAGE_HEIGHT) {
        // Image is small enough, but still convert to JPEG for consistency
        // Unless it's an SVG (keep as-is)
        if (file.name.toLowerCase().endsWith('.svg')) {
          resolve({ file, optimized: false });
          return;
        }
      }

      // Calculate new dimensions while maintaining aspect ratio
      if (width > MAX_IMAGE_WIDTH) {
        height = Math.round(height * (MAX_IMAGE_WIDTH / width));
        width = MAX_IMAGE_WIDTH;
      }
      if (height > MAX_IMAGE_HEIGHT) {
        width = Math.round(width * (MAX_IMAGE_HEIGHT / height));
        height = MAX_IMAGE_HEIGHT;
      }

      // Create canvas and draw scaled image
      const canvas = document.createElement('canvas');
      canvas.width = width;
      canvas.height = height;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0, width, height);

      // Convert to JPEG blob
      canvas.toBlob((blob) => {
        if (!blob) {
          reject(new Error('Canvas toBlob failed'));
          return;
        }

        // Create new filename with .jpg extension
        const baseName = file.name.replace(/\.[^/.]+$/, '');
        const newFile = new File([blob], `${baseName}.jpg`, { type: 'image/jpeg' });

        resolve({
          file: newFile,
          optimized: true,
          originalSize: file.size,
          newSize: blob.size,
          originalDimensions: { w: img.width, h: img.height },
          newDimensions: { w: width, h: height }
        });
      }, 'image/jpeg', JPEG_QUALITY);
    };

    img.onerror = () => {
      URL.revokeObjectURL(url);
      reject(new Error('Failed to load image'));
    };

    img.src = url;
  });
}

async function handleFileUpload(event) {
  const fileList = event.target.files;
  if (!fileList || fileList.length === 0) return;

  for (const file of fileList) {
    let fileToUpload = file;
    let uploadName = file.name;

    // Check if it's an image that should be optimized
    if (isImageFile(file.name) && !file.name.toLowerCase().endsWith('.svg')) {
      uploadProgress.value = `Optimiere ${file.name}...`;

      try {
        const result = await optimizeImage(file);
        fileToUpload = result.file;
        uploadName = result.file.name;

        if (result.optimized) {
          const savedKB = Math.round((result.originalSize - result.newSize) / 1024);
          const savedPercent = Math.round((1 - result.newSize / result.originalSize) * 100);
          console.log(`Optimized ${file.name}: ${result.originalDimensions.w}x${result.originalDimensions.h} -> ${result.newDimensions.w}x${result.newDimensions.h}, saved ${savedKB}KB (${savedPercent}%)`);
        }
      } catch (e) {
        console.warn(`Could not optimize ${file.name}, uploading original:`, e);
        fileToUpload = file;
        uploadName = file.name;
      }
    }

    uploadProgress.value = `Lade ${uploadName} hoch...`;

    const formData = new FormData();
    formData.append('file', fileToUpload, uploadName);

    try {
      const response = await fetch(`/api/files/upload?path=${encodeURIComponent(currentPath.value)}`, {
        method: 'POST',
        body: formData
      });
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
    } catch (e) {
      alert(`Fehler beim Hochladen von ${uploadName}: ${e.message}`);
    }
  }

  uploadProgress.value = '';
  event.target.value = '';
  await loadDirectory();
}

watch(currentPath, () => {
  loadDirectory();
});

watch(showNewFolderInput, async (show) => {
  if (show) {
    await nextTick();
    newFolderInput.value?.focus();
  }
});

onMounted(() => {
  loadDirectory();
});
</script>
