<script setup lang="ts">
import { computed, onMounted, onBeforeUnmount, ref } from 'vue'
import { useAdminConfigStore } from '@/store/adminConfigStore'
import type { AdminConfig, EnterpriseAgentItem } from '@/types/admin-config'
import { ExtractionMode, isFieldRequired } from '@/types/admin-config'
import { Button } from '@/components/ui/button'
import SystemConfigurationSection from '@/components/admin/SystemConfigurationSection.vue'
import EnterpriseAgentsSection from '@/components/admin/EnterpriseAgentsSection.vue'
import MyAgentsSection from '@/components/admin/MyAgentsSection.vue'
import PromptsLibraryAdminSection from '@/components/admin/PromptLibrary/PromptsLibrarySection.vue'
import ChartsSection from '@/components/admin/ChartsSection.vue'
import ConversationFilesSection from '@/components/admin/ConversationFilesSection.vue'
import UserExperienceSection from '@/components/admin/UserExperienceSection.vue'
import { onBeforeRouteLeave, useRoute } from 'vue-router'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import Badge from '@/components/ui/badge/Badge.vue'
import { Alert, AlertTitle, AlertDescription } from '@/components/ui/alert'
import { useSidebar } from '../ui/sidebar'

const store = useAdminConfigStore()
const route = useRoute()
const cfg = computed<AdminConfig | undefined>(() => store.draft as AdminConfig | undefined)
const { isTablet, isMobile, toggleSidebar } = useSidebar()

const activeSection = computed(() => (route.query.section as string) || 'system')
const sectionRefs = ref<Record<string, HTMLElement | null>>({})

const sections = [
  {
    id: 'system',
    label: 'Core Settings',
    icon: 'dku-icon-gear-16',
    description: 'Agent hub LLM configuration and system settings',
  },
  {
    id: 'enterprise-agents',
    label: 'Enterprise Agents',
    icon: 'dku-icon-briefcase-16',
    description:
      'Agents and Augmented LLMs can be made available as Enterprise Agents through Agent Hub',
  },
  {
    id: 'my-agents',
    label: 'My Agents',
    icon: 'dku-icon-user-16',
    description:
      'My Agents allows users to create their own agents with custom documents and tools.',
  },
  {
    id: 'prompts',
    label: 'Prompt Library',
    icon: 'dku-icon-file-text-16',
    description: 'Prompts users can reuse',
  },
  {
    id: 'charts',
    label: 'Charts Generation',
    icon: 'dku-icon-chart-16',
    description:
      'SQL Question Answering Agent Tool can provide tabular results. Agent Hub can generate charts from these results using the configured LLM.',
  },
  {
    id: 'conversation-files',
    label: 'Upload in Conversation',
    icon: 'dku-icon-file-upload-16',
    description: 'Manage "upload in conversation" capabilties',
  },
  {
    id: 'user-experience',
    label: 'User Experience',
    icon: 'dku-icon-project-blank-16',
    description: 'End-user interface settings',
  },
]

function isMissing(v?: string) {
  return !v || !v.trim()
}
function requireDescription(): boolean {
  return isFieldRequired(cfg.value, 'enterpriseAgentsDescription')
}
function agentTitle(it: EnterpriseAgentItem): string {
  const fallback = [it.projectKey, it.sourceAgentName].filter(Boolean).join(' _ ')
  return it.name?.trim() || fallback || '(unnamed)'
}

function myAgentsEnabled(): boolean {
  return !!cfg.value?.myAgentsEnabled
}
function requireMA_TextCompletionModels(): boolean {
  return isFieldRequired(cfg.value, 'myAgentsTextCompletionModels')
}
function requireMA_EmbeddingModel(): boolean {
  return isFieldRequired(cfg.value, 'myAgentsEmbeddingModel')
}
function requireMA_FileSystem(): boolean {
  return isFieldRequired(cfg.value, 'myAgentsFsConnection')
}
function requireMA_Folder(): boolean {
  return isFieldRequired(cfg.value, 'myAgentsFolder')
}
function requireMA_NumDocs(): boolean {
  return isFieldRequired(cfg.value, 'myAgentsNumDocs')
}
function chartsEnabled(): boolean {
  return cfg.value?.chartsGenerationMode !== 'disabled'
}
function requireCharts_MaxArtifactsSize(): boolean {
  return isFieldRequired(cfg.value, 'chartsMaxArtifactsSize')
}
function requireAgentHub_LLM(): boolean {
  return isFieldRequired(cfg.value, 'agentHubLLM')
}
function requireUploadManagedFolder(): boolean {
  return isFieldRequired(cfg.value, 'uploadManagedFolder')
}
function documentUploadEnabled(): boolean {
  return !!cfg.value?.enableDocumentUpload
}
function isExtractionModeScreenshots(): boolean {
  return cfg.value?.extractionMode === ExtractionMode.PagesScreenshots || !cfg.value?.extractionMode
}

