/**
 * media-svc — Images and Videos search
 * API: POST /api/v1/media/images, POST /api/v1/media/videos
 */

import Fastify from 'fastify';
import cors from '@fastify/cors';
import { z } from 'zod';
import { loadChatModel } from './lib/models/registry.js';
import { searchImages } from './lib/agents/image.js';
import { searchVideos } from './lib/agents/video.js';

const PORT = parseInt(process.env.PORT ?? '3016', 10);

const chatModelSchema = z.object({
  providerId: z.string(),
  key: z.string(),
});

const imageBodySchema = z.object({
  query: z.string(),
  chatHistory: z.array(z.tuple([z.string(), z.string()])),
  chatModel: chatModelSchema,
});

const videoBodySchema = z.object({
  query: z.string(),
  chatHistory: z.array(z.tuple([z.string(), z.string()])),
  chatModel: chatModelSchema,
});

const app = Fastify({ logger: true });
await app.register(cors, { origin: true });

app.get('/health', async () => ({ status: 'ok' }));

app.post('/api/v1/media/images', async (req, reply) => {
  try {
    const parsed = imageBodySchema.safeParse((req as { body?: unknown }).body);
    if (!parsed.success) {
      return reply.status(400).send({ error: 'Invalid body', details: parsed.error.flatten() });
    }
    const { query, chatHistory, chatModel } = parsed.data;
    const llm = await loadChatModel(chatModel.providerId, chatModel.key);
    const history = chatHistory.map(([role, content]) => ({
      role: (role === 'human' ? 'user' : 'assistant') as 'user' | 'assistant',
      content,
    }));
    const images = await searchImages({ chatHistory: history, query }, llm);
    return reply.send({ images });
  } catch (err) {
    req.log.error(err);
    const msg = err instanceof Error ? err.message : 'Image search failed';
    return reply.status(500).send({ error: msg });
  }
});

app.post('/api/v1/media/videos', async (req, reply) => {
  try {
    const parsed = videoBodySchema.safeParse((req as { body?: unknown }).body);
    if (!parsed.success) {
      return reply.status(400).send({ error: 'Invalid body', details: parsed.error.flatten() });
    }
    const { query, chatHistory, chatModel } = parsed.data;
    const llm = await loadChatModel(chatModel.providerId, chatModel.key);
    const history = chatHistory.map(([role, content]) => ({
      role: (role === 'human' ? 'user' : 'assistant') as 'user' | 'assistant',
      content,
    }));
    const videos = await searchVideos({ chatHistory: history, query }, llm);
    return reply.send({ videos });
  } catch (err) {
    req.log.error(err);
    const msg = err instanceof Error ? err.message : 'Video search failed';
    return reply.status(500).send({ error: msg });
  }
});

try {
  await app.listen({ port: PORT, host: '0.0.0.0' });
  console.log(`media-svc listening on :${PORT}`);
} catch (err) {
  console.error(err);
  process.exit(1);
}
