import { defineStore } from 'pinia'
import type { AgentInfo, OperationsSnapshot, RoutingTarget } from '../types'
import { apiFetch } from '../services/api'

const fallback: OperationsSnapshot = {
  generatedAt: new Date().toISOString(),
  runtime: { runtime: 'OpenClaw', status: 'Unknown', detail: 'Awaiting connection…' },
  models: [],
  metrics: { activeAgents: 0, queuedTasks: 0, successRate: 0, incidents: 0 },
  projects: [],
  tasks: [],
  activity: [],
}

const fallbackRouting: RoutingTarget[] = []

export const useOperationsStore = defineStore('operations', {
  state: () => ({
    snapshot: fallback,
    routing: fallbackRouting,
    loading: false,
    connected: false,
  }),
  actions: {
    async createProject(name: string) {
      const response = await apiFetch('/api/v1/projects', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name }),
      })
      if (!response.ok) throw new Error('Project could not be created')
      const project = await response.json()
      this.snapshot.projects.unshift({
        id: project.id,
        name: project.name,
        status: project.status,
        progress: project.progress,
      })
    },
    async createTask(title: string, priority: string) {
      const response = await apiFetch('/api/v1/tasks', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ title, priority }),
      })
      if (!response.ok) throw new Error('Task could not be created')
      const task = await response.json()
      this.snapshot.tasks.unshift(task)
      this.snapshot.metrics.queuedTasks += 1
    },
    async updateTaskState(id: string, state: string) {
      const response = await apiFetch(`/api/v1/tasks/${id}/state`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ state }),
      })
      if (!response.ok) throw new Error('Task state could not be updated')
      const updatedTask = await response.json()
      const index = this.snapshot.tasks.findIndex(task => task.id === id)
      if (index !== -1) this.snapshot.tasks[index] = updatedTask
      this.snapshot.metrics.queuedTasks = this.snapshot.tasks.filter(task => task.state !== 'Done').length
      this.snapshot.metrics.incidents = this.snapshot.tasks.filter(task => task.state === 'Blocked').length
      const completed = this.snapshot.tasks.filter(task => task.state === 'Done').length
      this.snapshot.metrics.successRate = this.snapshot.tasks.length
        ? Math.round((completed * 1000) / this.snapshot.tasks.length) / 10
        : 100
    },
    async updateTask(id: string, data: { title?: string; priority?: string; projectId?: string | null }) {
      const response = await apiFetch(`/api/v1/tasks/${id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
      })
      if (!response.ok) throw new Error('Task could not be updated')
      const updatedTask = await response.json()
      const index = this.snapshot.tasks.findIndex(task => task.id === id)
      if (index !== -1) this.snapshot.tasks[index] = updatedTask
    },
    async updateProject(id: string, data: { name?: string; description?: string; status?: string }) {
      const response = await apiFetch(`/api/v1/projects/${id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
      })
      if (!response.ok) throw new Error('Project could not be updated')
      const updatedProject = await response.json()
      const index = this.snapshot.projects.findIndex(p => p.id === id)
      if (index !== -1) this.snapshot.projects[index] = {
        id: updatedProject.id,
        name: updatedProject.name,
        status: updatedProject.status,
        progress: updatedProject.progress,
      }
    },
    async deleteTask(id: string) {
      const response = await apiFetch(`/api/v1/tasks/${id}`, {
        method: 'DELETE',
      })
      if (response.status === 403) {
        const err = await response.json().catch(() => ({ detail: 'Task cannot be deleted in its current state.' }))
        throw new Error(err.detail || 'Task cannot be deleted in its current state.')
      }
      if (!response.ok) throw new Error('Task could not be deleted')
      this.snapshot.tasks = this.snapshot.tasks.filter(t => t.id !== id)
      this.snapshot.metrics.queuedTasks = this.snapshot.tasks.filter(t => t.state !== 'Done').length
      const completed = this.snapshot.tasks.filter(t => t.state === 'Done').length
      this.snapshot.metrics.successRate = this.snapshot.tasks.length
        ? Math.round((completed * 1000) / this.snapshot.tasks.length) / 10
        : 100
    },
    async deleteProject(id: string) {
      const response = await apiFetch(`/api/v1/projects/${id}`, {
        method: 'DELETE',
      })
      if (!response.ok) throw new Error('Project could not be deleted')
      this.snapshot.projects = this.snapshot.projects.filter(p => p.id !== id)
    },
    async refresh() {
      this.loading = true
      try {
        const [snapshotResponse, routingResponse] = await Promise.all([
          apiFetch('/api/v1/operations/snapshot'),
          apiFetch('/api/v1/routing'),
        ])
        if (!snapshotResponse.ok || !routingResponse.ok) throw new Error('Nexus API unavailable')
        this.snapshot = await snapshotResponse.json()
        this.routing = await routingResponse.json()
        this.connected = true
      } catch {
        this.connected = false
      } finally {
        this.loading = false
      }
    },
    async fetchAgents(): Promise<AgentInfo[]> {
      try {
        const response = await apiFetch('/api/v1/agents')
        if (!response.ok) throw new Error('Failed to fetch agents')
        return await response.json()
      } catch {
        return []
      }
    },
    async approveTask(id: string) {
      const response = await apiFetch(`/api/v1/tasks/${id}/approve`, {
        method: 'POST',
      })
      if (!response.ok) throw new Error('Task could not be approved')
      const index = this.snapshot.tasks.findIndex(task => task.id === id)
      if (index !== -1) {
        this.snapshot.tasks.splice(index, 1)
      }
      this.snapshot.metrics.queuedTasks = this.snapshot.tasks.filter(task => task.state !== 'Done').length
      this.snapshot.metrics.incidents = this.snapshot.tasks.filter(task => task.state === 'Blocked').length
      const completed = this.snapshot.tasks.filter(task => task.state === 'Done').length
      this.snapshot.metrics.successRate = this.snapshot.tasks.length
        ? Math.round((completed * 1000) / this.snapshot.tasks.length) / 10
        : 100
    },
    async rejectTask(id: string) {
      const response = await apiFetch(`/api/v1/tasks/${id}/reject`, {
        method: 'POST',
      })
      if (!response.ok) throw new Error('Task could not be rejected')
      const index = this.snapshot.tasks.findIndex(task => task.id === id)
      if (index !== -1) {
        this.snapshot.tasks[index] = { ...this.snapshot.tasks[index], state: 'Backlog' }
      }
      this.snapshot.metrics.queuedTasks = this.snapshot.tasks.filter(task => task.state !== 'Done').length
      this.snapshot.metrics.incidents = this.snapshot.tasks.filter(task => task.state === 'Blocked').length
      const completed = this.snapshot.tasks.filter(task => task.state === 'Done').length
      this.snapshot.metrics.successRate = this.snapshot.tasks.length
        ? Math.round((completed * 1000) / this.snapshot.tasks.length) / 10
        : 100
    },
  },
})
