import { reactive, computed } from 'vue'
import {
  CellsIcon,
  DashboardSquare01Icon,
  LeftToRightListDashIcon,
  PlayIcon,
  Wrench01Icon
} from '@hugeicons/core-free-icons'

export const MAX_SEARCH_HINT_ACTIONS = 100
export const MAX_SEARCH_HINT_DASHBOARDS = 100
export const MAX_SEARCH_HINT_ENTITIES_PER_TYPE = 50

const SOURCE_ENTITIES = 'entities'
const SOURCE_ACTIONS = 'actions'
const SOURCE_DASHBOARDS = 'dashboards'
const SOURCE_NAVIGATION = 'navigation'

// QuickSearch keeps insertion order; prefer entities over actions for equal matches.
const CATEGORY_PRIORITY = {
  Navigation: 0,
  Dashboards: 1,
  Entities: 2,
  Actions: 3
}

const state = reactive({
  itemsById: {},
  sourceToIds: {}
})

export const searchIndexItems = computed(() => {
  return Object.values(state.itemsById).sort((a, b) => {
    return categoryPriority(a.category) - categoryPriority(b.category)
  })
})

function categoryPriority (category) {
  return CATEGORY_PRIORITY[category] ?? 50
}

export function clearSearchIndex () {
  state.itemsById = {}
  state.sourceToIds = {}
}

function replaceSource (source, items) {
  const previousIds = state.sourceToIds[source] || []

  for (const itemId of previousIds) {
    delete state.itemsById[itemId]
  }

  const nextIds = []
  for (const item of items) {
    if (!item?.id) {
      continue
    }

    state.itemsById[item.id] = item
    nextIds.push(item.id)
  }

  state.sourceToIds[source] = nextIds
}

export function dashboardRoutePath (title, entityType, entityKey) {
  if (!title) {
    return '/'
  }

  if (title === 'Actions' && !entityType && !entityKey) {
    return '/'
  }

  let path = `/dashboards/${encodeURIComponent(title)}`

  if (entityType && entityKey) {
    path += `/${encodeURIComponent(entityType)}/${encodeURIComponent(entityKey)}`
  }

  return path
}

/**
 * Indexes search hints from Init (entities and actions).
 * Dashboards are indexed separately from rootDashboardEntries.
 */
export function indexSearchHints (searchHints) {
  replaceSource(SOURCE_ENTITIES, entityItemsFromHints(searchHints?.entities))
  replaceSource(SOURCE_ACTIONS, actionItemsFromHints(searchHints?.actions))
}

/**
 * Indexes dashboards from Init.rootDashboardEntries (already ACL-filtered).
 */
export function indexRootDashboardEntries (entries) {
  replaceSource(SOURCE_DASHBOARDS, dashboardItemsFromRootEntries(entries))
}

function entityItemsFromHints (hints) {
  if (!Array.isArray(hints)) {
    return []
  }

  const countsByType = {}
  const items = []

  for (const hint of hints) {
    if (!hint?.uniqueKey || !hint?.type) {
      continue
    }

    const count = countsByType[hint.type] || 0
    if (count >= MAX_SEARCH_HINT_ENTITIES_PER_TYPE) {
      continue
    }

    countsByType[hint.type] = count + 1
    items.push({
      id: `entity:${hint.type}:${hint.uniqueKey}`,
      title: hint.title || hint.uniqueKey,
      description: hint.type,
      category: 'Entities',
      type: 'route',
      path: `/entity-details/${encodeURIComponent(hint.type)}/${encodeURIComponent(hint.uniqueKey)}`,
      icon: CellsIcon
    })
  }

  return items
}

function actionItemsFromHints (hints) {
  if (!Array.isArray(hints)) {
    return []
  }

  const items = []
  for (const hint of hints.slice(0, MAX_SEARCH_HINT_ACTIONS)) {
    if (!hint?.bindingId) {
      continue
    }

    items.push({
      id: `action:${hint.bindingId}`,
      title: hint.title || hint.bindingId,
      category: 'Actions',
      type: 'route',
      path: `/action/${encodeURIComponent(hint.bindingId)}`,
      icon: PlayIcon
    })
  }

  return items
}

function dashboardItemsFromRootEntries (entries) {
  if (!Array.isArray(entries)) {
    return []
  }

  const items = []
  for (const entry of entries.slice(0, MAX_SEARCH_HINT_DASHBOARDS)) {
    if (!entry?.title) {
      continue
    }

    const section = (entry.category || '').trim()

    items.push({
      id: `dashboard:${entry.title}`,
      title: entry.title,
      description: section,
      category: 'Dashboards',
      type: 'route',
      path: dashboardRoutePath(entry.title),
      icon: DashboardSquare01Icon
    })
  }

  return items
}

/**
 * Indexes system navigation destinations that the user can already reach from
 * the sidebar, respecting Init visibility flags.
 */
export function indexSystemNavigation ({
  showLogs = false,
  showDiagnostics = false,
  entitiesTitle = 'Entities',
  logsTitle = 'Logs',
  diagnosticsTitle = 'Diagnostics'
} = {}) {
  const items = [{
    id: 'nav:entities',
    title: entitiesTitle,
    category: 'Navigation',
    type: 'route',
    path: '/entities',
    icon: CellsIcon
  }]

  if (showLogs) {
    items.push({
      id: 'nav:logs',
      title: logsTitle,
      category: 'Navigation',
      type: 'route',
      path: '/logs',
      icon: LeftToRightListDashIcon
    })
  }

  if (showDiagnostics) {
    items.push({
      id: 'nav:diagnostics',
      title: diagnosticsTitle,
      category: 'Navigation',
      type: 'route',
      path: '/diagnostics',
      icon: Wrench01Icon
    })
  }

  replaceSource(SOURCE_NAVIGATION, items)
}
