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

import {
  acpApi,
  isAgentKindAdmin,
  type AcpSession,
  type AgentKindAdmin,
  type AgentKindPublic,
  type CreateAgentKindReq,
  type CreateSessionReq,
  type UpdateAgentKindReq,
} from '@/api/acp'

export const useAcpStore = defineStore('acp', () => {
  const agentKinds = ref<AgentKindAdmin[]>([]) // admin view (full DTO)
  const enabledAgentKinds = ref<AgentKindPublic[]>([]) // public view (redacted DTO)
  const loading = ref(false)
  const error = ref<string | null>(null)

  const sessions = ref<AcpSession[]>([])
  const currentSession = ref<AcpSession | null>(null)

  async function listAgentKinds(asAdmin: boolean) {
    loading.value = true
    error.value = null
    try {
      const data = await acpApi.agentKinds.list()
      if (asAdmin) {
        agentKinds.value = data.filter(isAgentKindAdmin)
      } else {
        enabledAgentKinds.value = data as AgentKindPublic[]
      }
    } catch (e) {
      error.value = e instanceof Error ? e.message : 'failed'
    } finally {
      loading.value = false
    }
  }

  async function createAgentKind(req: CreateAgentKindReq) {
    const k = await acpApi.agentKinds.create(req)
    agentKinds.value.unshift(k)
    return k
  }

  async function updateAgentKind(id: string, req: UpdateAgentKindReq) {
    const updated = await acpApi.agentKinds.update(id, req)
    const idx = agentKinds.value.findIndex((k) => k.id === id)
    if (idx >= 0) agentKinds.value[idx] = updated
    return updated
  }

  async function deleteAgentKind(id: string) {
    await acpApi.agentKinds.remove(id)
    agentKinds.value = agentKinds.value.filter((k) => k.id !== id)
  }

  async function getAgentKind(id: string) {
    return acpApi.agentKinds.get(id)
  }

  async function listSessions(all = false, requirementId?: string) {
    loading.value = true
    error.value = null
    try {
      sessions.value = await acpApi.sessions.list({ all, requirement_id: requirementId })
    } catch (e) {
      error.value = e instanceof Error ? e.message : 'failed'
    } finally {
      loading.value = false
    }
  }

  async function getSession(id: string) {
    const s = await acpApi.sessions.get(id)
    currentSession.value = s
    return s
  }

  async function createSession(req: CreateSessionReq) {
    const s = await acpApi.sessions.create(req)
    sessions.value.unshift(s)
    return s
  }

  async function terminateSession(id: string) {
    await acpApi.sessions.terminate(id)
    const idx = sessions.value.findIndex((x) => x.id === id)
    if (idx >= 0) {
      sessions.value[idx] = { ...sessions.value[idx], status: 'exited' as const }
    }
    if (currentSession.value?.id === id) {
      currentSession.value = { ...currentSession.value, status: 'exited' as const }
    }
  }

  return {
    agentKinds,
    enabledAgentKinds,
    loading,
    error,
    listAgentKinds,
    createAgentKind,
    updateAgentKind,
    deleteAgentKind,
    getAgentKind,
    sessions,
    currentSession,
    listSessions,
    getSession,
    createSession,
    terminateSession,
  }
})
