<template>
  <div class="bg-white flex flex-col h-full overflow-hidden">
    <div class="px-6 space-y-4 pb-6">
      <div class="space-y-4 flex-shrink-0 pb-1 bg-white transition-shadow">
        <div class="flex justify-between mt-3 mb-2">
          <!-- Agent name with inline editing -->
          <div class="flex items-center mr-2.5">
            <!-- Display mode -->
            <template v-if="!isEditingName">
              <div class="font-semibold text-foreground text-2xl">
                {{ local.name }}
              </div>
              <div v-if="detailsLoading" class="ml-2">
                <Loader2 class="w-4 h-4 animate-spin" />
              </div>
              <Tooltip v-else>
                <TooltipTrigger asChild>
                  <button
                    @click="startEditingName"
                    class="ml-2 p-1 hover:bg-primary-alpha-light-30 text-foreground rounded transition-colors"
                    :disabled="detailsLoading"
                  >
                    <i class="dku-icon-edit-20"></i>
                  </button>
                </TooltipTrigger>
                <TooltipContent hideArrow>Edit name</TooltipContent>
              </Tooltip>
            </template>

            <!-- Edit mode -->
            <template v-else>
              <div
                class="inline-block rounded-md border border-border focus-within:border-primary transition-colors"
              >
                <input
                  ref="nameInputRef"
                  v-model="nameDraft"
                  name="agent-name"
                  :disabled="detailsLoading"
                  placeholder="Name your agent"
                  class="text-base leading-normal px-3 py-1.5 focus:outline-none transition-colors w-auto"
                  @blur="stopEditingName"
                  @keydown.enter="stopEditingName"
                  @keydown.escape="cancelEditingName"
                />
              </div>
            </template>
          </div>

          <div class="flex items-center gap-2">
            <Tooltip>
              <TooltipTrigger asChild>
                <Button
                  v-if="hasPublishedVersion"
                  variant="outline"
                  size="sm"
                  class="hover:text-primary-hover text-sm px-4"
                  :disabled="isPublishing || !canDiscardChanges"
                  @click="showDiscardDialog = true"
                >
                  <i class="dku-icon-arrow-undo-16"></i>
                </Button>
              </TooltipTrigger>
              <TooltipContent hideArrow>Discard changes</TooltipContent>
            </Tooltip>

            <Tooltip v-if="showMagicWand">
              <TooltipTrigger asChild>
                <span class="inline-flex">
                  <Button
                    variant="outline"
                    size="sm"
                    class="hover:text-primary-hover text-sm px-4"
                    :disabled="magicWandDisabledMode || detailsLoading"
                    @click="generateAgentConfig"
                  >
                    <i class="dku-icon-magic-wand-16"></i>
                    <span class="ml-2">Auto-fill</span>
                  </Button>
                </span>
              </TooltipTrigger>
              <TooltipContent hideArrow class="p-2">
                <template v-if="magicWandDisabledMode">
                  Fill agent instructions to unlock auto-fill
                </template>
                <template v-else>
                  Agent Hub will fill missing details based on provided Agent instructions<br />
                  Review and adjust as needed
                </template>
              </TooltipContent>
            </Tooltip>
          </div>
        </div>
        <div class="flex justify-start mb-2">
          <!-- Status badges -->
          <div class="flex items-center gap-1">
            <Badge v-if="canDiscardChanges" class="bg-[#F4ECE7] text-warning">
              <i class="dku-icon-history-16"></i>Unpublished changes
            </Badge>
            <Badge v-else-if="hasPublishedVersion" class="text-[#0B590B] bg-[#E7EEE7]">
              <i class="dku-icon-publish-16"></i>
              Live version
            </Badge>
            <Badge v-else class="bg-muted text-muted-foreground">
              <i class="dku-icon-custom-page-16"></i>
              Draft
            </Badge>
            <Badge v-if="isSaving" class="text-foreground bg-white">
              <i class="dku-icon-arrow-circular-16 animate-spin mr-1"></i>Saving…
            </Badge>
            <Badge v-if="saveFailed && !isSaving" class="text-foreground bg-white">
              <i class="dku-icon-dismiss-16 mr-1 text-red-600"></i> Save failed
            </Badge>
            <Badge
              v-if="!isSaving && !agentStore.noProjectCreated && !saveFailed"
              class="text-foreground bg-white"
            >
              <i class="dku-icon-checkmark-16 mr-1 text-[#0B590B]"></i>Saved
            </Badge>
            <Button
              variant="outline"
              size="sm"
              class="flex align-center"
              @click="forceSave"
              :disabled="isSaving"
              v-if="saveFailed"
            >
              <i class="dku-icon-arrow-clockwise-16"></i>
              <span class="ml-1">Retry</span></Button
            >
          </div>
        </div>
      </div>
      <div class="px-0 -mb-6">
        <div
          class="w-full border-b transition-colors"
          :class="headerHasBorder ? 'border-border' : 'border-transparent'"
        />
      </div>
    </div>

    <!-- Agent Prompt -->
    <div
      ref="scroller"
      class="px-6 space-y-5 flex-1 overflow-y-auto overflow-x-hidden mb-10"
      @scroll.passive="onScroll"
    >
      <div class="mb-2">
        <div class="flex items-center gap-1 mb-1">
          <Label class="text-foreground flex-inline gap-0"
            >Agent instructions <span class="text-red-600">*</span></Label
          >
          <Loader2 class="w-4 h-4 animate-spin mr-2" v-if="false && detailsLoading" />
        </div>
        <Alert variant="info" class="mb-2 py-2 px-2" collapsible defaultCollapsed>
          <i class="dku-icon-info-circle-outline-16"></i>
          <AlertTitle>Defines Agent's personality, role, and behavior</AlertTitle>
          <AlertDescription>
            These instructions ("prompt") are sent with every request to guide agent response.
            <br />
            Example: You are a helpful customer service agent specializing in technical support.
          </AlertDescription>
        </Alert>
        <Textarea
          ref="systemPromptTextarea"
          v-model="local.systemPrompt"
          :disabled="detailsLoading"
          rows="5"
          placeholder="Agent instructions"
          v-autogrow="local.systemPrompt"
          class="w-full !border !border-border rounded-md shadow-sm text-sm py-2 px-3 placeholder-muted-foreground min-h-[120px] lg:min-h-[220px] resize-none overflow-hidden overscroll-contain"
        ></Textarea>
      </div>

      <div class="flex mb-5 justify-end" v-if="prefs.uiConf?.enable_prompt_library">
        <Button size="sm" variant="ghost" @click.stop="openLlmAdvancedMode">
          <i class="dku-icon-text-box-16 mr-1 text-primary"></i>
          <span>Access ready-made prompts</span>
          <i class="dku-icon-chevron-right-16"></i>
        </Button>
      </div>

      <!-- Model (Base LLM) -->
      <div>
        <div class="flex items-center gap-1 mb-1">
          <Label class="flex-inline">Base model (LLM)</Label>
          <Tooltip>
            <TooltipTrigger asChild>
              <i class="dku-icon-info-circle-outline-16 text-base-foreground"></i>
            </TooltipTrigger>
            <TooltipContent hideArrow>
              <p>The language model that powers your agent.</p>
              <p>Different models have different capabilities and costs.</p>
            </TooltipContent>
          </Tooltip>
        </div>
        <LlmSelector
          custom-class="w-full lg:w-[256px] data-[size=default]:h-[42px]"
          :model-value="llmConfig.llmid"
          @update:model-value="updateLLMId"
        />
      </div>

      <!-- Model (Embedding LLM) HIDDEN -->
      <div v-if="false">
        <div class="flex items-center gap-2 mb-1">
          <Label class="font-medium">Select an embedding model</Label>
          <Tooltip>
            <TooltipTrigger asChild>
              <i class="dku-icon-info-circle-outline-16 text-base-foreground"></i>
            </TooltipTrigger>
            <TooltipContent hideArrow>
              <p class="max-w-xs">
                Choose the embedding model your agent will use to build its knowledge bank. This
                helps it find and answer document-related questions more effectively. Different
                models vary in quality, speed, and cost
              </p>
            </TooltipContent>
          </Tooltip>
        </div>
        <EmbeddingSelector custom-class="w-full lg:w-[256px]" v-model="llmConfig.embeddingLlmId" />
      </div>
      <Accordion type="multiple" collapsible v-model="expandedItems">
        <AccordionItem value="capabilities">
          <AccordionTrigger>
            <h4 class="text-xl font-semibold text-foreground group-hover:underline">
              Agent Capabilities
            </h4>
            <template #icon>
              <i
                class="dku-icon-chevron-down-16 text-muted-foreground pointer-events-none text-xl shrink-0 translate-y-0.5 transition-transform duration-200"
              />
            </template>
          </AccordionTrigger>
          <AccordionContent class="pb-0">
            <!-- Accordion for grouped sections with improved styling -->
            <Accordion
              type="multiple"
              :defaultValue="['llm', 'documents', 'tools', 'overview', 'capabilities']"
              v-model="expandedItems"
              class="space-y-5"
            >
              <!--<Alert
                variant="info"
                class="mb-3 py-2 px-2"
                defaultCollapsed
                collapsible
                v-if="!props.draft.project_key"
              >
                <i class="dku-icon-info-circle-outline-16"></i>
                <AlertTitle>Save the agent to be able to add documents and tools</AlertTitle>
                <AlertDescription>
                  You need to click on `Save Agent` before adding documents or tools. This ensures
                  that all configurations are properly linked to the agent.
                </AlertDescription>  
              </Alert> -->
              <!-- Documents Configuration -->
              <DocumentsConfig
                v-model="documentsConfig"
                :agent-id="local.id"
                :agent-name="local.name"
                :documents="props.draft.documents"
                :disabled="!props.draft.project_key"
                :indexing="props.draft.indexing"
              />

              <!-- Tools Configuration -->
              <ToolsConfig
                v-model="toolsConfig"
                :agent-name="local.name"
                :disabled="!props.draft.project_key"
              />
            </Accordion>
          </AccordionContent>
        </AccordionItem>
      </Accordion>
      <Accordion type="multiple" collapsible v-model="expandedItems">
        <AccordionItem value="overview">
          <AccordionTrigger>
            <h4 class="text-xl font-semibold text-foreground group-hover:underline">
              Agent Overview
            </h4>
            <template #icon>
              <i
                class="dku-icon-chevron-down-16 text-muted-foreground pointer-events-none text-xl shrink-0 translate-y-0.5 transition-transform duration-200"
              />
            </template>
          </AccordionTrigger>
          <AccordionContent>
            <div>
              <div class="flex items-center gap-1 mb-1">
                <div class="flex items-center justify-between w-full">
                  <div class="flex items-center gap-1">
                    <Label class="text-foreground flex-inline gap-0">
                      Describe your agent and its capabilities<span class="text-destructive"
                        >*</span
                      >
                    </Label>

                    <Loader2 class="w-4 h-4 animate-spin mr-2" v-if="detailsLoading" />
                  </div>
                </div>
              </div>
              <Alert variant="info">
                <i class="dku-icon-info-circle-outline-16"></i>
                <AlertTitle
                  >This description helps understand what the agent does. It also guides the LLM in
                  selecting the appropriate agent when multiple agents are selected.</AlertTitle
                >
              </Alert>
              <Textarea
                v-model="local.description"
                :disabled="detailsLoading"
                rows="5"
                placeholder="Your agent description"
                class="w-full !border !border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 text-sm py-2 px-3 resize-y placeholder-gray-400 placeholder-opacity-50 min-h-[120px] mt-1 mb-5"
              />
            </div>

            <!-- Example Questions Section -->
            <ExampleQuestionsConfig v-model="exampleQuestionsConfig" :loading="detailsLoading" />
          </AccordionContent>
        </AccordionItem>
      </Accordion>

      <div class="flex flex-row justify-end" :class="areRequiredFieldsFilled ? 'hidden' : ''">
        <div class="text-sm flex">
          <p class="text-red-600 pr-1">*</p>
          fields marked with an asterisk are mandatory for publishing
        </div>
      </div>
    </div>

    <LlmAdvancedMode
      v-if="showLlmAdvancedMode"
      :agent-name="local.name"
      :llmid="local.llmid"
      :system-prompt="local.systemPrompt"
      :embedding-llm-id="local.embeddingLlmId"
      @update:llmid="(id: string) => (local.llmid = id)"
      @update:system-prompt="(prompt: string) => (local.systemPrompt = prompt)"
      @update:embedding-llm-id="(id: string) => (local.embeddingLlmId = id)"
      @close="showLlmAdvancedMode = false"
      @use="(prompt: string) => (local.systemPrompt = prompt)"
    />
    <!-- Discard Changes Dialog -->
    <AlertDialog v-model:open="showDiscardDialog">
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>Discard Changes</AlertDialogTitle>
          <AlertDialogDescription>
            This will revert all changes back to the last published version. Any modifications
            you've made will be lost.
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>Cancel</AlertDialogCancel>
          <AlertDialogAction @click="onDiscardChanges"> Discard Changes </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  </div>
