using Asp.Versioning;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupDetails;
using Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupList;
using Mirea.Api.Dto.Responses;
using Mirea.Api.Endpoint.Common.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace Mirea.Api.Endpoint.Controllers.V1;

[ApiVersion("1.0")]
[CacheMaxAge(true)]
public class GroupController(IMediator mediator) : BaseController
{
    private static int GetCourseNumber(string groupName)
    {
        var current = DateTime.Now;
        if (!int.TryParse(groupName[2..], out var yearOfGroup)
            && !int.TryParse(groupName.Split('-')[^1][..2], out yearOfGroup))
            return -1;

        // Convert a two-digit year to a four-digit one
        yearOfGroup += current.Year / 100 * 100;

        return current.Year - yearOfGroup + (current.Month < 8 ? 0 : 1);
    }

    /// <summary>
    /// Retrieves a list of groups.
    /// </summary>
    /// <param name="page">The page number for pagination (optional).</param>
    /// <param name="pageSize">The page size for pagination (optional).</param>
    /// <returns>A list of groups.</returns>
    [HttpGet]
    [BadRequestResponse]
    public async Task<ActionResult<List<GroupResponse>>> Get([FromQuery][Range(0, int.MaxValue)] int? page,
        [FromQuery][Range(1, int.MaxValue)] int? pageSize)
    {
        var result = await mediator.Send(new GetGroupListQuery()
        {
            Page = page,
            PageSize = pageSize
        });

        return Ok(result.Groups
            .Select(g => new GroupResponse()
            {
                Id = g.Id,
                Name = g.Name,
                FacultyId = g.FacultyId,
                CourseNumber = GetCourseNumber(g.Name)
            })
        );
    }

    /// <summary>
    /// Retrieves detailed information about a specific group.
    /// </summary>
    /// <param name="id">The ID of the group to retrieve.</param>
    /// <returns>Detailed information about the group.</returns>
    [HttpGet("{id:int}")]
    [BadRequestResponse]
    [NotFoundResponse]
    public async Task<ActionResult<GroupDetailsResponse>> GetDetails(int id)
    {
        var result = await mediator.Send(new GetGroupInfoQuery()
        {
            Id = id
        });

        return Ok(new GroupDetailsResponse()
        {
            Id = result.Id,
            Name = result.Name,
            FacultyId = result.FacultyId,
            FacultyName = result.Faculty,
            CourseNumber = GetCourseNumber(result.Name)
        });
    }

    /// <summary>
    /// Retrieves a list of groups by faculty ID.
    /// </summary>
    /// <param name="id">The ID of the faculty.</param>
    /// <returns>A list of groups belonging to the specified faculty.</returns>
    [HttpGet("GetByFaculty/{id:int}")]
    [BadRequestResponse]
    [NotFoundResponse]
    public async Task<ActionResult<List<GroupResponse>>> GetByFaculty(int id)
    {
        var result = await mediator.Send(new GetGroupListQuery());

        return Ok(result.Groups
            .Where(g => g.FacultyId == id)
            .Select(g => new GroupResponse()
            {
                Id = g.Id,
                Name = g.Name,
                CourseNumber = GetCourseNumber(g.Name),
                FacultyId = g.FacultyId
            }));
    }
}