<template>
  <div class="form-control w-full">
    <label class="label">
      <span class="label-text font-medium">Upload Solution Files</span>
      <span class="label-text-alt text-xs">Images or GIFs only</span>
    </label>

    <div
      class="border-2 border-dashed border-base-300 rounded-lg p-6 text-center hover:border-primary transition-colors duration-300"
      :class="{ 'border-primary bg-primary/5': isDragOver }"
      @drop="handleDrop"
      @dragover.prevent="isDragOver = true"
      @dragleave="isDragOver = false"
      @dragenter.prevent
    >
      <input
        ref="fileInput"
        type="file"
        multiple
        accept="image/*,.gif"
        class="hidden"
        @change="handleFileSelect"
      />

      <div v-if="submissionFiles.length === 0" class="space-y-4">
        <div
          class="mx-auto w-12 h-12 text-base-content/40 flex items-center justify-center"
        >
          <i class="mdi mdi-cloud-upload text-5xl"></i>
        </div>
        <div>
          <p class="text-base-content/70 mb-2">Drop your files here or</p>
          <button
            type="button"
            @click="fileInput?.click()"
            class="btn btn-primary btn-sm"
          >
            Choose Files
          </button>
        </div>
        <p class="text-xs text-base-content/50">
          Supported formats: JPG, PNG, GIF (max 256MB each)
        </p>
      </div>

      <div v-else class="space-y-4">
        <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 gap-4">
          <div
            v-for="(file, index) in submissionFiles"
            :key="index"
            class="relative group"
          >
            <div class="aspect-square rounded-lg overflow-hidden bg-base-200">
              <img
                :src="file.preview"
                :alt="file.file.name"
                class="w-full h-full object-cover"
              />
            </div>

            <div
              class="absolute inset-0 bg-black/80 opacity-0 group-hover:opacity-100 transition-opacity duration-200 rounded-lg flex items-center justify-center"
            >
              <button
                @click="removeFile(index)"
                class="btn btn-error btn-lg btn-circle"
              >
                <i class="mdi mdi-close"></i>
              </button>
            </div>

            <div class="mt-2">
              <p class="text-xs font-medium truncate">{{ file.file.name }}</p>
              <p class="text-xs text-base-content/60">
                {{ formatFileSize(file.file.size) }} •
                {{ file.type.toUpperCase() }}
              </p>

              <!-- OCR Status and Results -->
              <div
                v-if="file.ocrProcessing"
                class="mt-1 flex items-center gap-1"
              >
                <span class="loading loading-spinner loading-xs"></span>
                <span class="text-xs text-info">Extracting puzzle data...</span>
              </div>

              <div v-else-if="file.ocrError" class="mt-1">
                <p class="text-xs text-error">{{ file.ocrError }}</p>
              </div>

              <div v-else-if="file.ocrData" class="mt-1 space-y-1">
                <div class="text-xs flex items-center justify-between">
                  <div class="flex items-center gap-2">
                    <span class="font-medium text-success">✓ OCR Complete</span>
                    <span
                      v-if="file.ocrData.confidence"
                      class="badge badge-xs"
                      :class="
                        getConfidenceBadgeClass(file.ocrData.confidence.overall)
                      "
                      :title="`Overall confidence: ${Math.round(file.ocrData.confidence.overall * 100)}%`"
                    >
                      {{ Math.round(file.ocrData.confidence.overall * 100) }}%
                    </span>
                  </div>
                  <button
                    @click="processOCR(file)"
                    class="btn btn-xs btn-ghost"
                    title="Retry OCR"
                  >
                    <i class="mdi mdi-refresh"></i>
                  </button>
                </div>
                <div class="text-xs space-y-1 bg-base-200 p-2 rounded">
                  <div v-if="file.ocrData.puzzle">
                    <strong>Puzzle:</strong> {{ file.ocrData.puzzle }}
                    <span
                      v-if="file.ocrData.confidence?.puzzle"
                      class="ml-2 opacity-60"
                      :title="`Puzzle confidence: ${Math.round(file.ocrData.confidence.puzzle * 100)}%`"
                    >
                      ({{ Math.round(file.ocrData.confidence.puzzle * 100) }}%)
                    </span>
                  </div>
                  <div v-if="file.ocrData.cost">
                    <strong>Cost:</strong> {{ file.ocrData.cost }}
                    <span
                      v-if="file.ocrData.confidence?.cost"
                      class="ml-2 opacity-60"
                      :title="`Cost confidence: ${Math.round(file.ocrData.confidence.cost * 100)}%`"
                    >
                      ({{ Math.round(file.ocrData.confidence.cost * 100) }}%)
                    </span>
                  </div>
                  <div v-if="file.ocrData.cycles">
                    <strong>Cycles:</strong> {{ file.ocrData.cycles }}
                    <span
                      v-if="file.ocrData.confidence?.cycles"
                      class="ml-2 opacity-60"
                      :title="`Cycles confidence: ${Math.round(file.ocrData.confidence.cycles * 100)}%`"
                    >
                      ({{ Math.round(file.ocrData.confidence.cycles * 100) }}%)
                    </span>
                  </div>
                  <div v-if="file.ocrData.area">
                    <strong>Area:</strong> {{ file.ocrData.area }}
                    <span
                      v-if="file.ocrData.confidence?.area"
                      class="ml-2 opacity-60"
                      :title="`Area confidence: ${Math.round(file.ocrData.confidence.area * 100)}%`"
                    >
                      ({{ Math.round(file.ocrData.confidence.area * 100) }}%)
                    </span>
                  </div>
                </div>
              </div>

              <!-- Manual Puzzle Selection (when OCR confidence is low) -->
              <div v-if="file.needsManualPuzzleSelection" class="mt-2">
                <div class="alert alert-warning alert-sm">
                  <i class="mdi mdi-alert-circle text-lg"></i>
                  <div class="flex-1">
                    <div class="font-medium">Low OCR Confidence</div>
                    <div class="text-xs">
                      Please select the correct puzzle manually
                    </div>
                  </div>
                </div>
                <div class="mt-2">
                  <select
                    v-model="file.manualPuzzleSelection"
                    class="select select-bordered select-sm w-full"
                    @change="onManualPuzzleSelection(file)"
                  >
                    <option value="">Select puzzle...</option>
                    <option
                      v-for="puzzle in puzzlesStore.puzzles"
                      :key="puzzle.id"
                      :value="puzzle.title"
                    >
                      {{ puzzle.title }}
                    </option>
                  </select>
                </div>
              </div>

              <!-- Manual OCR trigger for non-auto detected files -->
              <div
                v-else-if="
                  !file.ocrProcessing && !file.ocrError && !file.ocrData
                "
                class="mt-1"
              >
                <button
                  @click="processOCR(file)"
                  class="btn btn-xs btn-outline"
                >
                  <i class="mdi mdi-text-recognition"></i>
                  Extract Puzzle Data
                </button>
              </div>
            </div>
          </div>
        </div>

        <div class="flex justify-center">
          <button
            type="button"
            @click="fileInput?.click()"
            class="btn btn-outline btn-sm"
          >
            Add More Files
          </button>
        </div>
      </div>
    </div>

    <div v-if="error" class="label">
      <span class="label-text-alt text-error">{{ error }}</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, nextTick } from "vue";
