import type { FastifyInstance } from 'fastify';
import type { AiProvider } from '@wa-ticketing/shared';
import { authenticate, requireRole } from '../middleware/auth.js';
import { aiAgentService } from '../services/aiAgentService.js';
import { listModelsForPreview } from '../services/llmProviderService.js';
import { auditService } from '../services/auditService.js';

const adminOnly = [authenticate, requireRole('admin')];
const staff = [authenticate, requireRole('admin', 'user')];

export async function aiAgentRoutes(fastify: FastifyInstance) {
  fastify.get('/', { preHandler: staff }, async (_req, reply) => {
    return reply.send(await aiAgentService.list());
  });

  fastify.post('/preview-models', { preHandler: staff }, async (req, reply) => {
    const body = req.body as {
      provider?: AiProvider;
      api_key?: string;
      base_url?: string | null;
    };
    if (!body?.provider || !['openai', 'anthropic', 'openai_compatible', 'openrouter'].includes(body.provider)) {
      return reply.status(400).send({ error: 'provider is required' });
    }
    try {
      const models = await listModelsForPreview({
        provider: body.provider,
        apiKey: body.api_key ?? '',
        baseUrl: body.base_url,
      });
      return reply.send({ models });
    } catch (e: unknown) {
      const err = e as { statusCode?: number; message?: string };
      return reply.status(err.statusCode ?? 500).send({ error: err.message ?? 'Failed to list models' });
    }
  });

  fastify.post('/', { preHandler: adminOnly }, async (req, reply) => {
    const body = req.body as {
      display_name?: string;
      provider?: AiProvider;
      api_key?: string;
      base_url?: string | null;
      model_id?: string;
      persona_system?: string;
      guardrails?: string;
      knowledge_module_ids?: string[];
    };
    if (!body.display_name?.trim() || !body.provider || !body.model_id?.trim()) {
      return reply.status(400).send({ error: 'display_name, provider, and model_id are required' });
    }
    const a = await aiAgentService.create({
      display_name: body.display_name,
      provider: body.provider,
      api_key: body.api_key ?? '',
      base_url: body.base_url,
      model_id: body.model_id,
      persona_system: body.persona_system,
      guardrails: body.guardrails,
      knowledge_module_ids: body.knowledge_module_ids,
    });
    await auditService.log(req.user!.sub, 'user', 'ai_agent.created', 'ai_agent', a.id, {
      display_name: a.display_name,
    });
    return reply.status(201).send(a);
  });

  fastify.get('/:id', { preHandler: staff }, async (req, reply) => {
    const { id } = req.params as { id: string };
    const a = await aiAgentService.getById(id);
    if (!a) return reply.status(404).send({ error: 'Agent not found' });
    return reply.send(a);
  });

  fastify.patch('/:id', { preHandler: adminOnly }, async (req, reply) => {
    const { id } = req.params as { id: string };
    const body = req.body as Partial<{
      display_name: string;
      provider: AiProvider;
      api_key: string;
      base_url: string | null;
      model_id: string;
      persona_system: string;
      guardrails: string;
      knowledge_module_ids: string[];
    }>;
    const a = await aiAgentService.update(id, body);
    if (!a) return reply.status(404).send({ error: 'Agent not found' });
    await auditService.log(req.user!.sub, 'user', 'ai_agent.updated', 'ai_agent', id, {});
    return reply.send(a);
  });

  fastify.delete('/:id', { preHandler: adminOnly }, async (req, reply) => {
    const { id } = req.params as { id: string };
    const ok = await aiAgentService.delete(id);
    if (!ok) return reply.status(404).send({ error: 'Agent not found' });
    await auditService.log(req.user!.sub, 'user', 'ai_agent.deleted', 'ai_agent', id, {});
    return reply.status(204).send();
  });
}
