<script setup lang="ts">
import { debounce, isEmpty } from '~/utils/helpers'

// Constants
const CHAMPIONS_API_URL = '/api/champions'

// State
const {
  data: championsData,
  pending: loadingChampions,
  error: championsError
} = useFetch('/api/cdragon/champion-summary', {
  key: 'champions-data',
  lazy: false,
  server: false // Disable server-side fetching to avoid hydration issues
})
const {
  data: championsLanes,
  pending: loadingLanes,
  error: lanesError
} = useFetch(CHAMPIONS_API_URL, {
  key: 'champions-lanes',
  lazy: false,
  server: false // Disable server-side fetching to avoid hydration issues
})

// Data processing
const champions = computed(() => {
  if (!championsData.value || !Array.isArray(championsData.value)) return []

  return championsData.value
    .slice(1)
    .filter((champion: ChampionSummary) => !champion.name.includes('Doom Bot'))
    .sort((a: ChampionSummary, b: ChampionSummary) => a.name.localeCompare(b.name))
})

const lanesMap = computed(() => {
  const map = new Map<string, LaneData[]>()
  if (championsLanes.value) {
    for (const champion of championsLanes.value as ChampionData[]) {
      map.set(champion.alias.toLowerCase(), champion.lanes)
    }
  }
  return map
})

// Filter state
const filteredChampions = ref<ChampionSummary[]>([])
const searchText = ref('')
const searchBar = useTemplateRef('searchBar')

// Lane filtering
function filterToLane(filter: number): string {
  const laneMap = ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'UTILITY']
  return laneMap[filter] || ''
}

function filterChampionsByLane(laneFilter: number): void {
  if (laneFilter === -1) {
    filteredChampions.value = [...champions.value]
    return
  }

  const laneName = filterToLane(laneFilter)
  filteredChampions.value = champions.value.filter((champion: ChampionSummary) => {
    const championLanes = lanesMap.value.get(champion.alias.toLowerCase())
    if (!championLanes) return false

    return championLanes.some(lane => lane.data === laneName)
  })
}

// Search functionality
const debouncedSearch = debounce((searchTerm: string) => {
  if (isEmpty(searchTerm)) {
    filteredChampions.value = [...champions.value]
  } else {
    filteredChampions.value = champions.value.filter((champion: ChampionSummary) =>
      champion.name.toLowerCase().includes(searchTerm.toLowerCase())
    )
  }
}, 300)

// Watchers
watch(searchBar, (_newS, _oldS) => {
  searchBar.value?.focus()
})

watch(searchText, newTerm => {
  debouncedSearch(newTerm)
})

// Watch for changes in champions data and update filtered champions
watch(
  champions,
  newChampions => {
    filteredChampions.value = [...newChampions]
  },
  { immediate: true }
)

// Navigation
function navigateToChampion(championAlias: string): void {
  try {
    navigateTo(`/champion/${championAlias.toLowerCase()}`)
  } catch (error) {
    console.error('Navigation error:', error)
  }
}

// Initialize filtered champions
onMounted(() => {
  filteredChampions.value = [...champions.value]
})

// Error handling
const hasErrors = computed(() => championsError.value || lanesError.value)
const isLoading = computed(() => loadingChampions.value || loadingLanes.value)
</script>

<template>
  <div>
    <!-- Loading state -->
    <div v-if="isLoading" class="loading-state">
      <div class="loading-spinner" />
      <p>Loading champions...</p>
    </div>

    <!-- Error state -->
    <div v-else-if="hasErrors" class="error-state">
      <p>Failed to load champion data. Please refresh the page.</p>
    </div>

    <!-- Main content -->
    <div v-else>
      <div class="search-lanefilter-container">
        <LaneFilter id="cs-lanefilter" @filter-change="filterChampionsByLane" />
        <input
          ref="searchBar"
          v-model="searchText"
          class="search-bar"
          type="text"
          placeholder="Search a champion"
          @keyup.enter="
            () => filteredChampions.length > 0 && navigateToChampion(filteredChampions[0].alias)
          "
        />
      </div>

      <!-- Empty state -->
      <div v-if="filteredChampions.length === 0" class="empty-state">
        <p>No champions found. Try a different search or filter.</p>
      </div>

      <div v-else class="champion-container">
        <NuxtLink
          v-for="champion in filteredChampions"
          :key="champion.id"
          :to="'/champion/' + champion.alias.toLowerCase()"
          style="width: fit-content; height: fit-content"
        >
          <div class="cs-champion-img-container">
            <NuxtImg
              format="webp"
              class="cs-champion-img"
              :src="CDRAGON_BASE + mapPath(champion.squarePortraitPath)"
              :alt="champion.name"
            />
          </div>
        </NuxtLink>
      </div>
    </div>
  </div>
</template>

<style>
/* Loading and error states */
.loading-state,
.error-state,
.empty-state {
  text-align: center;
  padding: 40px 20px;
  color: var(--color-on-surface);
  font-size: 1.2rem;
}

.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid var(--color-surface);
  border-top: 4px solid var(--color-primary);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.loading-state p {
  margin: 0;
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 0.6;
  }
  50% {
    opacity: 1;
  }
}

.error-state {
  color: var(--color-error);
}

.empty-state {
  opacity: 0.7;
}

.search-bar {
  width: 400px;
  height: 60px;

  background-color: var(--color-surface-darker);

  font-size: 1.75rem;

  border-radius: 12px;
  border: none;
  padding-left: 10px;
}
.search-bar:focus {
  border: 2px solid var(--color-on-surface);
  outline: none;
}

#cs-lanefilter {
  margin: auto;
  margin-right: 20px;
}

.search-lanefilter-container {
  width: fit-content;
  margin: auto;
  display: flex;
  align-items: center;
}

.champion-container {
  width: 90%;
  height: auto;

  display: grid;
  grid-template-columns: repeat(auto-fit, 128px);
  grid-gap: 10px;
  justify-content: center;

  margin: auto;
  margin-top: 20px;
  margin-bottom: 20px;
}
.cs-champion-img-container {
  overflow: hidden;
  width: 120px;
  height: 120px;
  border: 1px solid var(--color-surface);
}
.cs-champion-img-container:hover {
  border: 1px solid var(--color-on-surface);
}
.cs-champion-img {
  width: 116px;
  height: 116px;
  transform: translate(4px, 4px) scale(1.2, 1.2);

  user-select: none;
}

@media only screen and (max-width: 920px) {
  .search-lanefilter-container {
    flex-direction: column;
  }
  #cs-lanefilter {
    margin-right: auto;
  }
  .champion-container {
    width: 100%;
  }
}
@media only screen and (max-width: 450px) {
  .search-bar {
    width: 92%;
    height: 40px;
  }
  .cs-champion-img-container {
    width: 80px;
    height: 80px;
  }
  .cs-champion-img {
    width: 76px;
    height: 76px;
  }
  .champion-container {
    grid-template-columns: repeat(auto-fit, 80px);
  }
  .search-lanefilter-container {
    margin-top: 10px;
  }
}
</style>
