using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SportsDivision.Application.DTOs;
using SportsDivision.Application.Interfaces;

namespace SportsDivision.Web.Controllers;

[Authorize]
public class RegistrationController : Controller
{
    private readonly IRegistrationService _registrationService;
    private readonly ITournamentService _tournamentService;
    private readonly IStudentService _studentService;

    public RegistrationController(
        IRegistrationService registrationService,
        ITournamentService tournamentService,
        IStudentService studentService)
    {
        _registrationService = registrationService;
        _tournamentService = tournamentService;
        _studentService = studentService;
    }

    public async Task<IActionResult> Index(int tournamentEventLevelId)
    {
        var registrations = await _registrationService.GetByTournamentEventLevelAsync(tournamentEventLevelId);
        ViewBag.TournamentEventLevelId = tournamentEventLevelId;

        return View(registrations);
    }

    [HttpGet]
    public async Task<IActionResult> Register(int tournamentEventLevelId, int? studentId)
    {
        var students = await _studentService.GetAllAsync();
        ViewBag.Students = students;
        ViewBag.TournamentEventLevelId = tournamentEventLevelId;

        if (studentId.HasValue)
        {
            var eligibility = await _registrationService.CheckEligibilityAsync(tournamentEventLevelId, studentId.Value);
            ViewBag.IsEligible = eligibility.IsEligible;
            ViewBag.EligibilityReason = eligibility.Reason;
            ViewBag.SelectedStudentId = studentId.Value;
        }

        var dto = new EventRegistrationCreateDto
        {
            TournamentEventLevelId = tournamentEventLevelId,
            StudentId = studentId
        };

        return View(dto);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Register(EventRegistrationCreateDto dto)
    {
        if (!ModelState.IsValid)
        {
            var students = await _studentService.GetAllAsync();
            ViewBag.Students = students;
            ViewBag.TournamentEventLevelId = dto.TournamentEventLevelId;
            return View(dto);
        }

        try
        {
            var registeredBy = User.Identity?.Name ?? "Unknown";
            await _registrationService.RegisterStudentAsync(dto, registeredBy);
            TempData["SuccessMessage"] = "Student registered successfully.";
            return RedirectToAction(nameof(Index), new { tournamentEventLevelId = dto.TournamentEventLevelId });
        }
        catch (KeyNotFoundException)
        {
            return NotFound();
        }
        catch (InvalidOperationException ex)
        {
            TempData["ErrorMessage"] = ex.Message;
            var students = await _studentService.GetAllAsync();
            ViewBag.Students = students;
            ViewBag.TournamentEventLevelId = dto.TournamentEventLevelId;
            return View(dto);
        }
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Unregister(int eventRegistrationId, int tournamentEventLevelId)
    {
        try
        {
            await _registrationService.UnregisterAsync(eventRegistrationId);
            TempData["SuccessMessage"] = "Registration removed successfully.";
        }
        catch (KeyNotFoundException)
        {
            return NotFound();
        }
        catch (InvalidOperationException ex)
        {
            TempData["ErrorMessage"] = ex.Message;
        }

        return RedirectToAction(nameof(Index), new { tournamentEventLevelId });
    }

    [HttpGet]
    public async Task<IActionResult> ByStudent(int studentId)
    {
        try
        {
            var student = await _studentService.GetByIdAsync(studentId);
            if (student == null)
            {
                return NotFound();
            }

            var registrations = await _registrationService.GetByStudentAsync(studentId);
            ViewBag.Student = student;

            return View(registrations);
        }
        catch (KeyNotFoundException)
        {
            return NotFound();
        }
    }
}
