using Microsoft.AspNetCore.Mvc;
using PersonSport.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;          //För autentisering med Claims
using Microsoft.AspNetCore.Authentication.Cookies;  //För autentisering med Claims
using System.Security.Claims;
using System.Text;
using System.Security.Cryptography;
using Microsoft.AspNetCore.Authorization;

namespace PersonSport.Controllers {

    [Authorize]
    public class LoginController : Controller {

        [AllowAnonymous]
        public IActionResult Index() {
            return View();
        }

        public IActionResult ShowAdmins() {
            List<Admin> administratorer = new();

            using (var db = new IdrottContext()) {
                administratorer = db.Administratorer.ToList();
                ViewBag.antal = db.Administratorer.Count();
            }

            return View(administratorer);
        }

        [HttpGet]
        public IActionResult CreateAdmin() {
            return View();
        }

        [HttpPost]
        public IActionResult CreateAdmin(Admin nyAdmin) {
            try {

                nyAdmin.Password = Sha256_hash(nyAdmin.Password);

                if (ModelState.IsValid) {
                    using (var db = new IdrottContext()) {
                        // Kolla om namnet är upptaget
                        var antal = db.Administratorer.Where(s => s.Username == nyAdmin.Username).Count();
                        if (antal == 0) {
                            db.Add(nyAdmin);
                            db.SaveChanges();
                        }
                        else {
                            TempData["Meddelande"] = "Administratören finns redan. Välj ett annat namn.";
                        }
                    }
                    return RedirectToAction(nameof(ShowAdmins));
                }
            }
            catch (Exception) {
                throw;
            }
            return NotFound();
        }

        public IActionResult DeleteAdmin(int id) {
            var admin = new Admin() { AdminId = id };

            using (var db = new IdrottContext()) {
                int antalAdmins = db.Administratorer.Count();
                if (antalAdmins <= 1) {
                    TempData["TooFewAdmins"] = "Det måste finnas minst 1 Administratör kvar.";
                }
                else {
                    db.Attach(admin);
                    db.Remove(admin);
                    db.SaveChanges();
                }
            }

            return RedirectToAction(nameof(ShowAdmins));
        }

        [HttpGet]
        public IActionResult EditAdmin(int id) {
            Admin ny = new();

            if (ModelState.IsValid) {
                using var db = new IdrottContext(); var admin = db.Administratorer.Where(p => p.AdminId == id).FirstOrDefault();
                ny.AdminId = admin.AdminId;
                ny.Username = admin.Username;
                db.SaveChanges();
            }
            return View(ny);
        }

        [HttpPost]
        public IActionResult EditAdmin(Admin updated) {
            if (ModelState.IsValid) {
                using (var db = new IdrottContext()) {
                    var up = db.Administratorer.Where(p => p.AdminId == updated.AdminId).FirstOrDefault();

                    up.AdminId = updated.AdminId;
                    up.Username = updated.Username;
                    up.Password = Sha256_hash(updated.Password);
                    db.SaveChanges();
                }
                return RedirectToAction(nameof(ShowAdmins));
            }
            return NotFound();
        }

        [AllowAnonymous]
        [HttpPost]
        public async Task<IActionResult> CheckLogin(Admin attKolla, string returnUrl = null) {

            using var db = new IdrottContext();                 // Kolla uppgifterna mot DB
                                                                // Lösenordet krypteras med SHA-256
            var loginAttempt = db.Administratorer.Where(p => p.Username == attKolla.Username && p.Password == Sha256_hash(attKolla.Password)).FirstOrDefault();

            if (loginAttempt == null) {
                // Om de inte stämmer; skicka tillbaka till Login-sidan
                TempData["msg"] = "Inloggningen inte godkänd.";
                TempData["hint"] = "Tips: Testa 'admin' och 'password'";
                return RedirectToAction(nameof(Index));
            }
            else {
                var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
                identity.AddClaim(new Claim(ClaimTypes.Name, attKolla.Username));

                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
                if (returnUrl != null)
                    return Redirect(returnUrl);
                else
                    return RedirectToAction("Index", "Start");
            }
        }

        public async Task<IActionResult> Logout() {
            await HttpContext.SignOutAsync(
                CookieAuthenticationDefaults.AuthenticationScheme);
            return RedirectToAction("Index", "Start");
        }

        [AllowAnonymous]
        public static String Sha256_hash(string value) {
            StringBuilder sb = new();

            using (var hash = SHA256.Create()) {
                Encoding enc = Encoding.UTF8;
                Byte[] result = hash.ComputeHash(enc.GetBytes(value));

                foreach (Byte b in result)
                    sb.Append(b.ToString("x2"));
            }

            return sb.ToString();
        }
    }
}
