<script setup lang="ts">
import { ref, watch, onMounted } from 'vue'
import { getCachedImageUrl } from '@/common/imageCache'

const props = defineProps<{
  fetchUrl: string
  itemKey: string
  itemFields: readonly string[]
  imageFields?: readonly string[]
  selectable?: boolean
  deletable?: boolean
  onClicked?: (item: any) => void
  onDelete?: (id: string) => void
  filterFn?: (item: any) => boolean
  getItemClass?: (item: any) => string | string[] | Record<string, boolean>
}>()

const emit = defineEmits(['clicked', 'delete', 'loading-complete'])

const items = ref<any[]>([])
const loading = ref(true)
const error = ref<string | null>(null)
const selectedItems = ref<string[]>([])

defineExpose({
  items,
  selectedItems,
})

const fetchItems = async () => {
  loading.value = true
  error.value = null
  console.log(`Fetching items from: ${props.fetchUrl}`)
  try {
    const resp = await fetch(props.fetchUrl)
    console.log(`Fetch response status: ${resp.status}`)
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
    const data = await resp.json()
    //console log all data
    console.log('Fetched data:', data)
    let itemList = data[props.itemKey || 'items'] || []
    if (props.filterFn) itemList = itemList.filter(props.filterFn)
    const initiallySelected: string[] = []
    await Promise.all(
      itemList.map(async (item: any) => {
        if (props.imageFields) {
          for (const field of props.imageFields) {
            if (item[field]) {
              try {
                item[`${field.replace('_id', '_url')}`] = await getCachedImageUrl(item[field])
              } catch {
                console.error('Error fetching image for item', item.id)
                item[`${field.replace('_id', '_url')}`] = null
              }
            }
          }
        } else if (item.image_id) {
          try {
            item.image_url = await getCachedImageUrl(item.image_id)
          } catch {
            item.image_url = null
          }
        }
        //for each item see it there is an 'assigned' field that is true.  if so check the item's selectable checkbox
        if (props.selectable && item.assigned === true) {
          initiallySelected.push(item.id)
        }
      }),
    )
    items.value = itemList
    if (props.selectable) {
      selectedItems.value = initiallySelected
    }
  } catch (err) {
    error.value = err instanceof Error ? err.message : 'Failed to fetch items'
    items.value = []
    if (props.selectable) selectedItems.value = []
  } finally {
    emit('loading-complete', items.value.length)
    loading.value = false
  }
}

onMounted(fetchItems)
watch(() => props.fetchUrl, fetchItems)

const handleClicked = (item: any) => {
  emit('clicked', item)
  props.onClicked?.(item)
}
const handleDelete = (item: any) => {
  emit('delete', item)
  props.onDelete?.(item)
}
</script>

<template>
  <div class="listbox">
    <div v-if="loading" class="loading">Loading...</div>
    <div v-else-if="error" class="error">{{ error }}</div>
    <div v-else-if="items.length === 0" class="empty">No items found.</div>
    <div v-else>
      <div v-for="(item, idx) in items" :key="item.id" class="list-row">
        <div :class="['list-item', props.getItemClass?.(item)]" @click.stop="handleClicked(item)">
          <slot name="item" :item="item">
            <!-- Default rendering if no slot is provided -->
            <img v-if="item.image_url" :src="item.image_url" />
            <span class="list-name">List Item</span>
            <span class="list-value">1</span>
          </slot>
          <div v-if="props.selectable || props.deletable" class="interact">
            <input
              v-if="props.selectable"
              type="checkbox"
              class="list-checkbox"
              v-model="selectedItems"
              :value="item.id"
              @click.stop
            />
            <button
              v-if="props.deletable"
              class="delete-btn"
              @click.stop="handleDelete(item)"
              aria-label="Delete item"
              type="button"
            >
              <!-- SVG icon here -->
              <svg width="20" height="20" viewBox="0 0 20 20" fill="none" aria-hidden="true">
                <circle cx="10" cy="10" r="9" fill="#fff" stroke="#ef4444" stroke-width="2" />
                <path
                  d="M7 7l6 6M13 7l-6 6"
                  stroke="#ef4444"
                  stroke-width="2"
                  stroke-linecap="round"
                />
              </svg>
            </button>
          </div>
          <div v-if="idx < items.length - 1" class="list-separator"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.listbox {
  flex: 0 1 auto;
  max-width: 480px;
  width: 100%;
  max-height: calc(100vh - 4.5rem);
  overflow-y: auto;
  margin: 0.2rem 0 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  background: var(--list-bg);
  padding: 0.2rem 0.2rem 0.2rem;
  border-radius: 12px;
}
.list-item {
  display: flex;
  align-items: center;
  border: 2px outset var(--list-item-border-reward);
  border-radius: 8px;
  padding: 0.2rem 1rem;
  background: var(--list-item-bg);
  font-size: 1.05rem;
  font-weight: 500;
  transition: border 0.18s;
  margin-bottom: 0.2rem;
  margin-left: 0.2rem;
  margin-right: 0.2rem;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.03);
  box-sizing: border-box;
  justify-content: space-between;
  cursor: pointer;
}
.list-item .interact {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* Image styles */
:deep(.list-item img) {
  width: 36px;
  height: 36px;
  object-fit: cover;
  border-radius: 8px;
  margin-right: 0.7rem;
  background: var(--list-image-bg);
  flex-shrink: 0;
}

/* Name/label styles */
.list-name {
  flex: 1;
  text-align: left;
  font-weight: 600;
}

/* Points/cost/requested text */
.list-value {
  min-width: 60px;
  text-align: right;
  font-weight: 600;
}
.delete-btn {
  background: transparent;
  border: none;
  border-radius: 50%;
  margin-left: 0.7rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  transition:
    background 0.15s,
    box-shadow 0.15s;
  width: 2rem;
  height: 2rem;
  opacity: 0.92;
}
.delete-btn:hover {
  background: var(--delete-btn-hover-bg);
  box-shadow: 0 0 0 2px var(--delete-btn-hover-shadow);
  opacity: 1;
}
.delete-btn svg {
  display: block;
}

/* Checkbox */
.list-checkbox {
  margin-left: 1rem;
  width: 1.2em;
  height: 1.2em;
  accent-color: var(--checkbox-accent);
  cursor: pointer;
}

/* Loading, error, empty states */
.loading,
.empty {
  margin: 1.2rem 0;
  color: var(--list-loading-color);
  font-size: 1.15rem;
  font-weight: 600;
  text-align: center;
  line-height: 1.5;
}
.error {
  color: var(--error);
  margin-top: 0.7rem;
  text-align: center;
  background: var(--error-bg);
  border-radius: 8px;
  padding: 1rem;
}
/* Separator (if needed) */
.list-separator {
  height: 0px;
  background: #0000;
  margin: 0rem 0.2rem;
  border-radius: 0px;
}
</style>