interface ValidationError {
  section: string
  field: string
  message: string
  index?: number
}

const validationErrors = computed<ValidationError[]>(() => {
  const c = cfg.value
  if (!c) return []
  const errs: ValidationError[] = []

  if (requireDescription()) {
    c.enterpriseAgents?.forEach((it, idx) => {
      if (isMissing(it.description)) {
        errs.push({
          section: 'enterprise-agents',
          field: `description-${idx}`,
          message: `"${agentTitle(it)}": Description is required`,
          index: idx,
        })
      }
      if (it.allowInsightsCreation && isMissing(it.storiesWorkspace)) {
        errs.push({
          section: 'enterprise-agents',
          field: `workspace-${idx}`,
          message: `"${agentTitle(
            it
          )}": Workspace for stories is required when insights creation is enabled`,
          index: idx,
        })
      }
    })
  }

  if (myAgentsEnabled()) {
    if (
      requireMA_TextCompletionModels() &&
      (!c.myAgentsTextCompletionModels || c.myAgentsTextCompletionModels.length === 0)
    ) {
      errs.push({
        section: 'my-agents',
        field: 'textCompletionModels',
        message: 'At least one LLM is required',
      })
    }
    if (requireMA_EmbeddingModel() && isMissing(c.myAgentsEmbeddingModel)) {
      errs.push({
        section: 'my-agents',
        field: 'embeddingModel',
        message: 'Embedding Model is required',
      })
    }
    if (requireMA_FileSystem() && isMissing(c.myAgentsFsConnection)) {
      errs.push({
        section: 'my-agents',
        field: 'fsConnection',
        message: 'File System Connection is required',
      })
    }
    if (requireMA_Folder() && isMissing(c.myAgentsFolder)) {
      errs.push({
        section: 'my-agents',
        field: 'folder',
        message: 'Folder where My Agents will be created is required',
      })
    }
    const nd = c.myAgentsNumDocs
    if (
      requireMA_NumDocs() &&
      (nd === undefined || nd === null || isNaN(Number(nd)) || Number(nd) < 1)
    ) {
      errs.push({
        section: 'my-agents',
        field: 'numDocs',
        message: 'Number of documents to retrieve must be an integer ≥ 1',
      })
    }
  }

  if (chartsEnabled()) {
    const maxSize = c.chartsMaxArtifactsSize
    if (
      requireCharts_MaxArtifactsSize() &&
      (maxSize === undefined || maxSize === null || isNaN(Number(maxSize)) || Number(maxSize) < 1)
    ) {
      errs.push({
        section: 'charts',
        field: 'maxArtifactsSize',
        message: 'Max Artifacts Size must be an integer ≥ 1',
      })
    }
  }

  if (requireAgentHub_LLM() && isMissing(c.agentHubLLM)) {
    errs.push({ section: 'system', field: 'agentHubLLM', message: 'Agent Hub LLM is required' })
  }

  if (documentUploadEnabled() && requireUploadManagedFolder() && isMissing(c.uploadManagedFolder)) {
    errs.push({
      section: 'conversation-files',
      field: 'uploadManagedFolder',
      message: 'Upload Managed Folder is required',
    })
  }

  if (documentUploadEnabled() && isExtractionModeScreenshots()) {
    const maxImages = c.maxImagesInConversation
    if (
      maxImages === undefined ||
      maxImages === null ||
      isNaN(Number(maxImages)) ||
      Number(maxImages) < 1
    ) {
      errs.push({
        section: 'conversation-files',
        field: 'maxImagesInConversation',
        message: 'Max Images in Conversation must be an integer ≥ 1',
      })
    }
  }

  return errs
})

