<template>
  <!--
    Outer wrapper is draggable. Browser suppresses click-to-navigate during
    a real drag, so NuxtLink navigation still works on a plain click.
  -->
  <div
    class="project-card project-card-wrapper"
    :class="{ 'is-dragging': isDragging }"
    draggable="true"
    @dragstart="onDragStart"
    @dragend="onDragEnd"
  >
    <NuxtLink
      :to="`/project/${project.id}`"
      draggable="false"
      class="premium-glass rounded-2xl overflow-hidden group hover:-translate-y-1 transition-all duration-300 block select-none"
    >
      <!-- Thumbnail -->
      <div
        class="aspect-video w-full bg-slate-900 relative overflow-hidden"
        @mouseenter="playPreview"
        @mouseleave="pausePreview"
      >
        <!-- Status Badge -->
        <div class="absolute top-3 left-3 z-10 flex gap-2">
          <span
            class="px-2.5 py-1 rounded-full text-xs font-semibold backdrop-blur-md"
            :class="statusClasses"
          >
            {{ formattedStatus }}
          </span>
        </div>

        <!-- Action Buttons (Continue + Delete) -->
        <div class="absolute top-3 right-3 z-10 flex gap-2">
          <!-- Continue button (only for non-active projects: error, planned, or stopped) -->
          <button
            v-if="canContinue"
            @click.prevent.stop="$emit('continue', project)"
            class="w-8 h-8 rounded-full bg-white/80 backdrop-blur-md border border-white/80 flex items-center justify-center text-slate-600 hover:bg-green-500 hover:text-white hover:border-green-500 transition-all shadow-sm opacity-0 group-hover:opacity-100"
            :title="
              project.status === 'error'
                ? 'Retry Generation'
                : 'Continue Generation'
            "
          >
            <UIcon
              :name="
                project.status === 'error'
                  ? 'i-lucide-rotate-ccw'
                  : 'i-lucide-play-circle'
              "
              class="w-4 h-4"
            />
          </button>

          <!-- Delete button -->
          <button
            @click.prevent.stop="$emit('delete', project)"
            class="w-8 h-8 rounded-full bg-white/80 backdrop-blur-md border border-white/80 flex items-center justify-center text-slate-600 hover:bg-red-500 hover:text-white hover:border-red-500 transition-all shadow-sm opacity-0 group-hover:opacity-100"
          >
            <UIcon name="i-lucide-trash-2" class="w-4 h-4" />
          </button>
        </div>

        <!-- Drag hint badge (shows on hover) -->
        <div
          class="absolute bottom-2 right-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none"
        >
          <div
            class="flex items-center gap-1 px-2 py-1 rounded-full bg-black/40 backdrop-blur-sm text-white text-xs font-medium"
          >
            <UIcon name="i-lucide-grip" class="w-3 h-3" />
            Drag to group
          </div>
        </div>

        <!-- Play icon overlay -->
        <div
          v-if="videoUrl"
          class="absolute inset-0 z-10 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none"
        >
          <div
            class="w-12 h-12 rounded-full bg-black/50 backdrop-blur-sm flex items-center justify-center"
          >
            <UIcon
              name="i-lucide-play"
              class="w-6 h-6 text-white translate-x-0.5"
            />
          </div>
        </div>

        <!-- Video preview -->
        <video
          v-if="videoUrl"
          ref="videoEl"
          :src="videoUrl"
          draggable="false"
          class="w-full h-full object-cover transition-opacity duration-500"
          :class="{
            'opacity-0': !isHovered && !videoStarted,
            'opacity-100': isHovered || videoStarted,
          }"
          muted
          loop
          preload="metadata"
          @loadedmetadata="onVideoMetadata"
          @play="videoStarted = true"
        />

        <!-- Premium Thumbnail / Generating / Fallback Overlay -->
        <div
          v-if="!isHovered && !videoStarted"
          class="absolute inset-0 z-0 flex flex-col items-center justify-center overflow-hidden"
        >
          <!-- Thumbnail Image (if available) -->
          <div v-if="project.thumbnail" class="absolute inset-0 bg-slate-900">
            <img
              :src="project.thumbnail"
              class="w-full h-full object-cover opacity-60 transition-transform duration-700 group-hover:scale-110"
              alt="Project Thumbnail"
            />
            <div
              class="absolute inset-0 bg-gradient-to-t from-slate-950/80 via-slate-950/20 to-transparent"
            ></div>
          </div>

          <!-- Fallback Stock Image Background -->
          <div v-else class="absolute inset-0 bg-slate-900">
            <img
              src="https://images.unsplash.com/photo-1635070041078-e363dbe005cb?auto=format&fit=crop&q=80&w=1200"
              class="w-full h-full object-cover opacity-40 transition-transform duration-700 group-hover:scale-110"
              alt="Default Project Thumbnail"
            />
            <div
              class="absolute inset-0 bg-gradient-to-t from-slate-950/80 via-slate-950/20 to-transparent"
            ></div>
          </div>

          <!-- Generating Animation Overlay -->
          <div
            v-if="project.status !== 'completed' && project.status !== 'error'"
            class="absolute inset-0 z-10 flex items-center justify-center"
          >
            <div class="absolute inset-0 bg-green-500/10 animate-pulse"></div>
            <div
              class="w-full h-1 bg-gradient-to-r from-transparent via-green-400 to-transparent absolute top-0 animate-[scan_3s_linear_infinite]"
            ></div>
            <div
              class="w-full h-1 bg-gradient-to-r from-transparent via-green-400 to-transparent absolute bottom-0 animate-[scan_3s_linear_infinite_reverse]"
            ></div>
          </div>

          <!-- Project Identity -->
          <div
            class="relative z-20 flex flex-col items-center px-6 text-center"
          >
            <div
              class="px-5 py-3 rounded-2xl border border-white/20 backdrop-blur-md shadow-2xl transition-all duration-500 group-hover:scale-105"
              :class="
                project.status !== 'completed' && project.status !== 'error'
                  ? 'bg-orange-500/20 border-orange-500/40'
                  : 'bg-green-500/20 border-green-500/30 group-hover:bg-green-500/30'
              "
            >
              <div
                v-if="
                  project.status !== 'completed' && project.status !== 'error'
                "
                class="flex flex-col items-center gap-2"
              >
                <UIcon
                  :name="
                    project.status === 'awaiting_approval'
                      ? 'i-lucide-scroll-text'
                      : 'i-lucide-loader-2'
                  "
                  class="w-6 h-6"
                  :class="
                    project.status === 'awaiting_approval'
                      ? 'text-indigo-400'
                      : 'text-orange-400 animate-spin'
                  "
                />
                <h3 class="text-xl font-bold text-white leading-tight">
                  {{
                    project.status === "awaiting_approval"
                      ? "Review Plan"
                      : "Generating..."
                  }}
                </h3>
              </div>
              <h3 v-else class="text-xl font-bold text-white leading-tight">
                {{ project.name || "Untitled" }}
              </h3>
            </div>
          </div>
        </div>
      </div>

      <!-- Card Content -->
      <div class="p-5">
        <h3 class="font-bold text-slate-900 text-lg mb-1 truncate">
          {{ project.name || "Untitled Project" }}
        </h3>
        <p
          class="text-slate-500 text-sm line-clamp-2 h-10 mb-4"
          :title="project.overview || project.topic"
        >
          {{ project.overview || project.topic || "No description provided." }}
        </p>

        <div
          class="flex items-center justify-between text-xs text-slate-400 font-medium"
        >
          <div class="flex items-center gap-1.5">
            <UIcon name="i-lucide-calendar" class="w-3.5 h-3.5" />
            {{ formattedDate }}
          </div>
          <div class="flex items-center gap-1.5">
            <UIcon name="i-lucide-clock" class="w-3.5 h-3.5" />
            {{ duration || "--:--" }}
          </div>
        </div>
      </div>
    </NuxtLink>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
