<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import { useAdminConfigStore } from '@/store/adminConfigStore'
import type { AdminConfig, TextCompletionModel } from '@/types/admin-config'
import { API } from '@/Api'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Separator } from '@/components/ui/separator'
import { Switch } from '@/components/ui/switch'
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
} from '@/components/ui/select'
import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
} from '@/components/ui/dropdown-menu'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import AdminToolCard from '@/components/admin/AdminToolCard.vue'

const store = useAdminConfigStore()

type LLMOption = { id: string; name: string; type: string }
const availableTextModels = ref<LLMOption[]>([])
const availableEmbeddingModels = ref<LLMOption[]>([])
const loading = ref(false)
const modelsFilter = ref('')

const fileSystemConnections = ref<Array<{ id: string; label: string; type: string }>>([])
const folders = ref<
  Array<{ id: string; name: string; path: string; level: number; hasChildren: boolean }>
>([])
const managedTools = ref<Array<{ id: string; name: string; description: string; type: string }>>([])

function updateDraft(mutator: (cfg: AdminConfig) => void) {
  if (!store.draft) return
  const next = JSON.parse(JSON.stringify(store.draft)) as AdminConfig
  mutator(next)
  store.draft = next
}

const myAgentsEnabled = computed({
  get: () => !!store.draft?.myAgentsEnabled,
  set: (v: boolean) => {
    updateDraft((cfg) => {
      cfg.myAgentsEnabled = v
    })
  },
})

const textCompletionModels = computed({
  get: () => store.draft?.myAgentsTextCompletionModels ?? [],
  set: (models: TextCompletionModel[]) => {
    updateDraft((cfg) => {
      cfg.myAgentsTextCompletionModels = [...models]
    })
  },
})

const embeddingModel = computed({
  get: () => store.draft?.myAgentsEmbeddingModel ?? '',
  set: (v: string) => {
    updateDraft((cfg) => {
      cfg.myAgentsEmbeddingModel = v || undefined
    })
  },
})

const fsConnection = computed({
  get: () => store.draft?.myAgentsFsConnection ?? '',
  set: (v: string) => {
    updateDraft((cfg) => {
      cfg.myAgentsFsConnection = v || undefined
    })
  },
})

const folder = computed({
  get: () => store.draft?.myAgentsFolder ?? '',
  set: (v: string) => {
    updateDraft((cfg) => {
      cfg.myAgentsFolder = v || undefined
    })
  },
})

const numDocs = computed({
  get: () =>
    store.draft?.myAgentsNumDocs !== undefined ? String(store.draft.myAgentsNumDocs) : '',
  set: (v: string) => {
    const num = Number.parseInt(v || '0', 10)
    updateDraft((cfg) => {
      cfg.myAgentsNumDocs = Number.isFinite(num) && num >= 1 ? num : undefined
    })
  },
})

const selectedTools = computed({
  get: () => store.draft?.myAgentsManagedTools ?? [],
  set: (v: string[]) => {
    updateDraft((cfg) => {
      cfg.myAgentsManagedTools = [...v]
    })
  },
})

const enablePromptLibrary = computed({
  get: () => !!store.draft?.myAgentsEnablePromptLibrary,
  set: (v: boolean) => {
    updateDraft((cfg) => {
      cfg.myAgentsEnablePromptLibrary = v
    })
  },
})

const enableGroupsRestriction = computed({
  get: () => !!store.draft?.myAgentsEnableGroupsRestriction,
  set: (v: boolean) => {
    updateDraft((cfg) => {
      cfg.myAgentsEnableGroupsRestriction = v
    })
  },
})

const excludedShareGroups = ref<string[]>([])
const availableGroups = ref<Array<{ principal: string; displayName: string; type: string }>>([])
const groupsFilter = ref('')
const loadingGroups = ref(false)

// Initialize excludedShareGroups from store
if (store.draft?.myAgentsExcludedShareGroups) {
  excludedShareGroups.value = [...store.draft.myAgentsExcludedShareGroups]
}

// Watch for store changes to keep local state in sync
watch(
  () => store.draft?.myAgentsExcludedShareGroups,
  (newGroups) => {
    if (newGroups) {
      excludedShareGroups.value = [...newGroups]
    } else {
      excludedShareGroups.value = []
    }
  }
)

