using Microsoft.AspNetCore.Mvc;
using BoredCareers.Services.DatabaseService;
using BoredCareers.Entities;
using BoredCareers.Services;

namespace BoredCareers.Controllers {
    [ApiController]
    [Route("api/company")]
    public class CompanyController : MistoxControllerBase {

        EmailService _emailContext;

        public CompanyController(DatabaseService db, EmailService emailContext) : base(db) {
            _emailContext = emailContext;
        }

        [HttpGet]
        public async Task<IActionResult> GetCompany(int CompanyID) {
            Company? company = await _databaseService.GetCompany(CompanyID);
            if (company != null) {
                company.EmailToken = "";
                return Ok(company);
            }
            return NotFound("Company doesn't exist");
        }

        [HttpPost]
        public async Task<IActionResult> SetCompany([FromBody] Company company) {
            if (isLoggedIn()) {
                Company? test = await _databaseService.GetCompany(Convert.ToInt32(company.ID));
                if (test == null) {
                    company.ID = await _databaseService.SetCompany(company);

                    await _databaseService.SetEmployee(new Employee() {
                        AccountID = getLoggedInUserID(),
                        AccountName = getLoggedInUser().UserName,
                        AccountEmail = getLoggedInUser().Email,
                        Company = company
                    });
                    await SendVerify(Convert.ToInt32(company.ID));
                    return Ok();
                } else {
                    if (await isLoggedInUserEmployeeOf(Convert.ToInt32(company.ID))) {
                        if (company.Email != test.Email) {
                            company.EmailVerified = false;
                        }
                        await _databaseService.SetCompany(company);
                        return Ok();
                    }
                    return NotFound("You are not an employee of company");
                }
            }
            return NotFound("Not logged in");
        }

        [HttpDelete]
        public async Task<IActionResult> DeleteCompany(int CompanyID) {
            if (isLoggedIn()) {
                if (await isLoggedInUserEmployeeOf(CompanyID)) {
                    await _databaseService.DeleteCompany(CompanyID);
                    return Ok();
                }
                return NotFound("You are not an employee of company");
            }
            return NotFound("Not logged in");
        }

        [HttpGet("sendverifyemail")]
        public async Task<ActionResult> SendVerify([FromQuery] int CompanyID) {
            try {
                string key = "v" + CompanyID;
                // Stop from sending multiple emails quickly
                if (_emailContext._SentEmails.ContainsKey(key)) {
                    DateTime PreviousSentTime = _emailContext._SentEmails.GetValueOrDefault(key);
                    if (PreviousSentTime.AddMinutes(5) > DateTime.Now) {
                        return NotFound("Cannot sent another verify email until 5 minutes has elapsed");
                    } else {
                        _emailContext._SentEmails.Remove(key);
                    }
                }
                Company? test = await _databaseService.GetCompany(CompanyID);
                if (test != null) {
                    test.EmailToken = Guid.NewGuid().ToString();
                    await _databaseService.SetCompany(test);

                    string EmailContents = EmailService.CompanyVerifyEmailBody;
                    EmailContents = Substitue(EmailContents, "@CompanyName", test.Name);
                    EmailContents = Substitue(EmailContents, "@ID", CompanyID.ToString());
                    EmailContents = Substitue(EmailContents, "@VerifyPassword", test.EmailToken);

                    string result = await _emailContext.Send(test.Email, EmailService.CompanyVerifyEmailSubject, EmailContents);
                    _emailContext._SentEmails.Add(key, DateTime.Now);
                    return Redirect("/");
                }
                return NotFound("Account not found");
            } catch (Exception) {
                return NotFound("An internal server error has occured");
            }
        }

        [HttpGet("verifyemail")]
        public async Task<ActionResult> VerifyEmail([FromQuery] int CompanyID, [FromQuery] string EmailToken) {
            try {
                Company? test = await _databaseService.GetCompany(CompanyID);
                if (test != null) {
                    if (test.EmailToken == EmailToken) {
                        test.EmailToken = "";
                        test.EmailVerified = true;
                        await _databaseService.SetCompany(test);
                        return Redirect("/");
                    }
                    return BadRequest("The token isn't valid");
                }
                return BadRequest("Account not found"); ;
            } catch {
                return BadRequest("An internal server error has occured");
            }
        }

    }
}