import { config as apiConfig } from "~/utils/api";
import { useProjectStore } from "~/stores/projects";

const props = defineProps<{
  project: any;
  duration?: string;
}>();

const store = useProjectStore();
const emit = defineEmits<{
  delete: [project: any];
  continue: [project: any];
  dragstart: [projectId: string];
  dragend: [];
}>();

const videoEl = ref<HTMLVideoElement | null>(null);
const isDragging = ref(false);
const isHovered = ref(false);
const videoStarted = ref(false);
const localDuration = ref<string>("");

const videoUrl = computed(() => {
  if (!props.project.video_url) return null;
  if (props.project.video_url.startsWith("http"))
    return props.project.video_url;
  return `${apiConfig.API_BASE_URL}${props.project.video_url}`;
});

const formattedStatus = computed(() => {
  if (!props.project.status) return "Unknown";
  return props.project.status
    .replace(/_/g, " ")
    .replace(/\b\w/g, (c: string) => c.toUpperCase());
});

const statusClasses = computed(() => {
  const s = props.project.status;
  if (s === "completed")
    return "bg-white/80 border border-white/50 text-green-700 bg-green-50/80 border-green-200";
  if (s === "error")
    return "bg-white/80 border border-white/50 text-red-700 bg-red-50/80 border-red-200";
  if (s === "awaiting_approval")
    return "bg-indigo-50/80 border border-indigo-200 text-indigo-700";
  return "bg-white/80 border border-white/50 text-orange-700 bg-orange-50/80 border-orange-200";
});

