import { FastifyInstance } from 'fastify';
import { DbService, FEEDBACK_ACTIONS, FeedbackAction } from '../services/db.service.js';

export default async function historyRoutes(fastify: FastifyInstance, options: { dbService: DbService }) {
  const { dbService } = options;

  // Record a playback event. completed defaults to false.
  fastify.post('/history', async (request, reply) => {
    const { trackId, completed, batchId, listenedMs } = request.body as {
      trackId: string;
      completed?: boolean;
      batchId?: string;
      listenedMs?: number;
    };
    if (!trackId) {
      return reply.code(400).send({ error: 'trackId is required' });
    }
    // Clamped rather than rejected: a bogus duration must not cost the caller a
    // play record, and a 24h ceiling keeps one bad client from dominating any
    // listening-time total.
    const listened = typeof listenedMs === 'number' && Number.isFinite(listenedMs)
      ? Math.max(0, Math.min(Math.round(listenedMs), 24 * 60 * 60 * 1000))
      : undefined;
    const userId = (request.headers['x-user-id'] as string) || '00000000-0000-0000-0000-000000000000';
    const historyId = await dbService.recordPlay(userId, trackId, completed === true, batchId, listened);
    return reply.send({ historyId });
  });

  // Record a skip (transient negative signal).
  fastify.post('/history/skip', async (request, reply) => {
    const { trackId } = request.body as { trackId: string };
    if (!trackId) {
      return reply.code(400).send({ error: 'trackId is required' });
    }
    const userId = (request.headers['x-user-id'] as string) || '00000000-0000-0000-0000-000000000000';
    await dbService.recordSkip(userId, trackId);
    return reply.send({ status: 'ok' });
  });

  // Recent play history for the user.
  fastify.get('/history', async (request, reply) => {
    const userId = (request.headers['x-user-id'] as string) || '00000000-0000-0000-0000-000000000000';
    return await dbService.getHistory(userId);
  });

  // Explicit feedback.
  fastify.post('/feedback', async (request, reply) => {
    const { trackId, action } = request.body as { trackId: string; action: string };
    if (!trackId) {
      return reply.code(400).send({ error: 'trackId is required' });
    }
    if (!FEEDBACK_ACTIONS.includes(action as FeedbackAction)) {
      return reply.code(400).send({ error: `Invalid action. Allowed: ${FEEDBACK_ACTIONS.join(', ')}` });
    }
    const userId = (request.headers['x-user-id'] as string) || '00000000-0000-0000-0000-000000000000';
    await dbService.recordFeedback(userId, trackId, action as FeedbackAction);
    return reply.send({ status: 'ok' });
  });
}
