/** TUI route — Local model management page */

import { createSignal, createEffect, For, Show } from "solid-js"
import type { BackendStatus, ModelInstance } from "@/provider/local/types"

function fmt(bytes: number): string {
  if (bytes < 1024) return `${bytes}B`
  if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)}KB`
  if (bytes < 1073741824) return `${(bytes / 1048576).toFixed(1)}MB`
  return `${(bytes / 1073741824).toFixed(1)}GB`
}

export function LocalModels() {
  const [tab, setTab] = createSignal<0 | 1 | 2 | 3>(0)
  const [backends, setBackends] = createSignal<BackendStatus[]>([])
  const [instances, setInstances] = createSignal<ModelInstance[]>([])
  const [installed, setInstalled] = createSignal<Array<{ repo: string; filename: string; path: string; sizeBytes: number }>>([])
  const [gpu, setGpu] = createSignal<any>(null)
  const [hubQuery, setHubQuery] = createSignal("")
  const [hubResults, setHubResults] = createSignal<any[]>([])
  const [loading, setLoading] = createSignal(false)

  createEffect(() => { refresh() })

  async function refresh() {
    setLoading(true)
    try {
      const [g, b, m, i] = await Promise.all([
        fetch("/local/gpu").then((r) => r.json()).catch(() => null),
        fetch("/local/backends").then((r) => r.json()).catch(() => []),
        fetch("/local/models").then((r) => r.json()).catch(() => []),
        fetch("/local/instances").then((r) => r.json()).catch(() => []),
      ])
      setGpu(g); setBackends(b); setInstalled(m); setInstances(i)
    } finally { setLoading(false) }
  }

  async function searchHub() {
    const q = hubQuery(); if (!q) return
    const res = await fetch(`/local/hub/search?q=${encodeURIComponent(q)}`)
    setHubResults(await res.json())
  }

  async function loadModel(repo: string, filename: string) {
    await fetch("/local/instances/load", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ repo, filename }) })
    await refresh()
  }

  async function unloadModel(instanceId: string) {
    await fetch("/local/instances/unload", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ instanceId }) })
    await refresh()
  }

  const tabLabels = ["Backends", "Models", "HuggingFace", "RAG"]

  return (
    <box flexDirection="column" width="100%" height="100%" paddingTop={1} paddingBottom={1} paddingLeft={2} paddingRight={2}>
      {/* Header */}
      <box flexDirection="row">
        <text fg="cyan">{"Local Models"}</text>
        <text>{"  "}</text>
        <Show when={gpu()} fallback={<text>{"No GPU info"}</text>}>
          <text>{gpu().cudaAvailable ? `GPU: ${gpu().gpus.length}x | VRAM: ${gpu().availableVRAMMB}MB free` : "No CUDA GPU"}</text>
        </Show>
      </box>

      {/* Tabs */}
      <box flexDirection="row" paddingTop={1} paddingBottom={1}>
        <For each={tabLabels}>
          {(label, i) => (
            <box paddingRight={3}>
              <text fg={tab() === i() ? "green" : "white"}>{tab() === i() ? `[${label}]` : ` ${label} `}</text>
            </box>
          )}
        </For>
      </box>

      {/* Tab: Backends */}
      <Show when={tab() === 0}>
        <text fg="white">{"Detected Backends"}</text>
        <box paddingTop={1} />
        <For each={backends()}>
          {(b) => (
            <box flexDirection="row" paddingBottom={1}>
              <text fg={b.available ? "green" : "red"}>{b.available ? "● " : "○ "}</text>
              <text>{b.type + "  "}</text>
              <text>{b.endpoint}</text>
            </box>
          )}
        </For>
      </Show>

      {/* Tab: Models */}
      <Show when={tab() === 1}>
        <text fg="white">{"Installed Models"}</text>
        <box paddingTop={1} />
        <For each={installed()}>
          {(m) => (
            <box flexDirection="row" paddingBottom={1}>
              <text>{m.repo + "/" + m.filename + "  "}</text>
              <text>{fmt(m.sizeBytes) + "  "}</text>
              <text fg="green">{"[Load]"}</text>
            </box>
          )}
        </For>

        <Show when={instances().length > 0}>
          <box paddingTop={1} />
          <text fg="white">{"Running Instances"}</text>
          <box paddingTop={1} />
          <For each={instances()}>
            {(inst) => (
              <box flexDirection="row" paddingBottom={1}>
                <text fg={inst.status === "running" ? "green" : "yellow"}>{inst.status + " "}</text>
                <text>{inst.artifact.repo + " "}</text>
                <Show when={inst.endpoint}><text>{ "-> " + inst.endpoint + " "}</text></Show>
                <text fg="red">{"[Stop]"}</text>
              </box>
            )}
          </For>
        </Show>
      </Show>

      {/* Tab: Hub Search */}
      <Show when={tab() === 2}>
        <text fg="white">{"Search HuggingFace Hub"}</text>
        <box paddingTop={1} />
        <For each={hubResults()}>
          {(r) => (
            <box flexDirection="column" paddingBottom={1}>
              <text fg="cyan">{r.id}</text>
              <text>{`DL: ${r.downloads} | Likes: ${r.likes}${r.pipelineTag ? " | " + r.pipelineTag : ""}`}</text>
            </box>
          )}
        </For>
      </Show>

      {/* Tab: RAG */}
      <Show when={tab() === 3}>
        <text fg="white">{"RAG Assets"}</text>
        <box paddingTop={1} />
        <text>{"Embedding models, rerankers, and vector databases for RAG pipelines"}</text>
      </Show>

      {/* Loading indicator */}
      <Show when={loading()}>
        <text fg="yellow">{"Loading..."}</text>
      </Show>
    </box>
  )
}
