import type { FastifyInstance } from 'fastify';
import { z } from 'zod';
import type { Sql } from '../db.js';
import type { MessageMetadata } from '../types/api.js';

const FeedbackBody = z.object({
  value: z.enum(['up', 'down']),
});

export function registerMessageFeedbackRoutes(app: FastifyInstance, sql: Sql): void {
  app.post<{ Params: { id: string; message_id: string } }>(
    '/api/chats/:id/messages/:message_id/feedback',
    async (req, reply) => {
      const parsed = FeedbackBody.safeParse(req.body);
      if (!parsed.success) {
        reply.code(400);
        return { error: 'invalid body', details: parsed.error.flatten() };
      }
      const { id: chatId, message_id: messageId } = req.params;
      const { value } = parsed.data;

      const msg = await sql<{ id: string; role: string; metadata: MessageMetadata | null }[]>`
        SELECT id, role, metadata FROM messages WHERE id = ${messageId} AND chat_id = ${chatId}
      `;
      if (msg.length === 0) {
        reply.code(404);
        return { error: 'message not found' };
      }

      // Only allow feedback on assistant messages.
      if (msg[0]!.role !== 'assistant') {
        reply.code(400);
        return { error: 'only assistant messages can receive feedback' };
      }

      // Check if feedback already exists
      const existingMeta = msg[0]!.metadata;
      if (existingMeta && existingMeta.kind === 'feedback') {
        reply.code(409);
        return { error: 'feedback already recorded' };
      }

      const feedbackMeta: MessageMetadata = {
        kind: 'feedback',
        value,
        chat_id: chatId,
      };

      await sql`
        UPDATE messages
        SET metadata = ${sql.json(feedbackMeta as never)}, updated_at = clock_timestamp()
        WHERE id = ${messageId}
      `;

      return { ok: true };
    },
  );
}
