<script setup lang="ts">
import { ref, computed, onMounted, nextTick, onBeforeUnmount, watch } from 'vue'
import { useRouter } from 'vue-router'
import { v4 as uuidv4 } from 'uuid'
import { useAgentCatalogStore, type AgentBrief } from '@/store/agentCatalogStore'
import ChatInput from './ChatInput.vue'
import { Card } from './ui/card'
import { getAgentTypeIcon } from '@/lib/agentUtils'
import { Button } from './ui/button'
import { Popover, PopoverContent, PopoverTrigger } from './ui/popover'
import CustomMainHeader from '@/components/CustomMainHeader.vue'
import { WT1iser } from '@/lib/wt1'
import { usePrefStore } from '@/store/prefStore'
import { useConversationStore } from '@/store/conversationStore'
import type { SuggestedExample } from '@/types/agent'
import AgentPopover from '@/components/AgentPopover.vue'
import { toRaw } from 'vue'
import type { Message, MessageAttachment } from '@/types/messages'

const router = useRouter()

// Use the centralized chat store
const conversationStore = useConversationStore()
const catalog = useAgentCatalogStore()

// Chat input state
const selectedAgents = ref<string[]>([])
// Track if input has content for typing effect
const inputHasContent = ref(false)

// Track mode: agents vs LLM
const modeAgents = ref(true)
const selectedLlm = ref<string | null>(null)
// Track if we're in homepage example mode vs manual agent selection mode
const homepageExampleMode = ref(false)
const lastHomepageAgents = ref<string[]>([])

// Track hover state for each agent
const agentHoverStates = ref<Record<string, boolean>>({})

// Reference to ChatInput component for focus management
const chatInputRef = ref<InstanceType<typeof ChatInput> | null>(null)

// Animation state
const animationsStarted = ref(false)

// Example toggle state - use prefStore like ChatInterface
const showExampleToggle = computed({
  get: () => usePrefStore().showChatExamples,
  set: (value) => {
    usePrefStore().setShowChatExamples(value)
  },
})

// Watch for toggle changes to trigger animations
watch(showExampleToggle, (newVal) => {
  if (newVal && selectedAgents.value.length > 0 && modeAgents.value) {
    animationsStarted.value = false
    nextTick(() => (animationsStarted.value = true))
  }
})

// Typing effect for placeholder
const currentPlaceholder = ref('Ask Anything')
const typingTimer = ref<number | null>(null)
const questionIndex = ref(0)
const charIndex = ref(0)

// Get example questions for typing effect based on agent selection
const allExampleQuestions = computed<SuggestedExample[]>(() => {
  // Don't return questions if agents mode is disabled
  if (!modeAgents.value) {
    return []
  }
  // If no agent is selected, use homepage examples
  if (selectedAgents.value.length === 0) {
    const homepageQuestions = allAgentsExamples.value
      .filter((ex) => ex.query && ex.query.trim() !== '')
      .map((ex) => ({
        agentId: ex.agentIds[0] || '', // Use first agent ID if available
        question: ex.query,
        agent: ex.agents[0] || null, // Use first agent if available
      }))
      .sort((a, b) => a.question.localeCompare(b.question))

    const askAnything: SuggestedExample = {
      agentId: '',
      question: 'Ask Anything',
      agent: null,
    }

    return homepageQuestions.length > 0 ? [askAnything, ...homepageQuestions] : []
  }

  // If agents are selected, combine example questions from all selected agents
  const exampleQuestions = selectedAgents.value
    .map((agentId) => catalog.agents.find((a) => a.id === agentId))
    .filter((agent) => agent != null)
    .flatMap((agent) =>
      (agent.exampleQuestions || [])
        .filter((q: string) => q && q.trim() !== '')
        .map((q: string) => ({
          agentId: agent.id,
          question: q,
          agent: agent,
        }))
    )
    .sort((a, b) => a.question.localeCompare(b.question))

  if (exampleQuestions.length > 0) {
    const askAnything: SuggestedExample = {
      agentId: '',
      question: 'Ask Anything',
      agent: null,
    }
    return [askAnything, ...exampleQuestions]
  }

  return []
})

// Progressive loading for selected agent examples
const examplesToShow = ref(3)
const selectedAgentExamples = computed<SuggestedExample[]>(() => {
  if (selectedAgents.value.length === 0) return []
  return allExampleQuestions.value.filter((ex) => ex.agentId !== '' && ex.question.trim() !== '') // Exclude "Ask Anything" and empty questions
})
const displayedSelectedAgentExamples = computed<SuggestedExample[]>(() =>
  selectedAgentExamples.value.slice(0, examplesToShow.value)
)
const hasMoreSelectedExamples = computed(
  () => examplesToShow.value < selectedAgentExamples.value.length
)