</template>

<script setup lang="ts">
import { reactive, watch, onMounted, ref, computed, nextTick } from 'vue'

import { Textarea } from '@/components/ui/textarea'
import { Label } from '@/components/ui/label'
import { Accordion } from '@/components/ui/accordion'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import DocumentsConfig from './AgentConfiguration/DocumentsConfig.vue'
import ToolsConfig from './AgentConfiguration/ToolsConfig.vue'
import ExampleQuestionsConfig from './AgentConfiguration/ExampleQuestionsConfig.vue'
import { usePrefStore } from '@/store/prefStore'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import LlmSelector from '@/components/LlmSelector.vue'
import EmbeddingSelector from '@/components/EmbeddingSelector.vue'
import { Button } from './ui/button'
import LlmAdvancedMode from './AgentConfiguration/LanguageModel/LlmAdvancedMode.vue'
import { isEqual } from 'lodash'
import { useAgentStore } from '@/store/agentStore'
import { useAgentCatalogStore } from '@/store/agentCatalogStore'
import { Loader2 } from 'lucide-vue-next'
import AccordionItem from './ui/accordion/AccordionItem.vue'
import AccordionTrigger from './ui/accordion/AccordionTrigger.vue'
import AccordionContent from './ui/accordion/AccordionContent.vue'
import {
  AlertDialog,
  AlertDialogContent,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogCancel,
  AlertDialogAction,
} from '@/components/ui/alert-dialog'
import { toast } from 'vue-sonner'
import { API } from '@/Api'
import Badge from './ui/badge/Badge.vue'
import { DEFAULT_AGENT_NAME } from '@/constants/conversation'
import { WT1iser } from '@/lib/wt1'