import { ocrService } from "@/services/ocrService";
import { usePuzzlesStore } from "@/stores/puzzles";
import { useUploadsStore } from "@/stores/uploads";
import type { SubmissionFile } from "@/types";

// Pinia store
const puzzlesStore = usePuzzlesStore();
const { submissionFiles, processOCR } = useUploadsStore();

const fileInput = ref<HTMLInputElement>();
const isDragOver = ref(false);
const error = ref("");

// Watch for puzzle changes and update OCR service
watch(
  () => puzzlesStore.puzzles,
  (newPuzzles) => {
    if (newPuzzles && newPuzzles.length > 0) {
      ocrService.setAvailablePuzzleNames(puzzlesStore.puzzleNames);
    }
  },
  { immediate: true },
);

const handleFileSelect = (event: Event) => {
  const target = event.target as HTMLInputElement;
  if (target.files) {
    processFiles(Array.from(target.files));
  }
};

const handleDrop = (event: DragEvent) => {
  event.preventDefault();
  isDragOver.value = false;

  if (event.dataTransfer?.files) {
    processFiles(Array.from(event.dataTransfer.files));
  }
};

const processFiles = async (newFiles: File[]) => {
  error.value = "";

  for (const file of newFiles) {
    if (!isValidFile(file)) {
      continue;
    }

    try {
      const preview = await createPreview(file);
      const fileType = file.type.startsWith("image/gif") ? "gif" : "image";

      const submissionFile: SubmissionFile = {
        file,
        file_url: "",
        preview,
        type: fileType,
        ocrProcessing: false,
        ocrError: undefined,
        ocrData: undefined,
      };

      submissionFiles.push(submissionFile);

      // Start OCR processing for Opus Magnum images (with delay to ensure reactivity)
      if (isOpusMagnumImage(file)) {
        nextTick(() => {
          processOCR(submissionFile);
        });
      }
    } catch (err) {
      error.value = `Failed to process ${file.name}`;
    }
  }
};

const isValidFile = (file: File): boolean => {
  // Check file type
  if (!file.type.startsWith("image/")) {
    error.value = `${file.name} is not a valid image file`;
    return false;
  }

  // Check file size (256MB limit)
  if (file.size > 256 * 1024 * 1024) {
    error.value = `${file.name} is too large (max 256MB)`;
    return false;
  }

  return true;
};

const createPreview = (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (e) => resolve(e.target?.result as string);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
};

const removeFile = (index: number) => {
  submissionFiles.splice(index, 1);
};

const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return "0 Bytes";

  const k = 1024;
  const sizes = ["Bytes", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));

  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};

const isOpusMagnumImage = (file: File): boolean => {
  // Basic heuristic - could be enhanced with actual image analysis
  return file.type.startsWith("image/") && file.size > 50000; // > 50KB likely screenshot
};

const getConfidenceBadgeClass = (confidence: number): string => {
  if (confidence >= 0.8) return "badge-success";
  if (confidence >= 0.6) return "badge-warning";
  return "badge-error";
};

const onManualPuzzleSelection = (submissionFile: SubmissionFile) => {
  // Find the file in the reactive array
  const fileIndex = submissionFiles.findIndex(
    (f) => f.file === submissionFile.file,
  );
  if (fileIndex === -1) return;

  // Clear the manual selection requirement once user has selected
  if (submissionFiles[fileIndex].manualPuzzleSelection) {
    submissionFiles[fileIndex].needsManualPuzzleSelection = false;
    console.log(
      `Manual puzzle selection: ${submissionFile.file.name} -> ${submissionFiles[fileIndex].manualPuzzleSelection}`,
    );
  }
};
</script>
