import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export interface ToolDefinition {
  name: string
  description: string
  category: 'global' | 'canvas' | 'component' | 'theme' | 'database' | 'source' | 'project'
  schema: object
  handler: Function
}

export const useToolsStore = defineStore('tools', () => {
  // All available tool definitions
  const toolDefinitions = ref<Map<string, ToolDefinition>>(new Map())

  // Pinned tools persist across page changes (use array for reactivity)
  const pinnedToolsArray = ref<string[]>([])

  // Currently active tools (use array for reactivity)
  const activeToolsArray = ref<string[]>([])

  // Computed
  const allTools = computed(() => Array.from(toolDefinitions.value.values()))

  const activeToolsDefs = computed(() =>
    allTools.value.filter(t => activeToolsArray.value.includes(t.name))
  )

  const inactiveToolsDefs = computed(() =>
    allTools.value.filter(t => !activeToolsArray.value.includes(t.name))
  )

  const pinnedToolsDefs = computed(() =>
    allTools.value.filter(t => pinnedToolsArray.value.includes(t.name))
  )

  const toolsByCategory = computed(() => {
    const categories: Record<string, { active: ToolDefinition[], inactive: ToolDefinition[] }> = {}

    for (const tool of allTools.value) {
      if (!categories[tool.category]) {
        categories[tool.category] = { active: [], inactive: [] }
      }

      if (activeToolsArray.value.includes(tool.name)) {
        categories[tool.category].active.push(tool)
      } else {
        categories[tool.category].inactive.push(tool)
      }
    }

    return categories
  })

  // Actions
  function registerToolDefinition(tool: ToolDefinition) {
    toolDefinitions.value.set(tool.name, tool)
  }

  function registerToolDefinitions(tools: ToolDefinition[]) {
    for (const tool of tools) {
      toolDefinitions.value.set(tool.name, tool)
    }
  }

  function setToolActive(name: string, active: boolean) {
    const index = activeToolsArray.value.indexOf(name)
    if (active && index === -1) {
      activeToolsArray.value.push(name)
    } else if (!active && index !== -1) {
      activeToolsArray.value.splice(index, 1)
    }
  }

  function pinTool(name: string) {
    if (!pinnedToolsArray.value.includes(name)) {
      pinnedToolsArray.value.push(name)
      savePinnedTools()
    }
  }

  function unpinTool(name: string) {
    const index = pinnedToolsArray.value.indexOf(name)
    if (index !== -1) {
      pinnedToolsArray.value.splice(index, 1)
      savePinnedTools()
    }
  }

  function togglePin(name: string) {
    if (pinnedToolsArray.value.includes(name)) {
      unpinTool(name)
    } else {
      pinTool(name)
    }
  }

  function isToolPinned(name: string): boolean {
    return pinnedToolsArray.value.includes(name)
  }

  function isToolActive(name: string): boolean {
    return activeToolsArray.value.includes(name)
  }

  function getPinnedToolNames(): string[] {
    return [...pinnedToolsArray.value]
  }

  function getToolDefinition(name: string): ToolDefinition | undefined {
    return toolDefinitions.value.get(name)
  }

  // Persistence
  function savePinnedTools() {
    localStorage.setItem('pinnedTools', JSON.stringify(pinnedToolsArray.value))
  }

  function loadPinnedTools() {
    try {
      const saved = localStorage.getItem('pinnedTools')
      if (saved) {
        const parsed = JSON.parse(saved)
        pinnedToolsArray.value = parsed
      }
    } catch (e) {
      console.error('[ToolsStore] Failed to load pinned tools:', e)
    }
  }

  function clearActiveTools() {
    activeToolsArray.value = []
  }

  function setActiveTools(names: string[]) {
    activeToolsArray.value = [...names]
  }

  // Initialize
  loadPinnedTools()

  return {
    // State (reactive arrays)
    activeTools: activeToolsArray,
    pinnedTools: pinnedToolsArray,
    toolDefinitions,

    // Computed
    allTools,
    activeToolsDefs,
    inactiveToolsDefs,
    pinnedToolsDefs,
    toolsByCategory,

    // Actions
    registerToolDefinition,
    registerToolDefinitions,
    setToolActive,
    pinTool,
    unpinTool,
    togglePin,
    isToolPinned,
    isToolActive,
    getPinnedToolNames,
    getToolDefinition,
    clearActiveTools,
    setActiveTools,
    loadPinnedTools
  }
})