// Only allow continue for: error, planned, stopped, or cancelled
// BUT also check if there's already an active generation running for this project
const canContinue = computed(() => {
  const s = props.project.status;
  const statusAllowsContinue =
    s === "error" || s === "planned" || s === "stopped" || s === "cancelled";

  // Check if there's already an active generation for this project
  const hasActiveGeneration = Object.values(store.activeGenerations).some(
    (gen: any) => {
      const matchesProject =
        gen.projectId === props.project.id ||
        gen.projectName === props.project.id;
      const isActive = gen.status !== "stopped" && gen.status !== "completed";
      return matchesProject && isActive;
    },
  );

  // Only show continue if status allows it AND no active generation is running
  return statusAllowsContinue && !hasActiveGeneration;
});

const formattedDate = computed(() => {
  if (!props.project.created_at) return "";
  return new Intl.DateTimeFormat("en-US", {
    month: "short",
    day: "numeric",
    year: "numeric",
  }).format(new Date(props.project.created_at));
});

const duration = computed(
  () => props.duration || localDuration.value || props.project.duration,
);

function playPreview() {
  isHovered.value = true;
  videoEl.value?.play().catch(() => {});
}

function pausePreview() {
  isHovered.value = false;
  videoStarted.value = false;
  if (videoEl.value) {
    videoEl.value.pause();
    videoEl.value.currentTime = 0;
  }
}

function onVideoMetadata(e: Event) {
  const secs = (e.target as HTMLVideoElement).duration;
  if (!secs || !isFinite(secs)) return;
  const m = Math.floor(secs / 60);
  const s = Math.floor(secs % 60)
    .toString()
    .padStart(2, "0");
  localDuration.value = `${m}:${s}`;
}

function onDragStart(e: DragEvent) {
  // Small delay lets the browser snapshot the element before we dim it
  requestAnimationFrame(() => {
    isDragging.value = true;
  });
  if (e.dataTransfer) {
    e.dataTransfer.effectAllowed = "move";
    e.dataTransfer.setData("text/plain", props.project.id);
  }
  emit("dragstart", props.project.id);
}

function onDragEnd() {
  isDragging.value = false;
  emit("dragend");
}
</script>

<style scoped>
.project-card-wrapper {
  cursor: grab;
}
.project-card-wrapper.is-dragging {
  opacity: 0.45;
  transform: scale(0.97);
  cursor: grabbing;
}
/* Prevent browser from using its default link-drag ghost */
.project-card-wrapper a {
  -webkit-user-drag: none;
}

@keyframes scan {
  0% {
    transform: translateY(0);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    transform: translateY(180px);
    opacity: 0;
  }
}

@keyframes scan-reverse {
  0% {
    transform: translateY(0);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    transform: translateY(-180px);
    opacity: 0;
  }
}
</style>
