<script setup lang="ts">
import type { WebNovel, Chapter, ReaderPreferences } from '~/types'
import { v5 as uuidv5 } from 'uuid'

// Namespace UUID for generating deterministic chapter UUIDs
const CHAPTER_NAMESPACE = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'

const route = useRoute()
const router = useRouter()
const { addToHistory } = useReaderStorage()

const novelId = computed(() => route.params.novelId as string)
const chapterId = computed(() => route.params.chapterId as string)

const novel = ref<WebNovel | null>(null)
const chapter = ref<Chapter | null>(null)
const chapters = ref<Chapter[]>([])
const chapterUuidMap = ref<Map<string, string>>(new Map()) // UUID -> chapter id mapping
const isLoading = ref(true)
const showControls = ref(false)
const showChapterList = ref(false)
const chapterSearchQuery = ref('')

const preferences = ref<ReaderPreferences>({
  fontSize: 16,
  fontFamily: 'serif',
  lineHeight: 1.8,
  backgroundColor: 'white',
  textColor: 'black',
  theme: 'light',
  textJustify: false
})

const defaultPreferences: ReaderPreferences = {
  fontSize: 16,
  fontFamily: 'serif',
  lineHeight: 1.8,
  backgroundColor: 'white',
  textColor: 'black',
  theme: 'light',
  textJustify: false
}

const currentChapterIndex = computed(() => {
  return chapters.value.findIndex(ch => ch.id === chapterId.value)
})

const filteredChapters = computed(() => {
  if (!chapterSearchQuery.value.trim()) {
    return chapters.value
  }
  const query = chapterSearchQuery.value.toLowerCase()
  return chapters.value.filter(ch =>
    ch.title.toLowerCase().includes(query)
    || ch.number.toString().includes(query)
  )
})

const previousChapter = computed(() => {
  if (currentChapterIndex.value > 0) {
    return chapters.value[currentChapterIndex.value - 1]
  }
  return null
})

const nextChapter = computed(() => {
  if (currentChapterIndex.value < chapters.value.length - 1) {
    return chapters.value[currentChapterIndex.value + 1]
  }
  return null
})

const getBackgroundColor = () => {
  const colors: { [key: string]: string } = {
    white: '#ffffff',
    cream: '#f5f1e8',
    gray: '#f0f0f0',
    black: '#1a1a1a'
  }
  return colors[preferences.value.backgroundColor] || '#ffffff'
}

const getTextColor = () => {
  const colors: { [key: string]: string } = {
    black: '#000000',
    white: '#ffffff',
    gray: '#666666'
  }
  return colors[preferences.value.textColor] || '#000000'
}

const isDarkMode = computed(() => {
  if (import.meta.client) {
    return document.documentElement.classList.contains('dark')
  }
  return false
})

const applyThemeBasedPreset = () => {
  if (isDarkMode.value) {
    // Dark theme → Dark preset (serif + black background + white text)
    preferences.value = {
      ...defaultPreferences,
      fontFamily: 'serif',
      backgroundColor: 'black',
      textColor: 'white'
    }
  } else {
    // Light theme → Modern preset (sans-serif + white background + black text)
    preferences.value = {
      ...defaultPreferences,
      fontFamily: 'sans-serif',
      backgroundColor: 'white',
      textColor: 'black'
    }
  }
}