function loadMoreSelectedExamples() {
  examplesToShow.value = selectedAgentExamples.value.length
  // Re-trigger animations for newly shown examples
  animationsStarted.value = false
  nextTick(() => (animationsStarted.value = true))
}

// Simplified typing effect
function startTypingEffect() {
  stopTypingEffect()

  if (!modeAgents.value || allExampleQuestions.value.length <= 1 || inputHasContent.value) {
    currentPlaceholder.value = 'Ask Anything'
    return
  }

  const animate = () => {
    const questions = allExampleQuestions.value
    const currentQ = questions[questionIndex.value].question
    const nextQ = questions[(questionIndex.value + 1) % questions.length].question

    // Typing phase
    if (charIndex.value < currentQ.length) {
      currentPlaceholder.value = currentQ.slice(0, charIndex.value + 1)
      charIndex.value++
      typingTimer.value = window.setTimeout(animate, 50)
    }
    // Pause phase
    else if (charIndex.value === currentQ.length) {
      charIndex.value++
      typingTimer.value = window.setTimeout(animate, 2000)
    }
    // Erasing phase - find common prefix
    else {
      let commonLen = 0
      const minLen = Math.min(currentQ.length, nextQ.length)
      for (let i = 0; i < minLen; i++) {
        if (currentQ[i] === nextQ[i]) commonLen = i + 1
        else break
      }

      const currentLen = currentPlaceholder.value.length
      if (currentLen > commonLen) {
        currentPlaceholder.value = currentQ.slice(0, currentLen - 1)
        typingTimer.value = window.setTimeout(animate, 30)
      } else {
        // Move to next question
        questionIndex.value = (questionIndex.value + 1) % questions.length
        charIndex.value = commonLen
        currentPlaceholder.value = nextQ.slice(0, commonLen)
        typingTimer.value = window.setTimeout(animate, 500)
      }
    }
  }

  animate()
}

function stopTypingEffect() {
  if (typingTimer.value) {
    clearTimeout(typingTimer.value)
    typingTimer.value = null
  }
}

// Computed properties for agent examples (must be defined before watches that use them)
const allAgentsExamples = computed(() => {
  const prefStore = usePrefStore()
  const homepageExamples = prefStore.uiConf?.homepage_examples ?? []

  if (homepageExamples.length === 0) return []

  return homepageExamples.map((example) => ({
    label: example.homepage_example_label,
    query: example.homepage_example_query,
    agentIds: example.selected_agents || [],
    agents: (example.selected_agents || [])
      .map((agentId) => catalog.agents.find((a) => a.id === agentId))
      .filter((a) => a != null),
  }))
})

const agentsExamples = computed(() => {
  return allAgentsExamples.value
})

// Watch for user input and catalog changes
watch(inputHasContent, (val) => {
  if (val) stopTypingEffect()
  else if (modeAgents.value && allExampleQuestions.value.length > 0) {
    questionIndex.value = 0
    charIndex.value = 0
    startTypingEffect()
  }
})

watch(
  () => allExampleQuestions.value,
  (questions) => {
    if (!inputHasContent.value && modeAgents.value && questions.length > 0) {
      questionIndex.value = 0
      charIndex.value = 0
      nextTick(startTypingEffect)
    } else if (questions.length === 0) {
      currentPlaceholder.value = 'Ask Anything'
    }
  },
  { immediate: true }
)

watch(modeAgents, (isAgentsMode) => {
  if (!isAgentsMode) {
    // Agents disabled - stop typing and reset to default
    stopTypingEffect()
    currentPlaceholder.value = 'Ask Anything'
  } else {
    // Agents enabled - restart typing if appropriate
    if (!inputHasContent.value && allExampleQuestions.value.length > 0) {
      questionIndex.value = 0
      charIndex.value = 0
      nextTick(startTypingEffect)
    }
  }
})

