using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NPetrovich;
using Otchinslator.Services;

namespace Otchinslator;

[ApiController]
[Authorize]
public class StatementController(IStatementGenerator statementGenerator, IConfiguration configuration, DatabaseContext db) : Controller
{
    [HttpPost("/generateStatement")]
    public async Task<IActionResult> GenerateStatement(UserDTO userDto)
    {
        var speciality = userDto.typeOfEducation switch
        {
            1 => SpecialityType.Bakalavriat,
            2 => SpecialityType.Magistatura,
            3 => SpecialityType.Specialitet,
            _ => throw new ArgumentOutOfRangeException() // Модель валидации не позволит передать некорректное значение
        };

        if (speciality == SpecialityType.Bakalavriat && userDto.kurs > 4)
        {
            Utils.LogToTg("Походу ломают `SpecialityType.Bakalavriat && userDto.kurs > 4`", configuration);
            return BadRequest("Некорректный курс для бакалавриата");
        }

        if (speciality == SpecialityType.Magistatura && userDto.kurs > 2)
        {
            Utils.LogToTg("Походу ломают `SpecialityType.Magistatura && userDto.kurs > 2`", configuration);
            return BadRequest("Некорректный курс для магистратуры");
        }

        var userEmail = User.Identity.Name;
        var userFIO = User.Claims.FirstOrDefault(x => x.Type == "name")?.Value;
        
        var petrovich = new Petrovich()
        {
            FirstName = userFIO.Split(' ')[0],
            LastName = userFIO.Split(' ')[1],
            MiddleName = userFIO.Split(' ').Length > 2 ? userFIO.Split(' ')[2] : "",
            Gender = Gender.Male
        };
    
        userFIO = petrovich.InflectFirstNameTo(Case.Genitive) + " " + petrovich.InflectLastNameTo(Case.Genitive) + " " + petrovich.InflectMiddleNameTo(Case.Genitive);
        
        var direction = db.Specialties.FirstOrDefault(x => x.Id == userDto.direction);
        if (direction == null)
        {
            Utils.LogToTg("Походу ломают `direction == null`", configuration);
            return BadRequest("Некорректное направление");
        }
        
        var userData = new UserData
        {
            reason = userDto.reason,
            email = userEmail,
            phone = userDto.phone,
            fio = userFIO,
            kurs = userDto.kurs,
            isFreeEducation = userDto.isFreeEducation,
            isOchno = userDto.isOchno,
            speciality = speciality,
            direction = direction.Code + " " + direction.Name.ToLower()
        };
        var statement = await statementGenerator.GenerateStatementAsync(userData);
        var pdf = await statementGenerator.ConvertToPDFAsync(statement);

        await using var fileStream = new FileStream("./PDFCache/" + userEmail.Split('@')[0] + ".pdf", FileMode.Create, FileAccess.Write);
        await pdf.CopyToAsync(fileStream);
        
        return Ok();
    }
    
    [HttpGet("/getStatement")]
    public async Task<IActionResult> GetStatement()
    {
        var userEmail = User.Identity.Name;
        var filePath = "./PDFCache/" + userEmail.Split('@')[0] + ".pdf";
        if (!System.IO.File.Exists(filePath))
            return NotFound("File not found");
        
        var outStream = new MemoryStream();
        await using var file = System.IO.File.OpenRead(filePath);
        await file.CopyToAsync(outStream);
        outStream.Position = 0;
        return File(outStream, "application/pdf");
    }

}