const loadData = async () => {
  try {
    isLoading.value = true

    // Load novel data from Nuxt Content
    const novelData = await queryCollection('content').path(`/novels/${novelId.value}`).first() as any

    if (!novelData) {
      throw new Error('Novel not found')
    }

    // Map novel data
    const mappedNovel: WebNovel = {
      id: novelId.value,
      slug: novelId.value,
      title: novelData.title || 'Unknown',
      author: novelData.meta?.author || 'Unknown',
      description: novelData.description || novelData.body?.text || '',
      cover: `/images/${novelId.value}/cover.png`,
      status: novelData.meta?.status || 'ongoing',
      genres: novelData.meta?.genres || [],
      rating: novelData.meta?.rating || 0,
      views: novelData.meta?.views || 0,
      followers: novelData.meta?.followers || 0,
      chapters: novelData.meta?.chapters || 0,
      language: novelData.meta?.language || 'English',
      tags: novelData.meta?.tags || [],
      createdAt: novelData.meta?.createdAt || new Date().toISOString(),
      updatedAt: novelData.meta?.updatedAt || new Date().toISOString()
    }
    novel.value = mappedNovel

    // Load all content and filter chapters for this novel
    const allItems = await queryCollection('content').all() as any[]
    const novelChapters = allItems
      .filter((item) => {
        const path = item._path || item.id || ''
        return path.includes(`/novels/${novelId.value}/`) && path.includes('/ch-')
      })
      .map((item, index) => {
        const internalId = item.slug || `ch-${index}`
        // Generate deterministic UUID from novel ID + internal chapter ID
        const uuid = uuidv5(`${novelId.value}/${internalId}`, CHAPTER_NAMESPACE)

        // Store UUID -> internal ID mapping
        chapterUuidMap.value.set(uuid, internalId)

        return {
          id: uuid, // Use UUID for public URLs
          internalId: internalId, // Keep internal reference
          novelId: novelId.value,
          number: item.meta?.number || index + 1,
          title: item.title || `Chapter ${index + 1}`,
          body: item.body, // Store full body for ContentRenderer
          views: item.meta?.views || 0,
          likes: item.meta?.likes || 0,
          createdAt: item.meta?.createdAt || new Date().toISOString(),
          updatedAt: item.meta?.updatedAt || new Date().toISOString()
        }
      })
      .sort((a, b) => a.number - b.number)

    chapters.value = novelChapters

    // Find and load the current chapter using UUID
    let currentChapter = novelChapters.find(ch => ch.id === chapterId.value)

    // If not found by UUID, try by internal ID (backward compatibility)
    if (!currentChapter) {
      currentChapter = novelChapters.find(ch => ch.internalId === chapterId.value)
    }

    if (currentChapter) {
      chapter.value = currentChapter as any
    } else {
      throw new Error('Chapter not found')
    }

    // Load preferences from localStorage
    const saved = localStorage.getItem('readerPreferences')
    if (saved) {
      preferences.value = { ...defaultPreferences, ...JSON.parse(saved) }
    } else {
      // Apply preset based on current app theme
      applyThemeBasedPreset()
    }
  } catch (error) {
    console.error('Error loading data:', error)
  } finally {
    isLoading.value = false
  }
}

const updatePreferences = (updates: Partial<ReaderPreferences>) => {
  preferences.value = { ...preferences.value, ...updates }
}

const savePreferences = () => {
  localStorage.setItem('readerPreferences', JSON.stringify(preferences.value))
}

const resetPreferences = () => {
  preferences.value = { ...defaultPreferences }
}

const goToChapter = (ch: any) => {
  router.push(`/novel/${novelId.value}/${ch.id}`)
}

const handleKeyDown = (e: KeyboardEvent) => {
  if (e.key === 'ArrowLeft' && previousChapter.value) {
    goToChapter(previousChapter.value)
  } else if (e.key === 'ArrowRight' && nextChapter.value) {
    goToChapter(nextChapter.value)
  }
}

onMounted(() => {
  loadData()
  window.addEventListener('keydown', handleKeyDown)
})

onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyDown)
})

// Update SEO meta when chapter is loaded
watch([chapter, novel], ([newChapter, newNovel]) => {
  if (newChapter && newNovel) {
    useSeoMeta({
      title: `${newChapter.title} - ${newNovel.title}`,
      description: newNovel.description,
      ogTitle: `${newChapter.title} - ${newNovel.title}`,
      ogDescription: newNovel.description,
      ogImage: newNovel.cover,
      twitterCard: 'summary_large_image'
    })

    // Add to reading history
    addToHistory({
      novelId: novelId.value,
      novelTitle: newNovel.title,
      chapterId: newChapter.id,
      chapterTitle: newChapter.title,
      cover: newNovel.cover
    })
  }
})
</script>

