import { Router, IRouter } from 'express';
import { voteService } from '../services/vote.service';
import { voteSubmitSchema } from '@gala/shared/utils';
import { VOTE_CATEGORIES } from '@gala/shared/types';
import type { VoteCategory } from '@gala/shared/types';

const router: IRouter = Router();

/**
 * POST /api/vote/submit
 * Submit a vote (HTTP fallback for WebSocket)
 */
router.post('/submit', async (req, res, next) => {
  try {
    // TODO: Get userId from auth middleware
    const userId = req.headers['x-user-id'] as string;
    if (!userId) {
      return res.status(401).json({
        success: false,
        error: 'UNAUTHORIZED',
        message: 'User ID required',
      });
    }

    // Validate input
    const parseResult = voteSubmitSchema.safeParse(req.body);
    if (!parseResult.success) {
      return res.status(400).json({
        success: false,
        error: 'INVALID_INPUT',
        message: parseResult.error.message,
      });
    }

    const { candidateId, category, localId } = parseResult.data;

    const result = await voteService.submitVote(
      userId,
      category as VoteCategory,
      candidateId,
      localId
    );

    if (!result.success) {
      const statusCodes: Record<string, number> = {
        ALREADY_VOTED: 409,
        MAX_VOTES_REACHED: 403,
        LOCK_FAILED: 503,
        INTERNAL_ERROR: 500,
      };

      return res.status(statusCodes[result.error!] || 500).json({
        success: false,
        error: result.error,
        message: result.message,
      });
    }

    return res.json({
      success: true,
      data: {
        candidateId: result.candidate_id,
        newCount: result.new_count,
        userTotalVotes: result.user_total_votes,
      },
    });
  } catch (error) {
    next(error);
  }
});

/**
 * GET /api/vote/results/:category
 * Get results for a specific category
 */
router.get('/results/:category', async (req, res, next) => {
  try {
    const { category } = req.params;
    const limit = parseInt(req.query.limit as string, 10) || 10;

    if (!VOTE_CATEGORIES.includes(category as VoteCategory)) {
      return res.status(400).json({
        success: false,
        error: 'INVALID_CATEGORY',
        message: 'Invalid vote category',
      });
    }

    const results = await voteService.getCategoryResults(category as VoteCategory, limit);

    return res.json({
      success: true,
      data: {
        category,
        results,
      },
    });
  } catch (error) {
    next(error);
  }
});

/**
 * GET /api/vote/results
 * Get results for all categories
 */
router.get('/results', async (_req, res, next) => {
  try {
    const results = await voteService.getAllResults(VOTE_CATEGORIES as unknown as VoteCategory[]);

    return res.json({
      success: true,
      data: results,
    });
  } catch (error) {
    next(error);
  }
});

/**
 * GET /api/vote/status
 * Get user's vote status
 */
router.get('/status', async (req, res, next) => {
  try {
    const userId = req.headers['x-user-id'] as string;
    if (!userId) {
      return res.status(401).json({
        success: false,
        error: 'UNAUTHORIZED',
        message: 'User ID required',
      });
    }

    const votedCategories = await voteService.getUserVotedCategories(userId);

    return res.json({
      success: true,
      data: {
        userId,
        votedCategories,
        remainingVotes: 7 - votedCategories.length,
      },
    });
  } catch (error) {
    next(error);
  }
});

export default router;
