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

const imageCacheName = 'images-v1'

const props = defineProps<{
  childId: string | null
  childPoints: number
  isParentAuthenticated: boolean
}>()
const emit = defineEmits(['trigger-reward'])

const rewards = ref<RewardStatus[]>([])
const loading = ref(true)
const error = ref<string | null>(null)

const scrollWrapper = ref<HTMLDivElement | null>(null)
const rewardRefs = ref<Record<string, HTMLElement | null>>({})
const lastCenteredRewardId = ref<string | null>(null)
const readyRewardId = ref<string | null>(null)

const fetchRewards = async (id: string | number | null) => {
  if (!id) {
    rewards.value = []
    loading.value = false
    return
  }

  loading.value = true
  error.value = null

  try {
    const resp = await fetch(`/api/child/${id}/reward-status`)
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
    const data = await resp.json()
    rewards.value = data.reward_status

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

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

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

const centerReward = async (rewardId: string) => {
  await nextTick()
  const wrapper = scrollWrapper.value
  const card = rewardRefs.value[rewardId]
  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 handleRewardClick = async (rewardId: string) => {
  await nextTick()
  const wrapper = scrollWrapper.value
  const card = rewardRefs.value[rewardId]
  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 || lastCenteredRewardId.value !== rewardId) {
    // Center the reward, but don't trigger
    await centerReward(rewardId)
    lastCenteredRewardId.value = rewardId
    readyRewardId.value = rewardId
    return
  }

  // If already centered and visible, trigger the reward
  await triggerReward(rewardId)
  readyRewardId.value = null
}

const triggerReward = (rewardId: string) => {
  const reward = rewards.value.find((rew) => rew.id === rewardId)
  if (!reward) return // Don't trigger if not allowed
  emit('trigger-reward', reward, reward.points_needed <= 0, reward.redeeming)
}

watch(
  () => props.childId,
  (newId) => {
    fetchRewards(newId)
  },
  { immediate: true },
)

watch(
  () => props.childPoints,
  () => {
    rewards.value.forEach((reward) => {
      reward.points_needed = Math.max(0, reward.cost - props.childPoints)
    })
  },
)

function getPendingRewards(): string[] {
  return rewards.value.filter((r) => r.redeeming).map((r) => r.id)
}

// revoke created object URLs when component unmounts to avoid memory leaks
onBeforeUnmount(() => {
  revokeAllImageUrls()
})

// expose refresh method for parent component
defineExpose({ refresh: () => fetchRewards(props.childId), getPendingRewards })

const isAnyPending = computed(() => rewards.value.some((r) => r.redeeming))
</script>

<template>
  <div class="child-list-container">
    <h3>Rewards</h3>

    <div v-if="loading" class="loading">Loading rewards...</div>
    <div v-else-if="error" class="error">Error: {{ error }}</div>
    <div v-else-if="rewards.length === 0" class="empty">No rewards available</div>

    <div v-else class="scroll-wrapper" ref="scrollWrapper">
      <div class="item-scroll">
        <div
          v-for="r in rewards"
          :key="r.id"
          class="item-card"
          :class="{
            ready: readyRewardId === r.id,
            disabled: isAnyPending && !r.redeeming,
          }"
          :ref="(el) => (rewardRefs[r.id] = el)"
          @click="() => handleRewardClick(r.id)"
        >
          <div class="item-name">{{ r.name }}</div>
          <img v-if="r.image_id" :src="r.image_id" alt="Reward Image" class="item-image" />
          <div class="item-points" :class="{ ready: r.points_needed === 0 }">
            <template v-if="r.points_needed === 0"> REWARD READY </template>
            <template v-else> {{ r.points_needed }} more points </template>
          </div>
          <!-- PENDING block if redeeming is true -->
          <div v-if="r.redeeming" class="pending-block">PENDING</div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped></style>