const currentSectionErrors = computed<ValidationError[]>(() => {
  return validationErrors.value.filter((err) => err.section === activeSection.value)
})

const groupedCurrentErrors = computed(() => {
  const grouped: Record<string, ValidationError[]> = {}

  currentSectionErrors.value.forEach((error) => {
    const match = error.message.match(/^"([^"]+)":\s*(.+)$/)
    if (match) {
      const entityName = match[1]
      let fieldMessage = match[2]
      fieldMessage = fieldMessage.replace(/\s*is required$/i, '').trim()
      fieldMessage = fieldMessage.charAt(0).toUpperCase() + fieldMessage.slice(1)
      if (!grouped[entityName]) grouped[entityName] = []
      grouped[entityName].push({ ...error, message: fieldMessage })
    } else {
      if (!grouped['General']) grouped['General'] = []
      let cleanMessage = error.message.replace(/\s*is required$/i, '').trim()
      cleanMessage = cleanMessage.charAt(0).toUpperCase() + cleanMessage.slice(1)
      grouped['General'].push({ ...error, message: cleanMessage })
    }
  })

  return grouped
})

const canSave = computed(() => !!store.loaded && !!store.dirty && !store.saving)

const isActiveSectionDirty = computed(() => store.isSectionDirty(activeSection.value))

function goToError(error: ValidationError, event?: Event) {
  // Don't close the alert
  event?.stopPropagation()

  const targetId = `field-${error.field}`
  const targetEl = document.getElementById(targetId)

  // Check if field is already visible (agent already expanded)
  const isFieldVisible = targetEl && targetEl.offsetParent !== null
  const isHiddenEnterpriseAgentError =
    error.section === 'enterprise-agents' && error.index !== undefined && !isFieldVisible

  // Only expand if it's an enterprise agent error and field is not visible
  if (isHiddenEnterpriseAgentError) {
    window.dispatchEvent(
      new CustomEvent('expand-enterprise-agent', { detail: { index: error.index } })
    )
  }

  // Wait for expansion to complete if needed, then scroll and focus
  setTimeout(
    () => {
      const element = document.getElementById(targetId)
      if (!element) return

      // Scroll directly to the element
      element.scrollIntoView({ behavior: 'smooth', block: 'center' })

      // Focus the element if it's an input/textarea, or click if it's a select
      if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
        setTimeout(() => element.focus(), 100)
      } else if (element.getAttribute('role') === 'combobox') {
        setTimeout(() => element.click(), 100)
      } else {
        // Fallback: find input inside container
        const inputEl = element.querySelector('textarea, input, [role="combobox"]') as HTMLElement
        if (inputEl) {
          setTimeout(() => {
            inputEl.focus()
            if (inputEl.getAttribute('role') === 'combobox') {
              inputEl.click()
            }
          }, 100)
        }
      }
    },
    isHiddenEnterpriseAgentError ? 300 : 0
  )
}

function onSave() {
  if (canSave.value) store.save()
}
function onDiscard() {
  store.discard()
}
onBeforeRouteLeave((_to, _from, next) => {
  if (!store.dirty) return next()
  const ok = window.confirm('You have unsaved changes. Leave this page?')
  next(ok)
})

function handleBeforeUnload(e: BeforeUnloadEvent) {
  if (store.dirty) e.preventDefault()
}
function setSectionRef(sectionId: string, el: any) {
  if (el) sectionRefs.value[sectionId] = el
}

onMounted(() => {
  if (!store.loaded) store.load()
  window.addEventListener('beforeunload', handleBeforeUnload)
})

onBeforeUnmount(() => {
  window.removeEventListener('beforeunload', handleBeforeUnload)
})
</script>