<template>
  <div
    v-if="chapter && novel"
    class="min-h-screen flex flex-col transition-colors duration-300 w-full"
    :style="{
      backgroundColor: getBackgroundColor(),
      color: getTextColor()
    }"
  >
    <!-- Top Bar -->
    <div
      class="sticky top-0 z-20 border-b transition-colors duration-300"
      :style="{ borderColor: getTextColor() + '20' }"
    >
      <div class="flex items-center justify-between p-4 px-8">
        <!-- <UDashboardSidebarCollapse /> -->
        <button class="p-2 hover:opacity-60 transition-opacity" @click="router.push(`/novels/${novelId}`)">
          <UIcon name="i-lucide-arrow-left" class="size-5" />
        </button>

        <div class="flex-1 mx-4">
          <h1 class="text-sm font-semibold text-center truncate">
            {{ novel.title }}
          </h1>
          <p class="text-xs opacity-60 text-center truncate">
            <!-- Chapter {{ chapter.number }}:  -->
            {{ chapter.title }}
          </p>
        </div>

        <div class="flex items-center gap-2">
          <button
            class="p-2 hover:opacity-60 transition-opacity"
            :title="showControls ? 'Hide controls' : 'Show controls'"
            @click="showControls = !showControls; showChapterList = false"
          >
            <UIcon name="i-lucide-settings" class="size-5" />
          </button>

          <button
            class="p-2 hover:opacity-60 transition-opacity"
            :title="showChapterList ? 'Hide chapters' : 'Show chapters'"
            @click="showChapterList = !showChapterList; showControls = false"
          >
            <UIcon name="i-lucide-book-open" class="size-5" />
          </button>
        </div>
      </div>
    </div>

    <div class="flex flex-1 overflow-hidden">
      <!-- Main Content -->
      <div class="flex-1 overflow-y-auto flex flex-col w-full">
        <div class="flex-1">
          <article
            class="w-full px-8 py-8 prose prose-invert max-w-3xl mx-auto"
            :style="{
              fontSize: `${preferences.fontSize}px`,
              fontFamily: preferences.fontFamily === 'serif' ? 'Merriweather, Georgia, serif'
                : preferences.fontFamily === 'sans-serif' ? '\'Open Sans\', system-ui, sans-serif'
                  : 'monospace',
              lineHeight: preferences.lineHeight,
              textAlign: preferences.textJustify ? 'justify' : 'left'
            }"
          >
            <h1>{{ chapter.title }}</h1>
            <ContentRenderer :value="chapter" />
          </article>
        </div>

        <!-- Navigation -->
        <div class="border-t transition-colors duration-300 mt-8" :style="{ borderColor: getTextColor() + '20' }">
          <div class="w-full px-8 py-8">
            <div class="flex items-center justify-between mb-4">
              <span class="text-sm opacity-60">
                Chapter {{ chapter.number }} of {{ chapters.length }}
              </span>
              <span class="text-sm opacity-60">
                {{ chapter.views.toLocaleString() }} views · {{ chapter.likes.toLocaleString() }} likes
              </span>
            </div>

            <div class="flex gap-4">
              <button
                v-if="previousChapter"
                class="flex-1 p-3 rounded border transition-opacity hover:opacity-60"
                :style="{ borderColor: getTextColor() + '40' }"
                @click="goToChapter(previousChapter)"
              >
                <div class="text-xs opacity-60 mb-1">
                  Previous
                </div>
                <div class="text-sm font-semibold truncate">
                  <!-- Ch{{ previousChapter.number }}:  -->
                  {{ previousChapter.title }}
                </div>
              </button>

              <button
                v-if="nextChapter"
                class="flex-1 p-3 rounded border transition-opacity hover:opacity-60"
                :style="{ borderColor: getTextColor() + '40' }"
                @click="goToChapter(nextChapter)"
              >
                <div class="text-xs opacity-60 mb-1">
                  Next
                </div>
                <div class="text-sm font-semibold truncate">
                  <!-- Ch{{ nextChapter.number }}:  -->
                  {{ nextChapter.title }}
                </div>
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- Chapter List Sidebar -->
      <div
        v-if="showChapterList"
        class="w-80 border-1 overflow-y-auto transition-colors duration-300"
        :style="{ borderColor: getTextColor() + '20' }"
      >
        <div class="p-8">
          <p class="text-lg font-bold mb-4">
            Table Of Contents
            <span class="text-xs opacity-60 ml-2">
              ({{ chapters.length }} Chapter{{ chapters.length !== 1 ? 's' : '' }})
            </span>
          </p>
          <input
            v-model="chapterSearchQuery"
            type="text"
            placeholder="Search chapters..."
            class="w-full px-3 py-2 mb-4 text-sm rounded border transition-colors"
            :style="{
              borderColor: getTextColor() + '20',
              backgroundColor: getBackgroundColor(),
              color: getTextColor()
            }"
          >
          <button
            v-for="ch in filteredChapters"
            :key="ch.id"
            class="w-full text-left p-2 rounded transition-opacity hover:opacity-60"
            :class="{ 'opacity-100 font-semibold': ch.id === chapterId, 'opacity-60': ch.id !== chapterId }"
            @click="goToChapter(ch)"
          >
            <p class="text-xs truncate">
              {{ ch.title }}
            </p>
          </button>
        </div>
      </div>

      <!-- Controls Sidebar -->
      <div
        v-if="showControls"
        class="w-80 border-l overflow-y-auto transition-colors duration-300"
        :style="{ borderColor: getTextColor() + '20' }"
      >
        <div class="p-4">
          <ReaderControls
            :preferences="preferences"
            :background-color="getBackgroundColor()"
            :text-color="getTextColor()"
            @update="updatePreferences"
            @save="savePreferences"
            @reset="resetPreferences"
          />
        </div>
      </div>
    </div>
  </div>

  <!-- Loading skeleton -->
  <div v-else-if="isLoading" class="flex items-center justify-center h-full w-full p-10">
    <USkeleton class="w-full h-full" />
  </div>
</template>

<style scoped>
:deep(.prose) {
  color: inherit;
}

:deep(.prose p) {
  margin: 1em 0;
}

:deep(.prose h1) {
  margin: 1.5em 0 0.5em 0;
  text-size: 1.5em;
}
</style>
