using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using System;
using System.Net;
using System.Net.Mail;
using System.Threading.Tasks;
using System.Web;
using System.Web.Security;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;

namespace OlympiaIntranet
{
    public partial class SignIn : System.Web.UI.Page
    {
        // ref link: https://docs.microsoft.com/it-it/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project

        private static readonly TimeSpan TwoFATimeout = TimeSpan.FromHours(4);
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        /*
        protected void btnSignIn_Click(object sender, EventArgs e)
        {
            var userStore = new UserStore<IdentityUser>();
            var userManager = new UserManager<IdentityUser>(userStore);
            var user = userManager.Find(txtUserName.Text, txtPassword.Text);
            if (user != null)
            {
                var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                var userIdentity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);

                authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, userIdentity);
                if (user.UserName == "external") Response.Redirect("~/EsposizioneCertificati.aspx");
                else Response.Redirect("~/Default2.aspx");
            }
            else
            {
                // ref link: https://www.codeproject.com/Articles/1091641/Bootstrap-Alert-from-ASP-NET-Server-Side
                lblMsg.Visible = true;
                lblMsg.CssClass = "alert alert-warning alert-dismissible fade show";
                lblMsg.Text = "<i class='fa fa-warning'></i> Credenziali non valide! <button type='button' class='close' data-dismiss='alert'>&times;</button>";
            }
        }
        */

        protected async void btnSignIn_Click(object sender, EventArgs e)
        {
            var userStore = new UserStore<IdentityUser>();
            var userManager = new UserManager<IdentityUser>(userStore);
            var user = userManager.Find(txtUserName.Text, txtPassword.Text);

            if (user != null)
            {
#if DEBUG
        // 🔓 DEBUG MODE: bypass totale della 2FA
        FormsAuthentication.SetAuthCookie(user.UserName, false);
        Response.Redirect("~/Default2.aspx", endResponse: false);
        Context.ApplicationInstance.CompleteRequest();
        return;
#endif
                // 🔁 Controllo cookie 2FA per utenti abilitati
                HttpCookie cookie = Request.Cookies["Last2FA"];
                if (cookie != null && cookie.Values["User"] == user.UserName)
                {
                    DateTime verifiedAt;
                    if (DateTime.TryParse(cookie.Values["VerifiedAt"], out verifiedAt))
                    {
                        if (DateTime.UtcNow - verifiedAt < TwoFATimeout)
                        {
                            FormsAuthentication.SetAuthCookie(user.UserName, false);
                            Response.Redirect("~/Default2.aspx", endResponse: false);
                            Context.ApplicationInstance.CompleteRequest();
                            return;
                        }
                    }
                }

                // Genero un codice OTP (es. 6 cifre)
                var code = GenerateOtp6(); // new Random().Next(100000, 999999).ToString();

                // Salvo il codice in sessione (in produzione meglio DB/Redis)
                Session["2FA_Code"] = code;
                Session["2FA_UserId"] = user.Id;               

                //System.Diagnostics.Debug.WriteLine("SET SessionID: " + Session.SessionID); // per debug

                // Invia il codice via email (o SMS)
                userManager.EmailService = new EmailService();
                await userManager.SendEmailAsync(user.Id, "Olympia Intranet - Il tuo codice di verifica 2FA", "Il tuo codice 2FA è: " + code);

                // Vai alla pagina di verifica
                Response.Redirect("~/Verify2FA.aspx", endResponse: false);
                Context.ApplicationInstance.CompleteRequest();
            }
            else
            {
                lblMsg.Visible = true;
                lblMsg.CssClass = "alert alert-warning alert-dismissible fade show";
                lblMsg.Text = "<i class='fa fa-warning'></i> Credenziali non valide!";
            }
        }

        private static string GenerateOtp6()
        {
            using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider())
            {
                byte[] randomNumber = new byte[4];
                rng.GetBytes(randomNumber);

                // Converto in intero positivo
                int value = Math.Abs(BitConverter.ToInt32(randomNumber, 0));

                // Riduco al range 0–999999
                int otp = value % 1_000_000;

                return otp.ToString("D6"); // sempre 6 cifre (es. 000123)
            }
        }

        public class EmailService : IIdentityMessageService
        {
            public async Task SendAsync(IdentityMessage message)
            {
                using (var mail = new MailMessage())
                {
                    mail.From = new MailAddress("robot@olympia-wealth.com"); // deve essere un indirizzo valido in O365
                    mail.To.Add(message.Destination);
                    mail.Subject = message.Subject ?? "Codice di sicurezza";
                    mail.Body = message.Body ?? "Il tuo codice 2FA";

                    using (var smtp = new SmtpClient("smtp.office365.com", 587))
                    {
                        smtp.EnableSsl = true; // STARTTLS obbligatorio
                        smtp.Credentials = new NetworkCredential("robot@olympia-wealth.com", "Van60356");
                        smtp.Timeout = 20000; // 20 secondi

                        await smtp.SendMailAsync(mail);
                    }
                }
            }
        }
    }
}