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

namespace SportsDivision.Web.Controllers;

[Authorize]
public class StudentController : Controller
{
    private readonly IStudentService _studentService;
    private readonly ISchoolService _schoolService;

    public StudentController(IStudentService studentService, ISchoolService schoolService)
    {
        _studentService = studentService;
        _schoolService = schoolService;
    }

    public async Task<IActionResult> Index(int? schoolId, string? search, int page = 1, int pageSize = PaginationHelper.PageSize)
    {
        IEnumerable<StudentDto> students;

        if (!string.IsNullOrWhiteSpace(search))
        {
            students = await _studentService.SearchAsync(search);
        }
        else if (schoolId.HasValue)
        {
            students = await _studentService.GetBySchoolAsync(schoolId.Value);
        }
        else
        {
            students = await _studentService.GetAllAsync();
        }

        await PopulateSchoolsViewBag();
        ViewBag.SelectedSchoolId = schoolId;
        ViewBag.SearchTerm = search;

        return View(this.Page(students, page, pageSize));
    }

    public async Task<IActionResult> Details(int id)
    {
        try
        {
            var student = await _studentService.GetByIdAsync(id);
            if (student == null)
            {
                return NotFound();
            }

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

    [HttpGet]
    public async Task<IActionResult> Create()
    {
        await PopulateSchoolsViewBag();
        return View(new StudentCreateDto());
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(StudentCreateDto dto)
    {
        if (!ModelState.IsValid)
        {
            await PopulateSchoolsViewBag();
            return View(dto);
        }

        try
        {
            await _studentService.CreateAsync(dto);
            TempData["SuccessMessage"] = "Student created successfully.";
            return RedirectToAction(nameof(Index));
        }
        catch (InvalidOperationException ex)
        {
            TempData["ErrorMessage"] = ex.Message;
            await PopulateSchoolsViewBag();
            return View(dto);
        }
    }

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

            var dto = new StudentUpdateDto
            {
                StudentId = student.StudentId,
                ExistingStudentId = student.ExistingStudentId,
                FirstName = student.FirstName,
                LastName = student.LastName,
                DateOfBirth = student.DateOfBirth,
                Sex = student.Sex,
                SchoolId = student.SchoolId,
                IsActive = student.IsActive
            };

            await PopulateSchoolsViewBag();
            return View(dto);
        }
        catch (KeyNotFoundException)
        {
            return NotFound();
        }
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(StudentUpdateDto dto)
    {
        if (!ModelState.IsValid)
        {
            await PopulateSchoolsViewBag();
            return View(dto);
        }

        try
        {
            await _studentService.UpdateAsync(dto);
            TempData["SuccessMessage"] = "Student updated successfully.";
            return RedirectToAction(nameof(Index));
        }
        catch (KeyNotFoundException)
        {
            return NotFound();
        }
        catch (InvalidOperationException ex)
        {
            TempData["ErrorMessage"] = ex.Message;
            await PopulateSchoolsViewBag();
            return View(dto);
        }
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Delete(int id)
    {
        try
        {
            await _studentService.DeleteAsync(id);
            TempData["SuccessMessage"] = "Student deleted successfully.";
        }
        catch (KeyNotFoundException)
        {
            return NotFound();
        }
        catch (InvalidOperationException ex)
        {
            TempData["ErrorMessage"] = ex.Message;
        }

        return RedirectToAction(nameof(Index));
    }

    private async Task PopulateSchoolsViewBag()
    {
        var schools = await _schoolService.GetAllAsync();
        ViewBag.Schools = schools;
    }
}