<template>
  <div class="h-full flex flex-col min-w-0">
    <div class="flex items-center px-2 sm:px-6 border-b border-border h-[57px] w-full">
      <Tooltip v-if="isMobile">
        <TooltipTrigger asChild>
          <Button variant="ghost" size="sm" @click="toggleSidebar" class="admin-go-home-btn">
            <i class="dku-icon-chevron-left-16"></i>
            <span> Back </span>
          </Button>
        </TooltipTrigger>
        <TooltipContent hide-arrow>Open the sidebar</TooltipContent>
      </Tooltip>

      <div class="flex items-center gap-3 ml-auto">
        <Badge v-if="store.dirty" class="bg-[#F4ECE7] text-warning border-warning/20">
          <i class="dku-icon-history-16 mr-1"></i>Unsaved changes
        </Badge>

        <Button
          variant="outline"
          @click="onDiscard"
          :disabled="!store.dirty || store.saving"
          class="admin-btn admin-btn--secondary h-10"
        >
          <i class="dku-icon-arrow-undo-16" :class="{ 'mr-1': !(isTablet || isMobile) }"></i>
          {{ isTablet || isMobile ? '' : 'Discard' }}
        </Button>

        <Button :disabled="!canSave" @click="onSave" class="admin-btn admin-btn--primary h-10">
          <i class="dku-icon-save-16" :class="{ 'mr-1': !(isTablet || isMobile) }"></i>
          {{ isTablet || isMobile ? '' : !canSave ? 'Saved' : 'Save' }}
        </Button>
      </div>
    </div>

    <div class="flex-1 overflow-y-auto">
      <div class="w-full px-6 py-6">
        <template v-for="section in sections" :key="section.id">
          <div
            v-if="activeSection === section.id"
            :class="
              section.id === 'prompts' ? 'mb-4 max-w-[1600px] mx-auto' : 'mb-6 max-w-5xl mx-auto'
            "
          >
            <div class="flex items-center gap-2">
              <h2
                class="text-xl font-semibold text-primary-alpha-dark-70 flex items-center gap-2 admin-section-title"
              >
                <i :class="section.icon"></i>{{ section.label }}
              </h2>
              <Badge
                v-if="isActiveSectionDirty"
                class="bg-[#F4ECE7] text-warning border-warning/20"
              >
                <i class="dku-icon-history-16 mr-1"></i>Unsaved changes
              </Badge>
            </div>
            <p class="text-sm text-muted-foreground mt-1">{{ section.description }}</p>
          </div>
        </template>

        <div :class="activeSection === 'prompts' ? '' : 'max-w-5xl mx-auto'">
          <Alert
            v-if="currentSectionErrors.length"
            default-collapsed
            collapsible
            class="mb-6 admin-alert admin-alert--warning"
          >
            <i class="dku-icon-warning-16"></i>
            <AlertTitle class="admin-alert-title">
              {{ currentSectionErrors.length }}
              {{
                currentSectionErrors.length === 1
                  ? 'required field to complete'
                  : 'required fields to complete'
              }}
            </AlertTitle>
            <AlertDescription class="admin-alert-description">
              <p class="text-sm mb-3">
                Please complete the following required fields before saving:
              </p>

              <div class="space-y-3">
                <div v-for="(errors, entityName) in groupedCurrentErrors" :key="entityName">
                  <div v-if="entityName !== 'General'" class="font-semibold text-sm mb-1">
                    {{ entityName }}
                  </div>
                  <ul class="space-y-1 list-none" :class="entityName !== 'General' ? 'ml-4' : ''">
                    <li v-for="(error, i) in errors" :key="i" class="text-sm">
                      <button @click.stop="goToError(error, $event)" class="text-left underline">
                        {{ error.message }}
                      </button>
                    </li>
                  </ul>
                </div>
              </div>
            </AlertDescription>
          </Alert>

          <div>
            <div v-show="activeSection === 'system'" :ref="(el) => setSectionRef('system', el)">
              <SystemConfigurationSection />
            </div>
            <div
              v-show="activeSection === 'enterprise-agents'"
              :ref="(el) => setSectionRef('enterprise-agents', el)"
            >
              <EnterpriseAgentsSection />
            </div>
            <div
              v-show="activeSection === 'my-agents'"
              :ref="(el) => setSectionRef('my-agents', el)"
            >
              <MyAgentsSection />
            </div>
            <div v-show="activeSection === 'prompts'" :ref="(el) => setSectionRef('prompts', el)">
              <PromptsLibraryAdminSection />
            </div>
            <div v-show="activeSection === 'charts'" :ref="(el) => setSectionRef('charts', el)">
              <ChartsSection />
            </div>
            <div
              v-show="activeSection === 'conversation-files'"
              :ref="(el) => setSectionRef('conversation-files', el)"
            >
              <ConversationFilesSection />
            </div>
            <div
              v-show="activeSection === 'user-experience'"
              :ref="(el) => setSectionRef('user-experience', el)"
            >
              <UserExperienceSection />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
