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

namespace SportsDivision.Web.Controllers;

[Authorize]
public class SchoolController : Controller
{
    private readonly ISchoolService _schoolService;
    private readonly IUnitOfWork _unitOfWork;

    public SchoolController(ISchoolService schoolService, IUnitOfWork unitOfWork)
    {
        _schoolService = schoolService;
        _unitOfWork = unitOfWork;
    }

    public async Task<IActionResult> Index(int? zoneId, SchoolLevel? level, int page = 1, int pageSize = PaginationHelper.PageSize)
    {
        IEnumerable<SchoolDto> schools;

        if (zoneId.HasValue)
        {
            schools = await _schoolService.GetByZoneAsync(zoneId.Value);
        }
        else if (level.HasValue)
        {
            schools = await _schoolService.GetBySchoolLevelAsync(level.Value);
        }
        else
        {
            schools = await _schoolService.GetAllAsync();
        }

        await PopulateZonesViewBag();
        ViewBag.SelectedZoneId = zoneId;
        ViewBag.SelectedLevel = level;

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

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

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

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

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

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

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

            var dto = new SchoolUpdateDto
            {
                SchoolId = school.SchoolId,
                Name = school.Name,
                ShortName = school.ShortName,
                SchoolLevel = school.SchoolLevel,
                ZoneId = school.ZoneId,
                IsActive = school.IsActive
            };

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

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

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

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

        return RedirectToAction(nameof(Index));
    }

    private async Task PopulateZonesViewBag()
    {
        var zones = await _unitOfWork.Zones.GetAllAsync();
        ViewBag.Zones = zones.Select(z => new ZoneDto
        {
            ZoneId = z.ZoneId,
            Name = z.Name,
            Code = z.Code,
            IsActive = z.IsActive
        });
    }
}
