/**
 * Votes REST endpoints.
 *
 * POST   /items/:itemId/vote    — toggle upvote (add if not voted, remove if already voted)
 * GET    /items/:itemId/votes   — list voters for an item
 */

import type { FastifyInstance } from 'fastify';
import { NotFoundError } from '../../lib/errors.js';
import { extractAuth } from '../../lib/auth.js';
import * as repo from './repository.js';
import * as itemRepo from '../items/repository.js';
import type { VoteDoc } from './types.js';

export async function voteRoutes(app: FastifyInstance) {
  // Toggle vote
  app.post('/items/:itemId/vote', async req => {
    const auth = await extractAuth(req);
    const { itemId } = req.params as { itemId: string };

    const item = await itemRepo.getById(itemId);
    if (!item) throw new NotFoundError('Item not found');

    const existing = await repo.getByItemAndUser(itemId, auth.sub);

    if (existing) {
      // Remove vote
      await repo.remove(existing.id);
      const newCount = await repo.countByItem(itemId);
      await itemRepo.updateVoteCount(itemId, newCount);
      return { voted: false, voteCount: newCount };
    } else {
      // Add vote
      const doc: VoteDoc = {
        id: `vote_${crypto.randomUUID()}`,
        itemId,
        productId: item.productId,
        userId: auth.sub,
        createdAt: new Date().toISOString(),
      };
      await repo.create(doc);
      const newCount = await repo.countByItem(itemId);
      await itemRepo.updateVoteCount(itemId, newCount);
      return { voted: true, voteCount: newCount };
    }
  });

  // List voters
  app.get('/items/:itemId/votes', async req => {
    await extractAuth(req);
    const { itemId } = req.params as { itemId: string };

    const item = await itemRepo.getById(itemId);
    if (!item) throw new NotFoundError('Item not found');

    const votes = await repo.listByItem(itemId);
    return { votes, count: votes.length };
  });
}