const embeddingModelsByType = computed(() => {
  const grouped: Record<string, LLMOption[]> = {}
  availableEmbeddingModels.value.forEach((model) => {
    if (!grouped[model.type]) {
      grouped[model.type] = []
    }
    grouped[model.type].push(model)
  })
  return grouped
})

const selectedModelIds = computed(() => {
  return new Set(textCompletionModels.value.map((m) => m.id))
})

const filteredModels = computed(() => {
  const query = modelsFilter.value.toLowerCase().trim()
  if (!query) return availableTextModels.value

  return availableTextModels.value.filter((model) => {
    const name = model.name.toLowerCase()
    const id = model.id.toLowerCase()
    return name.includes(query) || id.includes(query)
  })
})

const filteredModelsByType = computed(() => {
  const grouped: Record<string, LLMOption[]> = {}
  filteredModels.value.forEach((model) => {
    if (!grouped[model.type]) {
      grouped[model.type] = []
    }
    grouped[model.type].push(model)
  })
  return grouped
})

function toggleTextCompletionModel(modelId: string) {
  const model = availableTextModels.value.find((m) => m.id === modelId)
  if (!model) return

  if (textCompletionModels.value.some((m) => m.id === modelId)) {
    textCompletionModels.value = textCompletionModels.value.filter((m) => m.id !== modelId)
  } else {
    textCompletionModels.value = [...textCompletionModels.value, { id: model.id, name: model.name }]
  }
}

function removeTextCompletionModel(id: string) {
  textCompletionModels.value = textCompletionModels.value.filter((m) => m.id !== id)
}

function clearAllModels() {
  textCompletionModels.value = []
}

function toggleTool(toolId: string) {
  const current = selectedTools.value
  if (current.includes(toolId)) {
    selectedTools.value = current.filter((id) => id !== toolId)
  } else {
    selectedTools.value = [...current, toolId]
  }
}

const selectedGroupIds = computed(() => {
  return new Set(excludedShareGroups.value)
})

const filteredGroups = computed(() => {
  const query = groupsFilter.value.toLowerCase().trim()
  let groups = availableGroups.value

  // Filter by search query if provided
  if (query) {
    groups = groups.filter((group) => {
      const name = group.displayName.toLowerCase()
      const principal = group.principal.toLowerCase()
      return name.includes(query) || principal.includes(query)
    })
  }

  // Keep all groups visible (including selected ones) - they'll show checkmarks
  return groups
})

async function loadGroups() {
  loadingGroups.value = true
  try {
    const { data } = await API.searchGroups()
    availableGroups.value = data?.results ?? []
  } catch (error) {
    console.error('Failed to load groups:', error)
    availableGroups.value = []
  } finally {
    loadingGroups.value = false
  }
}

function toggleGroup(groupPrincipal: string) {
  const current = excludedShareGroups.value
  if (current.includes(groupPrincipal)) {
    excludedShareGroups.value = current.filter((g) => g !== groupPrincipal)
  } else {
    excludedShareGroups.value = [...current, groupPrincipal]
  }
  updateExcludedGroups()
}

function updateExcludedGroups() {
  updateDraft((cfg) => {
    cfg.myAgentsExcludedShareGroups =
      excludedShareGroups.value.length > 0 ? [...excludedShareGroups.value] : undefined
  })
}

async function loadOptions() {
  try {
    const { data } = await API.listMyAgentsOptions()
    fileSystemConnections.value = data?.fileSystemConnections ?? []
    folders.value = data?.folders ?? []
    managedTools.value = data?.managedTools ?? []
  } catch (error) {
    console.error('Failed to load My Agents options:', error)
  }
}

onMounted(async () => {
  loading.value = true
  try {
    const [llmsData] = await Promise.all([API.listAvailableLLMs(), loadOptions()])
    availableTextModels.value = llmsData.data?.textCompletionModels ?? []
    availableEmbeddingModels.value = llmsData.data?.embeddingModels ?? []
    // Load groups if groups restriction is enabled
    if (enableGroupsRestriction.value) {
      await loadGroups()
    }
  } finally {
    loading.value = false
  }
})

// Watch enableGroupsRestriction to load groups when enabled and reset when disabled
watch(enableGroupsRestriction, async (enabled) => {
  if (enabled) {
    await loadGroups()
  } else {
    // Reset group selection when disabling groups restriction
    excludedShareGroups.value = []
    updateExcludedGroups()
  }
})

