import { defineStore } from 'pinia'
import { API } from '@/Api'
import { useIndexingStore } from '@/store/indexingStore'
import { isIndexing } from '@/constants/indexing'

export interface AgentBrief {
  id: string
  name: string
  status?: 'active' | 'draft'
  indexing?: { status: string }
  createdAt?: string
  isShared?: boolean
  shareCount: number
  published_at?: string
  publishing_status?: string
  published_version?: any
  hasUnpublishedChanges?: boolean
  isEnterprise?: boolean
  description?: string
  enableStories?: string
  exampleQuestions?: string[]
  shortExampleQueries?: string[]
  project_key?: string
}

export const useAgentCatalogStore = defineStore('agentCatalog', {
  state: () => ({
    agents: [] as AgentBrief[],
    loaded: false,
    loading: false,
  }),

  getters: {
    activeAgents: (state) => state.agents.filter((a) => !(a.status === 'draft')),
    getAgentById: (state) => (id: string) => state.agents.find((a) => a.id === id),
    getAllExampleQuestions: (state) =>
      state.agents.flatMap((a) => a.exampleQuestions || []).filter((q) => q !== ''),
  },

  actions: {
    async load(force = false) {
      if (this.loaded && !force) return
      if (this.loading) return
      this.loading = true
      try {
        const { data } = await API.getAgents()
        const enterprise = data.enterpriseAgents?.map((a: any) => ({
          id: a.id,
          name: a.name,
          isEnterprise: true,
          description: a.description,
          enableStories: a.stories_workspace ? true : false,
          shortExampleQueries: a.short_example_queries || [],
          exampleQuestions: a.example_queries || [],
          owner: a.owner,
          published_at: a.published_at,
        }))

        const user = data.userAgents?.map((a: any) => ({
          id: a.id,
          name: a.name,
          status: a.status ?? 'active',
          indexing: a.indexing ?? { status: '' },
          createdAt: a.createdAt,
          isShared: a.isShared,
          shareCount: a.shareCount,
          published_at: a.published_at,
          published_version: a.published_version,
          publishing_status: a.publishing_status,
          description: a.description,
          hasUnpublishedChanges: a.hasUnpublishedChanges ?? false,
          owner: a.owner,
          exampleQuestions: a.sample_questions || [],
          shortExampleQueries: a.short_example_queries || [],
        }))

        const fresh: AgentBrief[] = [...enterprise, ...user].map((na) => {
          const prev = this.agents.find((p) => p.id === na.id && p.status === na.status)
          return {
            ...na,
            indexing: na.indexing?.status ? na.indexing : prev?.indexing ?? { status: '' },
          }
        })

        this.agents = fresh
        this.loaded = true

        const idxStore = useIndexingStore()
        fresh.forEach((a) => {
          if (isIndexing(a.indexing?.status)) {
            idxStore.track(a.id, a.indexing!, a.name)
          }
        })
      } finally {
        this.loading = false
      }
    },

    invalidate() {
      this.loaded = false
    },

    updateAgent(agent: Partial<AgentBrief> & { id: string }) {
      const status = 'status' in agent ? agent.status : undefined

      const findIdx = () =>
        this.agents.findIndex((a) => a.id === agent.id && (status ? a.status === status : true))

      let idx = findIdx()

      if (idx !== -1) {
        const prev = this.agents[idx]
        const merged = {
          ...prev,
          ...agent,
          indexing: agent.indexing ?? prev.indexing,
        }
        this.agents[idx] = merged
      } else {
        const fullAgent = {
          ...agent,
          status: status || 'active',
          indexing: agent.indexing || { status: '' },
        } as AgentBrief
        this.agents.push(fullAgent)
      }

      if (status === 'draft' && 'hasUnpublishedChanges' in agent) {
        this.agents
          .filter((a) => a.id === agent.id && a.status === 'active')
          .forEach((a) => (a.hasUnpublishedChanges = agent.hasUnpublishedChanges))
      }

      if (status === 'active' && agent.published_at) {
        const activeAgent = this.agents.find((a) => a.id === agent.id && a.status === 'active')
        if (activeAgent) {
          activeAgent.hasUnpublishedChanges = false
        }
      }
    },

    removeAgent(id: string) {
      this.agents = this.agents.filter((a) => a.id !== id)
    },
  },
})