type TA = HTMLTextAreaElement

function resize(el: TA) {
  const min = parseFloat(getComputedStyle(el).minHeight || '0') || 0
  el.style.height = 'auto'
  const target = Math.max(el.scrollHeight, min)
  el.style.height = target + 'px'
}
function forceSave() {
  agentStore.doSave(true)
}
const vAutogrow = {
  mounted(el: TA) {
    el.style.overflow = 'hidden'
    const onInput = () => resize(el)
    ;(el as any)._autogrowOnInput = onInput
    el.addEventListener('input', onInput)
    requestAnimationFrame(() => resize(el))
  },
  updated(el: TA) {
    requestAnimationFrame(() => resize(el))
  },
  beforeUnmount(el: TA) {
    const onInput = (el as any)._autogrowOnInput
    if (onInput) el.removeEventListener('input', onInput)
  },
}

const scroller = ref<HTMLDivElement | null>(null)
const headerHasBorder = ref(false)

function onScroll(e: Event) {
  const el = e.target as HTMLElement
  headerHasBorder.value = el.scrollTop > 0
}

/** Props / Emit **/
const props = defineProps<{
  draft: {
    id: string
    name: string
    description: string
    systemPrompt: string
    kbDescription: string
    tools: string[]
    llmid: string
    embeddingLlmId: string
    documents?: any[]
    indexing?: { status: string }
    sample_questions?: string[]
    project_key?: string
    published_version?: any
  }
  isPublishing?: boolean
}>()