const missing = (v?: string) => !v || !v.trim()
</script>

<template>
  <div class="space-y-6">
    <div class="border rounded-lg admin-collapsible-card">
      <div class="px-4 py-3">
        <div class="flex items-center gap-2">
          <Switch
            class="admin-switch"
            v-model="myAgentsEnabled"
            @update:modelValue="(v: boolean) => (myAgentsEnabled = !!v)"
          />
          <label class="font-medium text-sm cursor-pointer">Enable My Agents</label>
        </div>
        <p class="admin-field-description ml-10">Allow users to build and use their own agents</p>
      </div>

      <div v-if="myAgentsEnabled" class="px-4 pb-4">
        <Separator class="mb-4" />

        <div class="space-y-4 pt-2 max-w-3xl">
          <div id="field-textCompletionModels" class="flex flex-col">
            <label class="admin-field-label"> LLMs<span class="text-red-600">*</span> </label>

            <DropdownMenu>
              <DropdownMenuTrigger as-child>
                <Button
                  variant="outline"
                  class="admin-select-trigger admin-dropdown-trigger w-full lg:w-[420px] justify-between"
                  :class="[textCompletionModels.length === 0 ? 'border-red-500' : '']"
                >
                  <span v-if="textCompletionModels.length === 0" class="text-muted-foreground">
                    Select models...
                  </span>
                  <span v-else>
                    {{ textCompletionModels.length }} model{{
                      textCompletionModels.length === 1 ? '' : 's'
                    }}
                    selected
                  </span>
                  <i class="dku-icon-caret-down-12 ml-2"></i>
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent class="w-[420px] p-0" align="start">
                <div class="p-2 border-b">
                  <Input v-model="modelsFilter" placeholder="Search models..." class="h-8" />
                </div>
                <div class="max-h-[300px] overflow-y-auto p-2">
                  <template v-for="(models, type) in filteredModelsByType" :key="type">
                    <div class="px-2 py-1.5 text-xs font-semibold text-muted-foreground">
                      {{ type }}
                    </div>
                    <div
                      v-for="model in models"
                      :key="model.id"
                      @click="toggleTextCompletionModel(model.id)"
                      class="flex items-center gap-2 px-2 py-2 cursor-pointer hover:bg-accent rounded-md"
                    >
                      <div
                        class="flex items-center justify-center w-4 h-4 border rounded flex-shrink-0 border-input"
                        :class="selectedModelIds.has(model.id) && 'bg-black'"
                      >
                        <i
                          v-if="selectedModelIds.has(model.id)"
                          class="dku-icon-checkmark-12 text-primary-foreground"
                        ></i>
                      </div>
                      <div class="flex-1 min-w-0">
                        <div class="text-sm font-medium">{{ model.name }}</div>
                        <div class="text-xs text-muted-foreground truncate">{{ model.id }}</div>
                      </div>
                    </div>
                  </template>
                  <div
                    v-if="Object.keys(filteredModelsByType).length === 0"
                    class="px-2 py-4 text-center text-sm text-muted-foreground"
                  >
                    No models found
                  </div>
                </div>
              </DropdownMenuContent>
            </DropdownMenu>

            <div v-if="textCompletionModels.length === 0" class="text-[11px] mt-1 text-red-600">
              <i class="dku-icon-warning-12 mr-1"></i>At least one LLM is required
            </div>

            <p class="admin-field-description">Models available for My Agents text generation</p>

            <div v-if="textCompletionModels.length > 0">
              <div class="flex items-center justify-end mb-2">
                <Button @click="clearAllModels" variant="ghost" size="sm" class="admin-icon--trash">
                  <i class="dku-icon-trash-16 mr-1"></i>
                  <span class="hidden sm:inline">Remove all</span>
                  <span class="sm:hidden">Remove</span>
                </Button>
              </div>

              <div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-3">
                <div
                  v-for="model in textCompletionModels"
                  :key="model.id"
                  class="flex items-start gap-3 border admin-tool-card rounded-lg p-3 transition-all relative group"
                >
                  <div class="flex-1 min-w-0 pr-6">
                    <div class="font-semibold text-sm admin-tool-title mb-1 leading-tight">
                      {{ model.name }}
                    </div>
                    <div class="text-xs text-muted-foreground truncate">{{ model.id }}</div>
                  </div>
                  <TooltipProvider>
                    <Tooltip>
                      <TooltipTrigger as-child>
                        <Button
                          size="sm"
                          variant="ghost"
                          @click.stop="removeTextCompletionModel(model.id)"
                          class="admin-icon--trash"
                        >
                          <i class="dku-icon-trash-16"></i>
                        </Button>
                      </TooltipTrigger>
                      <TooltipContent hide-arrow>
                        <p>Remove model</p>
                      </TooltipContent>
                    </Tooltip>
                  </TooltipProvider>
                </div>
              </div>
            </div>
          </div>

          <div id="field-embeddingModel">
            <label class="admin-field-label">
              Embedding Model<span class="text-red-600">*</span>
            </label>
            <div class="w-full lg:w-[256px]">
              <Select v-model="embeddingModel">
                <SelectTrigger
                  class="w-full admin-select-trigger"
                  :class="[
                    missing(embeddingModel) ? 'border-red-500' : '',
                    'admin-dropdown-trigger',
                  ]"
                >
                  <SelectValue placeholder="Select embedding model" />
                </SelectTrigger>
                <SelectContent hide-indicator>
                  <template v-for="(models, type) in embeddingModelsByType" :key="type">
                    <SelectLabel class="admin-select-label text-xs font-semibold px-2 py-1.5">
                      {{ type }}
                    </SelectLabel>
                    <SelectGroup>
                      <SelectItem
                        v-for="model in models"
                        :key="model.id"
                        :value="model.id"
                        class="pl-6 admin-select-item"
                      >
                        {{ model.name }}
                      </SelectItem>
                    </SelectGroup>
                  </template>
                </SelectContent>
              </Select>
            </div>
            <div v-if="missing(embeddingModel)" class="text-[11px] mt-1 text-red-600">
              <i class="dku-icon-warning-12 mr-1"></i>Embedding Model is required
            </div>
            <p class="admin-field-description">Model used to embed My Agents documents</p>
          </div>

          <Separator />

          <div id="field-fsConnection">
            <label class="admin-field-label">
              File System Connection<span class="text-red-600">*</span>
            </label>
            <div class="w-full lg:w-[256px]">
              <Select v-model="fsConnection">
                <SelectTrigger
                  class="w-full admin-select-trigger"
                  :class="[missing(fsConnection) ? 'border-red-500' : '', 'admin-dropdown-trigger']"
                >
                  <SelectValue placeholder="Select a connection" />
                </SelectTrigger>
                <SelectContent hide-indicator>
                  <SelectGroup>
                    <SelectItem
                      v-for="conn in fileSystemConnections"
                      :key="conn.id"
                      :value="conn.id"
                      class="admin-select-item"
                    >
                      {{ conn.label }}
                    </SelectItem>
                  </SelectGroup>
                </SelectContent>
              </Select>
            </div>
            <div v-if="missing(fsConnection)" class="text-[11px] mt-1 text-red-600">
              <i class="dku-icon-warning-12 mr-1"></i>File System Connection is required
            </div>
            <p class="admin-field-description">Connection to use for storing My Agents files</p>
          </div>

          <div id="field-folder">
            <label class="admin-field-label"> Folder where My Agents will be created </label>
            <div class="w-full lg:w-[256px]">
              <Select v-model="folder">
                <SelectTrigger class="w-full admin-select-trigger admin-dropdown-trigger">
                  <SelectValue placeholder="Select a folder" />
                </SelectTrigger>
                <SelectContent hide-indicator>
                  <SelectGroup>
                    <SelectItem
                      v-for="f in folders"
                      :key="f.id"
                      :value="f.id"
                      class="admin-select-item"
                      :style="{ paddingLeft: `${(f.level + 1) * 12}px` }"
                    >
                      {{ f.name }}
                    </SelectItem>
                  </SelectGroup>
                </SelectContent>
              </Select>
            </div>
            <p class="admin-field-description">Project folder where user agents will be stored</p>
          </div>

          <div id="field-numDocs">
            <label class="admin-field-label">
              Number of documents to retrieve<span class="text-red-600">*</span>
            </label>
            <Input
              v-model="numDocs"
              inputmode="numeric"
              type="number"
              min="1"
              step="1"
              class="admin-input w-[200px]"
              :class="[!numDocs || Number(numDocs) < 1 ? 'border-red-500' : '']"
            />
            <div v-if="!numDocs || Number(numDocs) < 1" class="text-[11px] mt-1 text-red-600">
              <i class="dku-icon-warning-12 mr-1"></i>Number of documents must be at least 1
            </div>
            <p class="admin-field-description">
              Maximum number of document chunks to retrieve for context
            </p>
          </div>

          <Separator />

          <div>
            <label class="admin-field-label">Managed Tools</label>
            <p class="admin-field-description">Tools available for My Agents to use</p>
            <div v-if="managedTools.length > 0" class="grid grid-cols-1 md:grid-cols-2 gap-3 mt-2">
              <AdminToolCard
                v-for="tool in managedTools"
                :key="tool.id"
                :tool="tool"
                :isSelected="selectedTools.includes(tool.id)"
                @toggle="toggleTool(tool.id)"
              />
            </div>
            <div v-else class="text-sm text-muted-foreground mt-2">No managed tools available</div>
          </div>

          <Separator />

          <div>
            <div class="flex items-center gap-2">
              <Switch
                class="admin-switch"
                v-model="enablePromptLibrary"
                @update:modelValue="(v: boolean) => (enablePromptLibrary = !!v)"
              />
              <label class="font-medium text-sm cursor-pointer">Enable Prompt Library</label>
            </div>
            <p class="admin-field-description ml-10">
              Allow users to access and use the prompt library in My Agents
            </p>
          </div>

          <Separator />

          <div>
            <div class="flex items-center gap-2">
              <Switch
                class="admin-switch"
                v-model="enableGroupsRestriction"
                @update:modelValue="(v: boolean) => (enableGroupsRestriction = !!v)"
              />
              <label class="font-medium text-sm cursor-pointer"
                >Enable groups restriction for sharing</label
              >
            </div>
            <p class="admin-field-description ml-10">
              By default, users can share agents with all groups. Enable this to restrict sharing to
              only the user's own DSS groups and members
            </p>
          </div>

          <div v-if="enableGroupsRestriction" id="field-excludedShareGroups">
            <label class="admin-field-label">List of groups that users may not share with</label>
            <p class="admin-field-description">
              Groups listed here will be excluded from the user's available groups for sharing
            </p>

            <DropdownMenu>
              <DropdownMenuTrigger as-child>
                <Button
                  variant="outline"
                  class="admin-select-trigger admin-dropdown-trigger w-full lg:w-[420px] justify-between"
                >
                  <span v-if="excludedShareGroups.length === 0" class="text-muted-foreground">
                    Select groups...
                  </span>
                  <span v-else>
                    {{ excludedShareGroups.length }} group{{
                      excludedShareGroups.length === 1 ? '' : 's'
                    }}
                    selected
                  </span>
                  <i class="dku-icon-caret-down-12 ml-2"></i>
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent class="w-[420px] p-0" align="start">
                <div class="p-2 border-b">
                  <Input v-model="groupsFilter" placeholder="Search groups..." class="h-8" />
                </div>
                <div class="max-h-[300px] overflow-y-auto p-2">
                  <div
                    v-if="loadingGroups"
                    class="px-2 py-4 text-center text-sm text-muted-foreground"
                  >
                    Loading groups...
                  </div>
                  <div
                    v-else-if="filteredGroups.length === 0"
                    class="px-2 py-4 text-center text-sm text-muted-foreground"
                  >
                    No groups found
                  </div>
                  <div
                    v-else
                    v-for="group in filteredGroups"
                    :key="group.principal"
                    @click="toggleGroup(group.principal)"
                    class="flex items-center gap-2 px-2 py-2 cursor-pointer hover:bg-accent rounded-md"
                  >
                    <div
                      class="flex items-center justify-center w-4 h-4 border rounded flex-shrink-0 border-input"
                      :class="selectedGroupIds.has(group.principal) && 'bg-black'"
                    >
                      <i
                        v-if="selectedGroupIds.has(group.principal)"
                        class="dku-icon-checkmark-12 text-primary-foreground"
                      ></i>
                    </div>
                    <div class="flex-1 min-w-0">
                      <div class="text-sm font-medium">{{ group.displayName }}</div>
                    </div>
                  </div>
                </div>
              </DropdownMenuContent>
            </DropdownMenu>
          </div>
        </div>
      </div>
    </div>

    <div class="text-sm flex">
      <p class="text-red-600 pr-1">*</p>
      fields marked with an asterisk are mandatory for publishing
    </div>
  </div>
</template>
