<script setup lang="ts">
import { ref, watch, onBeforeUnmount, nextTick, computed } from 'vue'
import { defineProps, defineEmits } from 'vue'
import { getCachedImageUrl, revokeAllImageUrls } from '../../common/imageCache'
import type { Task } from '@/common/models'

const imageCacheName = 'images-v1'

const props = defineProps<{
  title: string
  taskIds: string[]
  childId: string | number | null
  isParentAuthenticated: boolean
  filterType?: number | null
}>()
const emit = defineEmits<{
  (e: 'trigger-task', task: Task): void
}>()

const tasks = ref<Task[]>([])
const loading = ref(true)
const error = ref<string | null>(null)
const scrollWrapper = ref<HTMLDivElement | null>(null)
const taskRefs = ref<Record<string, HTMLElement | null>>({})

const lastCenteredTaskId = ref<string | null>(null)
const readyTaskId = ref<string | null>(null)

const fetchTasks = async () => {
  const taskPromises = props.taskIds.map((id) =>
    fetch(`/api/task/${id}`).then((res) => {
      if (!res.ok) throw new Error(`HTTP ${res.status}`)
      return res.json()
    }),
  )

  try {
    const results = await Promise.all(taskPromises)
    tasks.value = results

    // Fetch images for each task (uses shared imageCache)
    await Promise.all(tasks.value.map(fetchImage))
  } catch (err) {
    error.value = err instanceof Error ? err.message : 'Failed to fetch tasks'
    console.error('Error fetching tasks:', err)
  } finally {
    loading.value = false
  }
}

const fetchImage = async (task: Task) => {
  if (!task.image_id) {
    console.log(`No image ID for task: ${task.id}`)
    return
  }

  try {
    const url = await getCachedImageUrl(task.image_id, imageCacheName)
    task.image_url = url
  } catch (err) {
    console.error('Error fetching image for task', task.id, err)
  }
}

const centerTask = async (taskId: string) => {
  await nextTick()
  const wrapper = scrollWrapper.value
  const card = taskRefs.value[taskId]
  if (wrapper && card) {
    const wrapperRect = wrapper.getBoundingClientRect()
    const cardRect = card.getBoundingClientRect()
    const wrapperScrollLeft = wrapper.scrollLeft
    const cardCenter = cardRect.left + cardRect.width / 2
    const wrapperCenter = wrapperRect.left + wrapperRect.width / 2
    const scrollOffset = cardCenter - wrapperCenter
    wrapper.scrollTo({
      left: wrapperScrollLeft + scrollOffset,
      behavior: 'smooth',
    })
  }
}

const triggerTask = (taskId: string) => {
  const task = tasks.value.find((t) => t.id === taskId)
  if (task) emit('trigger-task', task)
}

const handleTaskClick = async (taskId: string) => {
  await nextTick()
  const wrapper = scrollWrapper.value
  const card = taskRefs.value[taskId]
  if (!wrapper || !card) return

  const wrapperRect = wrapper.getBoundingClientRect()
  const cardRect = card.getBoundingClientRect()
  const cardCenter = cardRect.left + cardRect.width / 2
  const cardFullyVisible = cardCenter >= wrapperRect.left && cardCenter <= wrapperRect.right

  if (!cardFullyVisible || lastCenteredTaskId.value !== taskId) {
    // Center the task, but don't trigger
    await centerTask(taskId)
    lastCenteredTaskId.value = taskId
    readyTaskId.value = taskId
    return
  }

  // If already centered and visible, emit to parent
  triggerTask(taskId)
  readyTaskId.value = null
}

const filteredTasks = computed(() => {
  if (props.filterType == 1) {
    return tasks.value.filter((t) => t.is_good)
  } else if (props.filterType == 2) {
    return tasks.value.filter((t) => !t.is_good)
  }
  return tasks.value
})

watch(
  () => props.taskIds,
  (newTaskIds) => {
    if (newTaskIds && newTaskIds.length > 0) {
      fetchTasks()
    } else {
      tasks.value = []
      loading.value = false
    }
  },
  { immediate: true },
)

// revoke all created object URLs when component unmounts
onBeforeUnmount(() => {
  revokeAllImageUrls()
})
</script>