// Watch for agent selection changes to restart typing effect
watch(selectedAgents, (newAgents) => {
  if (!inputHasContent.value && modeAgents.value && allExampleQuestions.value.length > 0) {
    questionIndex.value = 0
    charIndex.value = 0
    nextTick(startTypingEffect)
  }
  // Reset examples to show when agents change
  examplesToShow.value = 3

  // Check if this is a manual agent change (not from homepage example)
  if (homepageExampleMode.value) {
    // Compare new agents with last homepage agents
    const isSameAsHomepage =
      newAgents.length === lastHomepageAgents.value.length &&
      newAgents.every((id) => lastHomepageAgents.value.includes(id))

    if (!isSameAsHomepage) {
      // User manually changed agents, exit homepage example mode
      homepageExampleMode.value = false
      lastHomepageAgents.value = []
      // Trigger animations when switching to agent examples
      if (selectedAgents.value.length > 0) {
        animationsStarted.value = false
        nextTick(() => (animationsStarted.value = true))
      }
    }
  } else {
    // Trigger animations when agent examples appear (not in homepage mode)
    if (selectedAgents.value.length > 0) {
      animationsStarted.value = false
      nextTick(() => (animationsStarted.value = true))
    }
  }

  // If all agents are removed, reset homepage example mode
  if (newAgents.length === 0) {
    homepageExampleMode.value = false
    lastHomepageAgents.value = []
  }
})

// Watch for conversationStore agent changes and sync with local selectedAgents
watch(
  () => conversationStore.agentIds,
  (newAgentIds) => {
    selectedAgents.value = [...newAgentIds]
  }
)

// Start card animations when examples are ready
watch(
  () => allAgentsExamples.value.length,
  (newLen, oldLen) => {
    if (newLen > 0 && oldLen === 0) {
      nextTick(() => (animationsStarted.value = true))
    }
  }
)

function handleResetInput() {
  chatInputRef.value?.setMessage('')
}
const emit = defineEmits<{
  (e: 'loaded', val: boolean): void
}>()
onMounted(async () => {
  try {
    await catalog.load()
    await usePrefStore().load()
    const conf = await usePrefStore().uiConf
    if (!conf || conf.default_llm === undefined) {
      WT1iser.error('HomePage', 'no conf')
      emit('loaded', false)
    } else {
      if (!WT1iser.initialized) {
        WT1iser.init(conf)
      }
      if (!WT1iser.opened) {
        WT1iser.open()
      }
      emit('loaded', true)
    }
    // Sync selected agents from conversationStore if any
    if (conversationStore.agentIds.length > 0) {
      selectedAgents.value = [...conversationStore.agentIds]
    }
    await nextTick()
    chatInputRef.value?.focusInput()
    animationsStarted.value = true
    window.addEventListener('reset-home-input', handleResetInput)
  } catch (e) {
    emit('loaded', false)
  }
})

onBeforeUnmount(() => {
  stopTypingEffect()
  window.removeEventListener('reset-home-input', handleResetInput)
})

// Handle chat input send - redirect to conversation page
function handleChatSend(data: { text: string; attachments?: MessageAttachment[] } | string) {
  const messageText = typeof data === 'string' ? data : data.text
  const attachments = typeof data === 'string' ? [] : data.attachments ?? []
  const hasText = messageText.trim().length > 0
  const hasAttachments = attachments.length > 0

  if (hasText || hasAttachments) {
    const conversationId = conversationStore.activeConversationId || uuidv4()
    const initialMessage: Message = {
      role: 'user',
      content: messageText.trim(),
      attachments: attachments,
    }

    conversationStore.initializeConversation(
      conversationId,
      selectedAgents.value,
      modeAgents.value,
      selectedLlm.value,
      {
        initialMessage: initialMessage,
      }
    )

    conversationStore.setActiveConversation(conversationId)

    // Clear attachments from ChatInput before navigating
    chatInputRef.value?.clearAttachments()

    // Navigate to conversations page
    router.push({ name: 'Conversations', query: { submit: 'true' } })

    homepageExampleMode.value = false
    lastHomepageAgents.value = []
  }
}

// Handle short example query click - select agents and set query as message
function handleShortQueryClick(example: any) {
  WT1iser.selectExampleQuery()
  // Set homepage example mode and track the agents
  homepageExampleMode.value = true
  lastHomepageAgents.value = [...example.agentIds]
  // Update selected agents to match the example
  selectedAgents.value = [...example.agentIds]
  // Set the query in the input using ChatInput's exposed method
  chatInputRef.value?.setMessage(example.query.trim())
}

// Handle selected agent example click - set query as message
function handleSelectedAgentExampleClick(example: SuggestedExample) {
  WT1iser.selectExampleQuery()
  chatInputRef.value?.setMessage(example.question)
}

// Handle agent selection click - redirect to conversation with agent
function handleAgentSelectionClick(agent: AgentBrief) {
  // Create a new conversation with the selected agent
  const conversationId = uuidv4()
  conversationStore.initializeConversation(conversationId, [agent.id], true, null)
  conversationStore.setActiveConversation(conversationId)
  WT1iser.selectAgent(agent.isEnterprise ? 'enterprise' : 'published')
  // Navigate to conversations page
  router.push({ name: 'Conversations' })
}

