using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using QuestPDF.Fluent;
using SportsDivision.Application.Interfaces;
using SportsDivision.Web.Reports;

namespace SportsDivision.Web.Controllers;

[Authorize]
public class ReportController : Controller
{
    private readonly IReportService _reportService;
    private readonly ITournamentService _tournamentService;
    private readonly IScoringService _scoringService;

    public ReportController(
        IReportService reportService,
        ITournamentService tournamentService,
        IScoringService scoringService)
    {
        _reportService = reportService;
        _tournamentService = tournamentService;
        _scoringService = scoringService;
    }

    [HttpGet]
    public async Task<IActionResult> Index()
    {
        var tournaments = await _tournamentService.GetAllAsync();
        return View(tournaments);
    }

    [HttpGet]
    public async Task<IActionResult> PopularEvents(int tournamentId)
    {
        var report = await _reportService.GetPopularEventsAsync(tournamentId);
        ViewBag.TournamentId = tournamentId;
        return View(report);
    }

    [HttpGet]
    public async Task<IActionResult> RegistrationByGender(int tournamentId, int? zoneId)
    {
        var report = await _reportService.GetRegistrationByGenderAsync(tournamentId, zoneId);
        ViewBag.TournamentId = tournamentId;
        ViewBag.ZoneId = zoneId;
        return View(report);
    }

    [HttpGet]
    public async Task<IActionResult> EventSchoolReport(int tournamentId, int? eventId, int? eventLevelId)
    {
        var report = await _reportService.GetEventSchoolReportAsync(tournamentId, eventId, eventLevelId);
        ViewBag.TournamentId = tournamentId;
        ViewBag.EventId = eventId;
        ViewBag.EventLevelId = eventLevelId;
        return View(report);
    }

    [HttpGet]
    public async Task<IActionResult> StudentsBySchool(int tournamentId, int? schoolId, int? zoneId)
    {
        var report = await _reportService.GetStudentsBySchoolAsync(tournamentId, schoolId, zoneId);
        ViewBag.TournamentId = tournamentId;
        ViewBag.SchoolId = schoolId;
        ViewBag.ZoneId = zoneId;
        return View(report);
    }

    [HttpGet]
    public async Task<IActionResult> ScoresByEvent(int tournamentId, int? eventId, int? eventLevelId)
    {
        var report = await _reportService.GetScoresByEventAsync(tournamentId, eventId, eventLevelId);
        ViewBag.TournamentId = tournamentId;
        ViewBag.EventId = eventId;
        ViewBag.EventLevelId = eventLevelId;
        return View(report);
    }

    [HttpGet]
    public async Task<IActionResult> StudentPoints(int tournamentId, int? schoolId, int? zoneId)
    {
        var report = await _reportService.GetStudentPointsAsync(tournamentId, schoolId, zoneId);
        ViewBag.TournamentId = tournamentId;
        ViewBag.SchoolId = schoolId;
        ViewBag.ZoneId = zoneId;
        return View(report);
    }

    [HttpGet]
    public async Task<IActionResult> SchoolStandings(int tournamentId)
    {
        var standings = await _scoringService.GetSchoolStandingsAsync(tournamentId);
        ViewBag.TournamentId = tournamentId;
        return View(standings);
    }

    [HttpGet]
    public async Task<IActionResult> PopularEventsPdf(int tournamentId)
    {
        var report = await _reportService.GetPopularEventsAsync(tournamentId);
        var tournament = await _tournamentService.GetByIdAsync(tournamentId);
        var document = new PopularEventsDocument(report, tournament?.Name ?? "Tournament");
        var pdf = document.GeneratePdf();
        return File(pdf, "application/pdf", $"PopularEvents_{tournamentId}.pdf");
    }

    [HttpGet]
    public async Task<IActionResult> RegistrationByGenderPdf(int tournamentId, int? zoneId)
    {
        var report = await _reportService.GetRegistrationByGenderAsync(tournamentId, zoneId);
        var tournament = await _tournamentService.GetByIdAsync(tournamentId);
        var document = new RegistrationByGenderDocument(report, tournament?.Name ?? "Tournament");
        var pdf = document.GeneratePdf();
        return File(pdf, "application/pdf", $"RegistrationByGender_{tournamentId}.pdf");
    }

    [HttpGet]
    public async Task<IActionResult> EventSchoolReportPdf(int tournamentId, int? eventId, int? eventLevelId)
    {
        var report = await _reportService.GetEventSchoolReportAsync(tournamentId, eventId, eventLevelId);
        var tournament = await _tournamentService.GetByIdAsync(tournamentId);
        var document = new EventSchoolDocument(report, tournament?.Name ?? "Tournament");
        var pdf = document.GeneratePdf();
        return File(pdf, "application/pdf", $"EventSchoolReport_{tournamentId}.pdf");
    }

    [HttpGet]
    public async Task<IActionResult> StudentsBySchoolPdf(int tournamentId, int? schoolId, int? zoneId)
    {
        var report = await _reportService.GetStudentsBySchoolAsync(tournamentId, schoolId, zoneId);
        var tournament = await _tournamentService.GetByIdAsync(tournamentId);
        var document = new StudentsBySchoolDocument(report, tournament?.Name ?? "Tournament");
        var pdf = document.GeneratePdf();
        return File(pdf, "application/pdf", $"StudentsBySchool_{tournamentId}.pdf");
    }

    [HttpGet]
    public async Task<IActionResult> ScoresByEventPdf(int tournamentId, int? eventId, int? eventLevelId)
    {
        var report = await _reportService.GetScoresByEventAsync(tournamentId, eventId, eventLevelId);
        var tournament = await _tournamentService.GetByIdAsync(tournamentId);
        var document = new ScoresByEventDocument(report, tournament?.Name ?? "Tournament");
        var pdf = document.GeneratePdf();
        return File(pdf, "application/pdf", $"ScoresByEvent_{tournamentId}.pdf");
    }

    [HttpGet]
    public async Task<IActionResult> StudentPointsPdf(int tournamentId, int? schoolId, int? zoneId)
    {
        var report = await _reportService.GetStudentPointsAsync(tournamentId, schoolId, zoneId);
        var tournament = await _tournamentService.GetByIdAsync(tournamentId);
        var document = new StudentPointsDocument(report, tournament?.Name ?? "Tournament");
        var pdf = document.GeneratePdf();
        return File(pdf, "application/pdf", $"StudentPoints_{tournamentId}.pdf");
    }
}
