import { NextResponse } from 'next/server';
import { z } from 'zod';
import { OLLAMA_URL } from '../../lib/ollama-config';

const PostBodySchema = z.object({
  action: z.enum(['load', 'unload', 'pull', 'delete', 'show']),
  model: z
    .string()
    .min(1)
    .max(256)
    .regex(/^[a-zA-Z0-9._:/-]+$/),
});

async function fetchOllama(path: string, options?: RequestInit) {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), 5000);
  try {
    const res = await fetch(`${OLLAMA_URL}${path}`, {
      ...options,
      signal: controller.signal,
      headers: { 'Content-Type': 'application/json', ...options?.headers },
    });
    if (!res.ok) throw new Error(`Ollama ${path}: ${res.status}`);
    return res.json();
  } finally {
    clearTimeout(timeout);
  }
}

export async function GET() {
  try {
    const [modelsRes, psRes, versionRes] = await Promise.allSettled([
      fetchOllama('/api/tags'),
      fetchOllama('/api/ps'),
      fetchOllama('/api/version'),
    ]);

    const models = modelsRes.status === 'fulfilled' ? (modelsRes.value.models ?? []) : [];
    const running = psRes.status === 'fulfilled' ? (psRes.value.models ?? []) : [];
    const version = versionRes.status === 'fulfilled' ? (versionRes.value.version ?? null) : null;

    const totalSize = models.reduce((acc: number, m: { size: number }) => acc + (m.size || 0), 0);

    return NextResponse.json({
      status: 'online',
      url: OLLAMA_URL,
      models,
      running,
      totalModels: models.length,
      totalSize,
      runningCount: running.length,
      version,
    });
  } catch {
    return NextResponse.json({
      status: 'offline',
      url: OLLAMA_URL,
      models: [],
      running: [],
      totalModels: 0,
      totalSize: 0,
      runningCount: 0,
    });
  }
}

export async function POST(request: Request) {
  try {
    const raw = await request.json();
    const parsed = PostBodySchema.safeParse(raw);
    if (!parsed.success) {
      return NextResponse.json(
        { error: parsed.error.issues[0]?.message || 'Invalid request' },
        { status: 400 }
      );
    }
    const { action, model } = parsed.data;

    if (action === 'load') {
      await fetchOllama('/api/generate', {
        method: 'POST',
        body: JSON.stringify({ model, prompt: '', keep_alive: '10m' }),
      });
      return NextResponse.json({ success: true, message: `Loaded ${model}` });
    }

    if (action === 'unload') {
      await fetchOllama('/api/generate', {
        method: 'POST',
        body: JSON.stringify({ model, prompt: '', keep_alive: '0' }),
      });
      return NextResponse.json({ success: true, message: `Unloaded ${model}` });
    }

    if (action === 'pull') {
      const res = await fetch(`${OLLAMA_URL}/api/pull`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: model, stream: false }),
      });
      if (!res.ok) throw new Error(`Pull failed: ${res.status}`);
      return NextResponse.json({ success: true, message: `Pulled ${model}` });
    }

    if (action === 'delete') {
      const res = await fetch(`${OLLAMA_URL}/api/delete`, {
        method: 'DELETE',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: model }),
      });
      if (!res.ok) throw new Error(`Delete failed: ${res.status}`);
      return NextResponse.json({ success: true, message: `Deleted ${model}` });
    }

    if (action === 'show') {
      const data = await fetchOllama('/api/show', {
        method: 'POST',
        body: JSON.stringify({ name: model }),
      });
      return NextResponse.json({ success: true, ...data });
    }

    return NextResponse.json({ error: 'Unknown action' }, { status: 400 });
  } catch (err) {
    return NextResponse.json({ error: String(err) }, { status: 500 });
  }
}
