/**
 * Progress Controller
 *
 * HTTP request handlers for progress tracking endpoints
 */

import { Request, Response } from 'express';
import { progressService } from './progress.service';
import { AuthenticationError } from '../../shared/types';
import { asyncHandler } from '../../shared/middleware/validation.middleware';
import type { ModuleType } from '@prisma/client';

// ============================================
// CONTROLLER
// ============================================

class ProgressController {
  /**
   * GET /api/progress
   * Get overall progress for authenticated user
   */
  getOverallProgress = asyncHandler(async (req: Request, res: Response): Promise<void> => {
    const userId = req.user?.userId;

    if (!userId) {
      throw new AuthenticationError('User authentication required');
    }

    const progress = await progressService.getUserOverallProgress(userId);

    res.json({
      success: true,
      data: progress,
    });
  });

  /**
   * GET /api/progress/module/:moduleId
   * Get progress for a specific module
   */
  getModuleProgress = asyncHandler(async (req: Request, res: Response): Promise<void> => {
    const { moduleId } = req.params;
    const userId = req.user?.userId;

    if (!userId) {
      throw new AuthenticationError('User authentication required');
    }
    
    if (!moduleId) {
      throw new AuthenticationError('Module ID is required');
    }

    const progress = await progressService.getModuleProgress(userId, moduleId);

    res.json({
      success: true,
      data: progress,
    });
  });

  /**
   * GET /api/progress/type/:type
   * Get progress by module type
   */
  getProgressByType = asyncHandler(async (req: Request, res: Response): Promise<void> => {
    const { type } = req.params;
    const userId = req.user?.userId;

    if (!userId) {
      throw new AuthenticationError('User authentication required');
    }

    const progress = await progressService.getProgressByModuleType(
      userId,
      type as ModuleType
    );

    res.json({
      success: true,
      data: progress,
    });
  });

  /**
   * GET /api/progress/activity
   * Get recent activity for authenticated user
   */
  getRecentActivity = asyncHandler(async (req: Request, res: Response): Promise<void> => {
    const userId = req.user?.userId;

    if (!userId) {
      throw new AuthenticationError('User authentication required');
    }

    const limit = parseInt(req.query.limit as string, 10) || 10;

    const activity = await progressService.getRecentActivity(userId, limit);

    res.json({
      success: true,
      data: activity,
    });
  });

  /**
   * GET /api/progress/statistics
   * Get statistics summary for authenticated user
   */
  getStatistics = asyncHandler(async (req: Request, res: Response): Promise<void> => {
    const userId = req.user?.userId;

    if (!userId) {
      throw new AuthenticationError('User authentication required');
    }

    const statistics = await progressService.getStatisticsSummary(userId);

    res.json({
      success: true,
      data: statistics,
    });
  });

  /**
   * GET /api/progress/leaderboard
   * Get leaderboard
   */
  getLeaderboard = asyncHandler(async (req: Request, res: Response): Promise<void> => {
    const {
      moduleId,
      limit = '50',
      includeSelf = 'true',
    } = req.query;

    const limitNum = parseInt(limit as string, 10) || 50;
    const userId = req.user?.userId;

    if (!userId) {
      throw new AuthenticationError('User authentication required');
    }

    const leaderboardOptions: { moduleId?: string; limit: number; includeSelf: boolean; userId: string } = {
      limit: limitNum,
      includeSelf: includeSelf === 'true',
      userId,
    };
    
    if (moduleId) {
      leaderboardOptions.moduleId = moduleId as string;
    }

    const leaderboard = await progressService.getLeaderboards(leaderboardOptions);

    res.json({
      success: true,
      data: leaderboard,
    });
  });

  /**
   * DELETE /api/progress/module/:moduleId
   * Reset module progress (admin only - for now)
   */
  resetModuleProgress = asyncHandler(async (req: Request, res: Response): Promise<void> => {
    const { moduleId } = req.params;
    const userId = req.user?.userId;

    if (!userId) {
      throw new AuthenticationError('User authentication required');
    }
    
    if (!moduleId) {
      throw new AuthenticationError('Module ID is required');
    }

    // TODO: Add admin check here

    await progressService.resetModuleProgress(userId, moduleId);

    res.json({
      success: true,
      data: {
        message: 'Module progress reset successfully',
      },
    });
  });

  /**
   * GET /api/progress/dashboard
   * Get dashboard data for authenticated user
   */
  getDashboard = asyncHandler(async (req: Request, res: Response): Promise<void> => {
    const userId = req.user?.userId;

    if (!userId) {
      throw new AuthenticationError('User authentication required');
    }

    // Get all dashboard data in parallel
    const [overallProgress, recentActivity, statistics] = await Promise.all([
      progressService.getUserOverallProgress(userId),
      progressService.getRecentActivity(userId, 5),
      progressService.getStatisticsSummary(userId),
    ]);

    res.json({
      success: true,
      data: {
        overview: {
          totalPoints: overallProgress.totalPoints,
          totalExercisesCompleted: overallProgress.totalExercisesCompleted,
          totalModulesCompleted: overallProgress.totalModulesCompleted,
          currentStreak: overallProgress.currentStreak,
        },
        modules: overallProgress.modules.slice(0, 6), // First 6 modules
        recentActivity,
        statistics,
      },
    });
  });
}

// ============================================
// EXPORT
// ============================================

export const progressController = new ProgressController();
export default progressController;