// Constants

const prefs = usePrefStore()
const catalogStore = useAgentCatalogStore()
const agentStore = useAgentStore()

const emit = defineEmits<{
  (e: 'updateDraft', payload: Partial<typeof props.draft>): void
  (e: 'discardChanges'): void
}>()

/** Local state **/
const local = reactive({
  id: '',
  name: '',
  description: '',
  systemPrompt: '',
  kbDescription: '',
  tools: [] as string[],
  llmid: '',
  embeddingLlmId: '',
  sample_questions: [] as string[],
})

// UI State
const expandedItems = ref<string[]>(['overview', 'capabilities'])
const showLlmAdvancedMode = ref(false)
const showDiscardDialog = ref(false)
const systemPromptTextarea = ref<HTMLTextAreaElement>()

const nameInputRef = ref<HTMLInputElement>()
const isEditingName = ref(false)
const nameDraft = ref('')
const nameClearedByUser = ref(false)

function startEditingName() {
  isEditingName.value = true
  nameDraft.value = local.name || ''
  WT1iser.editAgent()
  nextTick(() => {
    nameInputRef.value?.focus()
    nameInputRef.value?.select()
  })
}

function stopEditingName() {
  isEditingName.value = false
  const trimmed = nameDraft.value.trim()
  if (trimmed === '') {
    nameClearedByUser.value = true
    local.name = ''
  } else {
    nameClearedByUser.value = false
    local.name = trimmed
  }
}

function cancelEditingName() {
  isEditingName.value = false
}

const showMagicWand = computed(() => prefs.uiConf?.enable_app_smart_mode)
const magicWandDisabledMode = computed(
  () => showMagicWand && props.draft.systemPrompt?.trim().length == 0
)

