import { Router, Request, Response } from 'express';
import { query } from '../db/client';
import { LeaderboardResponse, UserStatsResponse } from '../types';
import { logger } from '../services/logger';

const router = Router();

/**
 * GET /api/leaderboard
 * Aktuelle Rangliste aus der Materialized View
 */
router.get('/', async (req: Request, res: Response): Promise<void> => {
  const userId = req.staffbaseUser!.sub;
  const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);

  try {
    const [entries, metaRows] = await Promise.all([
      query<{
        user_id: string;
        full_name: string;
        team: string | null;
        total_points: number;
        tips_count: number;
        exact_count: number;
        tendency_count: number;
        rank: number;
      }>(
        `SELECT user_id, full_name, team, total_points, tips_count,
                exact_count, tendency_count, rank
         FROM leaderboard
         ORDER BY rank ASC
         LIMIT $1`,
        [limit]
      ),
      query<{ count: string }>(
        'SELECT COUNT(*) FROM leaderboard'
      ),
    ]);

    // Aktuellen User-Rank ermitteln (auch wenn er nicht in den Top-N ist)
    const userEntry = entries.find((e) => e.user_id === userId);
    let currentUserRank: number | null = userEntry?.rank ?? null;

    if (!userEntry) {
      const userRankRows = await query<{ rank: number }>(
        'SELECT rank FROM leaderboard WHERE user_id = $1',
        [userId]
      );
      currentUserRank = userRankRows[0]?.rank ?? null;
    }

    const response: LeaderboardResponse = {
      entries,
      currentUserRank,
      currentUserId: userId,
      totalParticipants: parseInt(metaRows[0]?.count ?? '0'),
      lastUpdated: new Date().toISOString(),
    };

    res.json(response);
  } catch (error) {
    logger.error('Failed to fetch leaderboard', { error });
    res.status(500).json({ error: 'Internal server error' });
  }
});

/**
 * GET /api/leaderboard/me
 * Statistiken des aktuellen Users
 */
router.get('/me', async (req: Request, res: Response): Promise<void> => {
  const userId = req.staffbaseUser!.sub;

  try {
    const [leaderboardRows, tipsRows] = await Promise.all([
      query<{
        full_name: string;
        team: string | null;
        total_points: number;
        tips_count: number;
        exact_count: number;
        tendency_count: number;
        rank: number | null;
      }>(
        `SELECT full_name, team, total_points, tips_count, exact_count, tendency_count, rank
         FROM leaderboard WHERE user_id = $1`,
        [userId]
      ),
      query<{ count: string; wrong_count: string }>(
        `SELECT
           COUNT(*) FILTER (WHERE points IS NOT NULL) AS count,
           COUNT(*) FILTER (WHERE points = 0) AS wrong_count
         FROM tips
         WHERE user_id = $1`,
        [userId]
      ),
    ]);

    const lb = leaderboardRows[0];
    const tipsStats = tipsRows[0];

    const evaluatedCount = parseInt(tipsStats?.count ?? '0');
    const wrongCount = parseInt(tipsStats?.wrong_count ?? '0');
    const accuracy =
      evaluatedCount > 0
        ? Math.round(
            (((lb?.exact_count ?? 0) + (lb?.tendency_count ?? 0)) /
              evaluatedCount) *
              100
          )
        : 0;

    const response: UserStatsResponse = {
      userId,
      fullName: lb?.full_name ?? req.staffbaseUser!.name ?? 'Unbekannt',
      team: lb?.team ?? null,
      totalPoints: lb?.total_points ?? 0,
      rank: lb?.rank ?? null,
      tipsCount: lb?.tips_count ?? 0,
      exactCount: lb?.exact_count ?? 0,
      tendencyCount: lb?.tendency_count ?? 0,
      wrongCount,
      accuracy,
    };

    res.json(response);
  } catch (error) {
    logger.error('Failed to fetch user stats', { error, userId });
    res.status(500).json({ error: 'Internal server error' });
  }
});

export default router;
