import { createStore } from "solid-js/store"
import { createSignal } from "solid-js"
import type { WorkerInfo, WorkerStatus, WorkerRole, PoolConfig, WorkerSpawnOpts } from "./types"
import { POOL_DEFAULTS } from "./types"

let nextId = 1

interface WorkerStoreState {
  workers: Record<string, WorkerInfo>
  gridOrder: string[]
  selectedID: string | null
  viewMode: "grid" | "detail"
  config: PoolConfig
  enabled: boolean
}

function emptyState(): WorkerStoreState {
  return {
    workers: {},
    gridOrder: [],
    selectedID: null,
    viewMode: "grid",
    config: { ...POOL_DEFAULTS },
    enabled: false,
  }
}

const [store, setStore] = createStore<WorkerStoreState>(emptyState())

export function getWorkerState() {
  return store
}

export function spawnWorker(opts: WorkerSpawnOpts): string {
  const id = `w_${nextId++}_${Date.now().toString(36)}`
  const cfg = store.config
  const worker: WorkerInfo = {
    id,
    index: store.gridOrder.length,
    sessionID: undefined,
    agent: opts.agent ?? cfg.defaultAgent,
    description: opts.description,
    status: "queued",
    role: opts.role ?? "worker",
    parentID: opts.parentID ?? null,
    childIDs: [],
    spawned: Date.now(),
    tokens: { input: 0, output: 0, reasoning: 0 },
    cost: 0,
    background: opts.background ?? false,
    priority: opts.priority ?? cfg.priorityDefault,
  }
  setStore("workers", id, worker)
  setStore("gridOrder", store.gridOrder.length, id)
  return id
}

export function updateWorker(id: string, patch: Partial<WorkerInfo>) {
  const existing = store.workers[id]
  if (!existing) return
  setStore("workers", id, patch)
}

export function cancelWorker(id: string) {
  const w = store.workers[id]
  if (!w) return
  if (w.status === "queued" || w.status === "running" || w.status === "spawning") {
    updateWorker(id, { status: "cancelled", completed: Date.now() })
  }
}

export function cancelAllWorkers() {
  for (const id of Object.keys(store.workers)) {
    cancelWorker(id)
  }
}

export function selectWorker(id: string | null) {
  setStore("selectedID", id)
}

export function setViewMode(mode: "grid" | "detail") {
  setStore("viewMode", mode)
}

export function setWorkerEnabled(v: boolean) {
  setStore("enabled", v)
}

export function setWorkerConfig(cfg: Partial<PoolConfig>) {
  setStore("config", { ...store.config, ...cfg })
}

export function clearCompleted() {
  const keep: string[] = []
  const newWorkers: Record<string, WorkerInfo> = {}
  for (const id of store.gridOrder) {
    const w = store.workers[id]
    if (!w) continue
    if (w.status === "done" || w.status === "error" || w.status === "cancelled") continue
    keep.push(id)
    newWorkers[id] = w
  }
  setStore({ workers: newWorkers, gridOrder: keep })
}

export function dismissWorker(id: string) {
  const newWorkers = { ...store.workers }
  delete newWorkers[id]
  setStore({
    workers: newWorkers,
    gridOrder: store.gridOrder.filter((gid) => gid !== id),
  })
}

export function getWorkerByIndex(index: number): WorkerInfo | null {
  const id = store.gridOrder[index]
  return id ? store.workers[id] ?? null : null
}

export function getRunningWorkers(): WorkerInfo[] {
  return Object.values(store.workers).filter((w) => w.status === "running" || w.status === "spawning")
}

export function getQueuedWorkers(): WorkerInfo[] {
  return Object.values(store.workers)
    .filter((w) => w.status === "queued")
    .sort((a, b) => a.priority - b.priority)
}

export function getWorkerStats() {
  const all = Object.values(store.workers)
  return {
    total: all.length,
    queued: all.filter((w) => w.status === "queued").length,
    running: all.filter((w) => w.status === "running" || w.status === "spawning").length,
    done: all.filter((w) => w.status === "done").length,
    error: all.filter((w) => w.status === "error").length,
  }
}

export function resetWorkerStore() {
  setStore(emptyState())
}