function goTo(page: string) {
  if (page === 'Dashboard') {
    WT1iser.viewMonitoring()
  } else if (page === 'AgentLibrary') {
    WT1iser.viewAgentLibrary()
  }
  router.push({ name: page })
}
</script>

<template>
  <header class="w-full h-[58px] md:h-[4px] py-1.5 md:py-0 border-t-[4px] border-t-primary">
    <CustomMainHeader />
  </header>

  <!-- Home content -->
  <div
    class="flex-1 h-full flex flex-col items-center justify-around px-3 sm:px-[60px] md:px-[80px] xl:px-60"
  >
    <!-- Chat Input -->
    <div class="w-full max-w-3xl -mt-50 md:-mt-24 relative">
      <div class="text-center">
        <img
          src="@/assets/dataiku-logo.png"
          alt="Dataiku Logo"
          class="h-[70px] w-[70px] mx-auto mb-2"
        />
        <h1 class="text-3xl font-bold text-primary-alpha-dark-70">Welcome to Agent Hub</h1>
      </div>
      <ChatInput
        ref="chatInputRef"
        v-model:selectedAgents="selectedAgents"
        :allAgents="catalog.agents"
        :isStreaming="false"
        :chatDisabled="false"
        :hasDeletedSelected="false"
        :inputPlaceholder="currentPlaceholder"
        :disableAgentSelection="false"
        v-model:mode-agents="modeAgents"
        v-model:selected-llm="selectedLlm"
        :activeOnlyAgents="true"
        :hideExampleToggle="
          (selectedAgents.length === 0 && allExampleQuestions.length === 0) ||
          homepageExampleMode ||
          !modeAgents
        "
        @send="handleChatSend"
        @update:hasContent="inputHasContent = $event"
        :exampleQuestions="allExampleQuestions"
      />
      <!-- Short example queries section - Absolute positioning -->
      <div
        class="absolute top-full left-0 right-0 mt-1 z-10"
        v-if="modeAgents && (selectedAgents.length === 0 || homepageExampleMode)"
      >
        <div class="flex flex-row flex-wrap gap-2 items-center justify-center w-full">
          <template v-for="(example, exampleIdx) in agentsExamples" :key="exampleIdx">
            <Card
              class="rounded-md shadow px-3 py-1 flex flex-row gap-2 cursor-pointer hover:bg-primary/10 hover:border-primary-alpha-dark-80 hover:text-primary-alpha-dark-80 transition-colors text-sm short-example-card"
              :class="{ 'animate-in': animationsStarted }"
              :style="{ 'animation-delay': `${exampleIdx * 300}ms` }"
              @click="handleShortQueryClick(example)"
            >
              <Popover
                :open="agentHoverStates['example-' + exampleIdx]"
                @update:open="(open) => (agentHoverStates['example-' + exampleIdx] = open)"
              >
                <PopoverTrigger as-child>
                  <i
                    class="my-auto dku-icon-briefcase-16"
                    @mouseenter="agentHoverStates['example-' + exampleIdx] = true"
                    @mouseleave="agentHoverStates['example-' + exampleIdx] = false"
                  ></i>
                </PopoverTrigger>
                <PopoverContent
                  class="w-80"
                  side="top"
                  @mouseenter="agentHoverStates['example-' + exampleIdx] = true"
                  @mouseleave="agentHoverStates['example-' + exampleIdx] = false"
                >
                  <div class="flex flex-col gap-2">
                    <p class="text-sm text-foreground">{{ example.query }}</p>
                    <div v-if="example.agents.length > 0" class="flex items-center gap-1">
                      <i class="dku-icon-ai-agent-16"></i>
                      <span class="text-xs text-muted-foreground">
                        {{ example.agents.map((a) => a.name).join(', ') }}
                      </span>
                    </div>
                  </div>
                </PopoverContent>
              </Popover>
              <div>{{ example.label || example.query }}</div>
            </Card>
          </template>
        </div>
      </div>

      <!-- Selected agent examples section - Absolute positioning -->
      <div
        v-if="
          modeAgents &&
          selectedAgents.length > 0 &&
          !homepageExampleMode &&
          displayedSelectedAgentExamples.length > 0 &&
          showExampleToggle
        "
        class="absolute top-full left-0 right-0 mt-1 space-y-2 z-10 max-h-[210px] overflow-y-auto"
      >
        <Card
          v-for="(ex, idx) in displayedSelectedAgentExamples"
          :key="`${ex.agentId}:${ex.question}:${idx}`"
          @click="handleSelectedAgentExampleClick(ex)"
          class="rounded-md shadow px-2 py-2 flex flex-row gap-2 cursor-pointer hover:bg-primary/10 hover:border-primary-alpha-dark-80 hover:text-primary-alpha-dark-80 transition-colors text-sm leading-6 agent-example-card"
          :class="{ 'animate-in': animationsStarted }"
          :style="{ 'animation-delay': `${idx * 100}ms` }"
        >
          <AgentPopover
            :icon="getAgentTypeIcon(toRaw(ex.agent), 16)"
            :name="ex.agent.name"
            :description="ex.agent.description"
          />
          <span class="text-foreground">{{ ex.question }}</span>
        </Card>

        <!-- More button for selected agent examples -->
        <Card
          v-if="hasMoreSelectedExamples"
          key="more-selected"
          class="rounded-lg p-4 py-2 text-base shadow-sm cursor-pointer hover:bg-gray-50 transition-colors w-fit agent-example-card"
          :class="{ 'animate-in': animationsStarted }"
          :style="{ 'animation-delay': `${displayedSelectedAgentExamples.length * 100}ms` }"
          @click="loadMoreSelectedExamples"
        >
          <p class="flex items-center text-foreground text-sm">
            More <i class="dku-icon-plus-16 ml-1"></i>
          </p>
        </Card>
      </div>
    </div>
    <!-- Hidden -->
    <div class="w-full max-w-3xl" v-if="false">
      <div class="flex items-center mb-1" v-if="catalog.activeAgents.length > 0">
        <i class="dku-icon-ai-agent-20 mr-1"></i>
        <h1 class="text-foreground text-xl">New Agents</h1>
        <!-- Agents selection -->
      </div>
      <div class="flex flex-col gap-2 justify-center">
        <template v-for="agent in catalog.activeAgents.slice(0, 3)" :key="agent.id">
          <Popover
            :open="agentHoverStates[agent.id]"
            @update:open="(open) => (agentHoverStates[agent.id] = open)"
          >
            <PopoverTrigger as-child>
              <Card
                class="rounded-md shadow px-5 py-2 flex flex-row gap-2 cursor-pointer hover:bg-primary/10 hover:border-primary-alpha-dark-80 hover:text-primary-alpha-dark-80 transition-colors"
                @mouseenter="agentHoverStates[agent.id] = true"
                @mouseleave="agentHoverStates[agent.id] = false"
                @click="handleAgentSelectionClick(agent)"
              >
                <i class="my-auto" :class="`${getAgentTypeIcon(agent, 16)}`"></i>
                <div>{{ agent.name }}</div>
              </Card>
            </PopoverTrigger>
            <PopoverContent
              class="w-80"
              side="top"
              @mouseenter="agentHoverStates[agent.id] = true"
              @mouseleave="agentHoverStates[agent.id] = false"
            >
              <div class="flex flex-col gap-2">
                <div class="flex items-center gap-2">
                  <i :class="`${getAgentTypeIcon(agent, 20)}`"></i>
                  <h4 class="font-semibold text-base">{{ agent.name }}</h4>
                </div>
                <p class="text-sm text-muted-foreground" v-if="agent.description">
                  {{ agent.description }}
                </p>
                <p class="text-sm text-muted-foreground italic" v-else>No description available</p>
              </div>
            </PopoverContent>
          </Popover>
        </template>
      </div>
      <div class="flex flex-row justify-end pt-2">
        <Button variant="ghost" @click="goTo('Dashboard')" class="font-semibold text-foreground">
          <i class="dku-icon-dashboard-16 text-primary my-auto"></i>
          My agents monitoring
          <i class="dku-icon-arrow-right-16 my-auto"></i>
        </Button>
        <Button variant="ghost" @click="goTo('AgentLibrary')" class="font-semibold text-foreground">
          <i class="dku-icon-square-card-view-16 text-primary my-auto"></i>
          Agent Library
          <i class="dku-icon-arrow-right-16 my-auto"></i>
        </Button>
      </div>
    </div>
  </div>
</template>

<style scoped>
/* Staggered animation for short examples */
.short-example-card {
  opacity: 0;
  transform: translateY(20px);
}

.short-example-card.animate-in {
  animation: fadeSlideIn 0.6s ease-out forwards;
}

@keyframes fadeSlideIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Staggered animation for agent examples with horizontal shift */
.agent-example-card {
  opacity: 0;
  transform: translateX(-20px);
}

.agent-example-card.animate-in {
  animation: fadeSlideInHorizontal 0.5s ease-out forwards;
}

@keyframes fadeSlideInHorizontal {
  from {
    opacity: 0;
    transform: translateX(-20px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}
</style>