// Discard changes functionality
const hasPublishedVersion = computed(() => !!props.draft.published_version)
const canDiscardChanges = computed(
  () => hasPublishedVersion.value && agentStore.hasUnsavedChanges()
)
const isSaving = computed(() => agentStore.isSaving)
const saveFailed = computed(() => agentStore.saveFailed)
// Configuration objects for child components
const llmConfig = computed({
  get: () => ({
    llmid: local.llmid,
    systemPrompt: local.systemPrompt,
    embeddingLlmId: local.embeddingLlmId,
  }),
  set: (value) => {
    local.llmid = value.llmid
    local.systemPrompt = value.systemPrompt
    local.embeddingLlmId = value.embeddingLlmId
  },
})

function openLlmAdvancedMode() {
  WT1iser.viewPromptLibrary()
  showLlmAdvancedMode.value = true
}

const documentsConfig = computed({
  get: () => ({
    kbDescription: local.kbDescription,
  }),
  set: (value) => {
    local.kbDescription = value.kbDescription
  },
})

const toolsConfig = computed({
  get: () => ({
    tools: local.tools,
  }),
  set: (value) => {
    local.tools = value.tools
  },
})
const updateLLMId = (id: string) => {
  local.llmid = id
}
const exampleQuestionsConfig = computed({
  get: () => ({
    sample_questions: local.sample_questions || [],
  }),
  set: (value) => {
    local.sample_questions = value.sample_questions
    // Trigger the updateDraft emit to sync with parent
    emit('updateDraft', {
      ...props.draft,
      sample_questions: value.sample_questions,
    })
  },
})

const areRequiredFieldsFilled = computed(
  () => props.draft.description.trim() && props.draft.systemPrompt.trim()
)

const detailsLoading = ref(false)
async function generateAgentConfig() {
  WT1iser.autoFillAgent(local.name, local.description, local.sample_questions)
  // Call the store action to generate agent config
  detailsLoading.value = true
  try {
    await agentStore.generateAgentConfig()
    local.sample_questions = agentStore.draft.sample_questions || local.sample_questions
    local.description = agentStore.draft.description || local.description
    // local.systemPrompt = agentStore.draft.systemPrompt || local.systemPrompt
    // Auto-fill should consider 'New Agent' as empty value and override it
    if (!local.name || local.name === DEFAULT_AGENT_NAME) {
      local.name = agentStore.draft.name || local.name
    }
  } finally {
    detailsLoading.value = false
  }
}

async function onDiscardChanges() {
  showDiscardDialog.value = false

  if (!props.draft.published_version) return

  try {
    const loadingToast = toast.loading('Discarding changes…')
    WT1iser.discardAgentChanges()
    await catalogStore.updateAgent({ id: props.draft.id, hasUnpublishedChanges: false })

    // Single API call handles everything server-side
    await API.discardAgentChanges(props.draft.id)

    // Emit event to parent to reload agent from server
    emit('discardChanges')

    toast.dismiss(loadingToast)
    toast.success('All changes discarded successfully')
  } catch (err: any) {
    toast.error(err?.response?.data?.error || 'Failed to discard changes')
  }
}
function hydrate(d: typeof props.draft) {
  local.id = d.id
  local.name = d.name || DEFAULT_AGENT_NAME
  local.description = d.description
  local.systemPrompt = d.systemPrompt
  local.kbDescription = d.kbDescription
  local.tools = [...(d.tools || [])]
  local.llmid = d.llmid || prefs.baseLlmid
  local.embeddingLlmId = d.embeddingLlmId || prefs.baseEmbeddingLlmId
  local.sample_questions = [...(d.sample_questions || [])]
  // local.short_example_queries = [...(d.short_example_queries || [])]
}
hydrate(props.draft)
watch(() => props.draft, hydrate, { deep: true })
let prevDraft: any = null
watch(
  () => ({
    name: local.name,
    description: local.description,
    systemPrompt: local.systemPrompt,
    kbDescription: local.kbDescription,
    tools: [...local.tools],
    llmid: local.llmid,
    embeddingLlmId: local.embeddingLlmId,
  }),
  (newDraft: any) => {
    if (!isEqual(newDraft, prevDraft)) {
      emit('updateDraft', newDraft)
      prevDraft = newDraft
    }
  },
  { deep: true }
)

onMounted(() => {
  if (scroller.value) headerHasBorder.value = scroller.value.scrollTop > 0
  // Focus the system prompt textarea when the component mounts
  if (systemPromptTextarea.value) {
    systemPromptTextarea.value.focus()
  }
})
</script>

<style scoped>
/* Override the accordion's default last:border-b-0 to preserve rounded borders */
:deep(.border.rounded-lg[data-slot='accordion-item']:last-child) {
  border-bottom-width: 1px !important;
}
</style>