<template>
  <div class="task-list-container">
    <h3>{{ title }}</h3>

    <div v-if="loading" class="loading">Loading tasks...</div>
    <div v-else-if="error" class="error">Error: {{ error }}</div>
    <div v-else-if="filteredTasks.length === 0" class="empty">No {{ title }}</div>
    <div v-else class="scroll-wrapper" ref="scrollWrapper">
      <div class="task-scroll">
        <div
          v-for="task in filteredTasks"
          :key="task.id"
          class="task-card"
          :class="{ good: task.is_good, bad: !task.is_good, ready: readyTaskId === task.id }"
          :ref="(el) => (taskRefs[task.id] = el)"
          @click="() => handleTaskClick(task.id)"
        >
          <div class="task-name">{{ task.name }}</div>
          <img v-if="task.image_url" :src="task.image_url" alt="Task Image" class="task-image" />
          <div
            class="task-points"
            :class="{ 'good-points': task.is_good, 'bad-points': !task.is_good }"
          >
            {{ task.is_good ? task.points : -task.points }} pts
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.task-list-container {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  padding: 1rem;
  color: white;
  width: 100%;
  box-sizing: border-box;
}

.task-list-container h3 {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
}

.loading,
.error,
.empty {
  text-align: center;
  padding: 1rem;
  font-size: 0.9rem;
  opacity: 0.8;
}

.error {
  color: #ff6b6b;
}

.scroll-wrapper {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-behavior: smooth;
  width: 100%;
  -webkit-overflow-scrolling: touch;
}

/* Modern scrollbar styling */
.scroll-wrapper::-webkit-scrollbar {
  height: 8px;
}

.scroll-wrapper::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.05);
  border-radius: 10px;
}

.scroll-wrapper::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, rgba(102, 126, 234, 0.8), rgba(118, 75, 162, 0.8));
  border-radius: 10px;
  border: 2px solid rgba(255, 255, 255, 0.08);
}

.scroll-wrapper::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, rgba(102, 126, 234, 1), rgba(118, 75, 162, 1));
  box-shadow: 0 0 8px rgba(102, 126, 234, 0.4);
}

.task-scroll {
  display: flex;
  gap: 0.75rem;
  min-width: min-content;
  padding: 0.5rem 0;
}

/* Fallback for browsers that don't support flex gap */
.task-card + .task-card {
  margin-left: 0.75rem;
}
.task-card {
  background: rgba(255, 255, 255, 0.15);
  border-radius: 8px;
  padding: 0.75rem;
  min-width: 140px;
  max-width: 220px;
  width: 100%;
  text-align: center;
  flex-shrink: 0;
  transition: all 0.2s ease;
  border: 2px solid rgba(255, 255, 255, 0.15);
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Outline colors depending on is_good */
.task-card.good {
  border-color: rgba(46, 204, 113, 0.9); /* green */
  background: rgba(46, 204, 113, 0.06);
}

.task-card.bad {
  border-color: rgba(255, 99, 71, 0.95); /* red */
  background: rgba(255, 99, 71, 0.03);
}

.task-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
}

.task-card.ready {
  box-shadow:
    0 0 0 3px #667eea88,
    0 0 12px #667eea44;
  border-color: #667eea;
  animation: ready-glow 0.7s;
}

@keyframes ready-glow {
  0% {
    box-shadow: 0 0 0 0 #667eea00;
    border-color: inherit;
  }
  100% {
    box-shadow:
      0 0 0 3px #667eea88,
      0 0 12px #667eea44;
    border-color: #667eea;
  }
}

.task-name {
  font-size: 0.85rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
  word-break: break-word;
  line-height: 1.2;
  color: #fff;
}

.task-points {
  font-size: 0.75rem;
  font-weight: 700;
}

.task-points.good-points {
  color: #2ecc71;
}

.task-points.bad-points {
  color: #ff6b6b;
}

/* Image styling */
.task-image {
  width: 70px;
  height: 70px;
  object-fit: cover;
  border-radius: 6px;
  margin: 0 auto 0.4rem auto;
  display: block;
}

/* Mobile tweaks */
@media (max-width: 480px) {
  .task-list-container {
    padding: 0.75rem;
    max-width: 100%;
  }
  .task-card {
    min-width: 100px;
    max-width: 150px;
    padding: 0.6rem;
  }
  .task-name {
    font-size: 0.8rem;
  }
  .task-image {
    width: 50px;
    height: 50px;
    margin: 0 auto 0.3rem auto;
  }
  .task-points {
    font-size: 0.72rem;
  }
  .scroll-wrapper::-webkit-scrollbar {
    height: 10px;
  }
  .scroll-wrapper::-webkit-scrollbar-thumb {
    border-width: 1px;
  }
}
</style>
