using ASP.Back.Libraries;
using Microsoft.AspNetCore.Mvc;
using System;
using TeamManiacs.Core.Enums;
using TeamManiacs.Core.Models;
using TeamManiacs.Data;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace ASP.Back.Controllers
{   
    
    [Route("api/[controller]")]
    [ApiController]
    public class AuthCodeController : ControllerBase
    {
        private readonly TeamManiacsDbContext _context;
        private static Emailer? _emailer;
        public AuthCodeController(TeamManiacsDbContext context, IWebHostEnvironment hostEnvironment , Emailer emailer)
        {
            _context = context;
            _emailer = emailer;
        }


        // POST api/<ValuesController>
        [HttpPut]
        public async Task<IActionResult> Put([FromBody] AuthCode usersCode)
        {
            //Put Auth Code to server. If code is valid and user is inactive, user will be activated. 

            AuthCode? ourCode =  _context.AuthCodes.FirstOrDefault(x=> x.Uid == usersCode.Uid && x.Type == usersCode.Type);
            if (ourCode == null)
            {
                return NotFound();
            }

            if(ourCode.Code != usersCode.Code)
            {
                return BadRequest();
            }

            switch(usersCode.Type)
            {
                case CodeType.Signup:
                    {
                        await Delete(ourCode);
                        Users? users = await _context.UserModels.FindAsync(usersCode.Uid);

                        if (users == null)
                        {
                            return NotFound();
                        }
                        if (users.Status != TeamManiacs.Core.Enums.UserStatus.inactive)
                        {
                            return BadRequest();
                        }
                        users.Status = TeamManiacs.Core.Enums.UserStatus.active;
                    }
                    break;
                case CodeType.PwdReset:
                    {
                        return StatusCode(200, new { Message = "Good Code" });
                    }
                default:
                    return BadRequest();
                    
            }

            await _context.SaveChangesAsync();

            return Ok();
        }

        // PUT api/<ValuesController>/[AuthCode]
        [HttpPost]
        public async Task<IActionResult> Post([FromBody] AuthCode usersCode)
        {
            //I should make sure we have an email also submitted here to prevent spamming. 
            if (_emailer == null)
            {
                return BadRequest();
            }
            //Generate a new code, if user is not inactive, code will not be generated. 
            Users? user = await _context.UserModels.FindAsync(usersCode.Uid);

            if(user == null)
            {
                return NotFound();
            }    

            if(user.Status != TeamManiacs.Core.Enums.UserStatus.inactive)
            {
                return BadRequest();
            }

            _context.AuthCodes.Remove(usersCode);
            //Make sure we don't already have an existing code...
            AuthCode? ourCode = _context.AuthCodes.FirstOrDefault(x => x.Uid == usersCode.Uid && x.Type == usersCode.Type);
            //if we do Delete it!
            if (ourCode != null)
            {
                await Delete(ourCode);
            }

            //Generate code
            AuthCode authCode = ControllerHelpers.GenerateAuthCode(user.UserId);
            authCode.Type = usersCode.Type;
            if (authCode == null)
            {
                return BadRequest();
            }
            
            await _context.AuthCodes.AddAsync(authCode);

            await _context.SaveChangesAsync();
            _emailer.SendTwoFactorEmail(user.Email, authCode.Code);


            return Ok();
        }

        private async Task<int> Delete(AuthCode usersCode)
        {    
            _context.AuthCodes.Remove(usersCode);

            return await _context.SaveChangesAsync();
        }
    }
}
