<template>
  <div
    class="flex animate-fade-up-fast"
    :class="isUser ? 'justify-end' : 'justify-start'"
    :style="{ animationDelay: `${index * 30}ms` }"
  >
    <div
      class="max-w-[85%] md:max-w-[75%] rounded-2xl px-4 py-3 transition-all duration-300"
      :class="[bubbleClasses, { 'cursor-pointer': hasContext }]"
      @click="handleBubbleClick"
    >
      <p class="text-sm leading-relaxed whitespace-pre-wrap break-words"
         :class="isDark ? 'text-white/90' : 'text-gray-800'">{{ displayText }}</p>

      <div v-if="inlineFilms.length > 0" class="mt-3 space-y-1" @click.stop>
        <FilmCard
          v-for="film in inlineFilms"
          :key="film.id"
          :film="film"
          @select="handleFilmSelect"
        />
      </div>

      <div v-if="inlineSongs.length > 0" class="mt-3 space-y-1" @click.stop>
        <SongCard
          v-for="song in inlineSongs"
          :key="song.id"
          :song="song"
          @select="handleSongSelect"
        />
      </div>

      <div v-if="inlinePodcasts.length > 0" class="mt-3 space-y-1" @click.stop>
        <PodcastCard
          v-for="podcast in inlinePodcasts"
          :key="podcast.id"
          :podcast="podcast"
          @select="handlePodcastSelect"
        />
      </div>

      <div v-if="inlineNewsLinks.length > 0" class="mt-3 space-y-1" @click.stop>
        <NewsCard
          v-for="(link, i) in inlineNewsLinks"
          :key="i"
          :article="link"
          @select-article="handleArticleSelect"
        />
      </div>

      <div v-if="inlineWebsitesLinks.length > 0" class="mt-3 space-y-1" @click.stop>
        <NewsCard
          v-for="(link, i) in inlineWebsitesLinks"
          :key="`web-${i}`"
          :article="link"
          @select-article="handleWebsiteSelect"
        />
      </div>

      <div class="flex items-center gap-2 mt-1.5">
        <span class="text-[10px] select-none"
              :class="isDark ? 'text-white/30' : 'text-gray-400'">{{ formattedTime }}</span>
        <button
          v-if="inlineFilms.length > 1"
          class="text-[10px] text-accent/70 hover:text-accent transition-colors"
          @click.stop="openPanel"
        >
          View all {{ inlineFilms.length }} films →
        </button>
        <button
          v-else-if="inlineSongs.length > 1"
          class="text-[10px] text-accent/70 hover:text-accent transition-colors"
          @click.stop="openPanel"
        >
          View all {{ inlineSongs.length }} songs →
        </button>
        <button
          v-else-if="inlinePodcasts.length > 1"
          class="text-[10px] text-accent/70 hover:text-accent transition-colors"
          @click.stop="openPanel"
        >
          View all {{ inlinePodcasts.length }} podcasts →
        </button>
        <button
          v-else-if="inlineNewsLinks.length > 1"
          class="text-[10px] text-accent/70 hover:text-accent transition-colors"
          @click.stop="openPanel"
        >
          View all {{ inlineNewsLinks.length }} articles →
        </button>
        <button
          v-else-if="inlineWebsitesLinks.length > 1"
          class="text-[10px] text-accent/70 hover:text-accent transition-colors"
          @click.stop="openPanel"
        >
          View all {{ inlineWebsitesLinks.length }} websites →
        </button>
        <button
          v-else-if="inlineMagazineSections.length > 0"
          class="text-[10px] text-accent/70 hover:text-accent transition-colors"
          @click.stop="openPanel"
        >
          View brief →
        </button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import type { Message, WebSearchResult } from '@aiui/core/types/message'
import type { Film, Song, Podcast } from '@aiui/core/types/content'
import { useTheme } from '@/composables/useTheme'
import { useContentPanel } from '@/composables/useContentPanel'
import { useArticleOverlayStore } from '@/stores/articleOverlay'
import FilmCard from '@/components/content/FilmCard.vue'
import SongCard from '@/components/content/SongCard.vue'
import PodcastCard from '@/components/content/PodcastCard.vue'
import NewsCard from '@/components/content/NewsCard.vue'

const props = withDefaults(
  defineProps<{
    message: Message
    index: number
    triggeringQuery?: string
  }>(),
  { triggeringQuery: '' }
)

const { isDark } = useTheme()
const { getContextualInlineContent, stripContentTags, stripMarkdownLinks, updatePanelFromText, openFilmDetail, openSongDetail, openPodcastDetail, openArticleDetail, closeFilmDetail, closeSongDetail, closePodcastDetail } = useContentPanel()
const overlayStore = useArticleOverlayStore()

const isUser = computed(() => props.message.role === 'user')

const inlineContent = computed(() => {
  if (isUser.value) return { films: [] as Film[], songs: [] as Song[], podcasts: [] as Podcast[], newsLinks: [], websitesLinks: [] }
  return getContextualInlineContent(props.message.content, props.triggeringQuery, props.message.webResults ?? [])
})

const bubbleClasses = computed(() =>
  isUser.value
    ? 'path-glass-bubble-user rounded-br-md rounded-2xl'
    : 'path-glass-bubble rounded-bl-md rounded-2xl'
)

const inlineFilms = computed(() => inlineContent.value.films)
const inlineSongs = computed(() => inlineContent.value.songs)
const inlinePodcasts = computed(() => inlineContent.value.podcasts)
const inlineNewsLinks = computed(() => inlineContent.value.newsLinks ?? [])
const inlineWebsitesLinks = computed(() => inlineContent.value.websitesLinks ?? [])
const inlineMagazineSections = computed(() => inlineContent.value.magazineSections ?? [])

const hasContext = computed(() => !isUser.value && (
  inlineFilms.value.length > 0 ||
  inlineSongs.value.length > 0 ||
  inlinePodcasts.value.length > 0 ||
  inlineNewsLinks.value.length > 0 ||
  inlineWebsitesLinks.value.length > 0 ||
  inlineMagazineSections.value.length > 0
))

const displayText = computed(() => {
  if (isUser.value) return props.message.content
  let text = stripContentTags(props.message.content)
  if (inlineNewsLinks.value.length > 0 || inlineWebsitesLinks.value.length > 0) text = stripMarkdownLinks(text)
  return text
})

const formattedTime = computed(() => {
  const d = new Date(props.message.timestamp)
  return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
})

function openPanelWithContext() {
  updatePanelFromText(props.message.content, props.triggeringQuery, props.message.webResults ?? [])
}

function handleFilmSelect(film: Film) {
  openPanelWithContext()
  closeSongDetail()
  closePodcastDetail()
  openFilmDetail(film)
}

function handleSongSelect(song: Song) {
  openPanelWithContext()
  closeFilmDetail()
  closePodcastDetail()
  openSongDetail(song)
}

function handlePodcastSelect(podcast: Podcast) {
  openPanelWithContext()
  closeFilmDetail()
  closeSongDetail()
  openPodcastDetail(podcast)
}

function openPanel() {
  closeFilmDetail()
  closeSongDetail()
  closePodcastDetail()
  openPanelWithContext()
}

function handleArticleSelect(article: WebSearchResult) {
  openPanelWithContext()
  openArticleDetail(article)
}

function handleWebsiteSelect(article: WebSearchResult) {
  overlayStore.open(article.url, article.title, undefined, article.imgSrc)
}

function handleBubbleClick() {
  if (hasContext.value) openPanel()
}
</script>
