using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Management;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
//using IdentityServer4.Test;

//using JwtAuthentication.Server.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using PowerAccounting.Areas.Identity.Data;
using PowerAccounting.Models;
using PowerAccounting.Models2;
using PowerAccounting.MyModels;
//using PowerAccounting.TempModels;
using Webgentle.BookStore.Models;
using Webgentle.BookStore.Repository;

namespace Webgentle.BookStore.Controllers
{
    [Route("api/rigister")]
    [ApiController]
    public class MyAccountController : ControllerBase
    {
        private readonly IAccountRepository _accountRepository;
        private readonly db_a63a88_iprotechContext _context;

        public MyAccountController(IAccountRepository accountRepository, db_a63a88_iprotechContext context)
        {
            _accountRepository = accountRepository;
            _context = context;
            // _accountRepository.SetingsRoles();
        }

        [HttpPost, Route("getalluserroles")]
        public async  Task<IList<string>> GetAllUserRoles([FromBody] PowerAccountingUser userModel)
        {
            return await _accountRepository.GetAllUserRoleAsync(userModel);
        }

        [HttpPost, Route("myactivation")]
        public async Task<IActionResult> MyActivation([FromBody] SignUpUserModel userModel)

        {
            if (userModel is null)
            {
                return BadRequest("Invalid client request");
            }

            if (userModel.Email != "jalal@powerbit.com")
            {
                //userModel.FirstName = "Powerbit";
                //userModel.LastName = "Admin";
                userModel.UserName = "Jalal";
                userModel.Email = "jalal@powerbit.com";
                userModel.Password = "jalal@powerbit.com";
                userModel.ConfirmPassword = "jalal@powerbit.com";
            }

            if (ModelState.IsValid)
                {
                    var result2 = await this._accountRepository.SetingsRoles();
                    if (result2[0].Succeeded)
                    {              
                        var result = await _accountRepository.CreateUserAsync(userModel,true);
                        if (result.Succeeded)
                        {
                        var myModel = new MyRoleModel() { Email = userModel.Email, Password = userModel.Password, Role = "Admin" };
                        var resultRole = await this._accountRepository.SetRoleToUserByMyRoleModelAsync(myModel);
                        if (resultRole.Succeeded)
                        {   
                            await this._context.SaveChangesAsync();
                        }
                       
                            return Ok(new OkResult { });
                        }

                        ModelState.Clear();
                    }
                   
                }
                        
            return BadRequest("I dont know!");
        }

        [HttpPost, Route("mySetUserToRole")]
        public async Task<IActionResult> MySetUserToRoleAsync([FromBody] MyRoleModel userModel)
        {
            if (userModel is null)
            {
                return BadRequest("Invalid client request");
            }

            if (ModelState.IsValid)
            {
                try
                {
                    var result = await this._accountRepository.SetRoleToUserByMyRoleModelAsync(userModel);
                    this._context.SaveChanges();
                    return Ok(new { result });
                }
                catch
                {
                    return BadRequest("catch an error on SaveChanges Function!");
                }
            }

            return BadRequest("I dont know!");
        }

        [HttpPost, Route("myconfirmuser")]
        public IActionResult MyConfirmUser([FromBody] PowerAccountingUser userModel)
        {
            if (userModel is null)
            {
                return BadRequest("Invalid client request");
            }

            if (ModelState.IsValid)
            {
                try
                {
                    //this.db.Users.Find(userModel.Id).EmailConfirmed = userModel.EmailConfirmed;
                    //this.db.SaveChanges();
                    return Ok(new OkResult { });
                }
                catch
                {
                    return BadRequest("catch an error on SaveChanges Function!");
                }          
            }

            return BadRequest("I dont know!");
        }

        [HttpPost,Route("delete")]
        public async Task<IActionResult> Delete([FromBody] PowerAccountingUser userModel)
        {

            if (userModel is null)
            {
                return BadRequest("Invalid client request");
            }

            if (ModelState.IsValid)
            {
                var result = await _accountRepository.DeleteUserByEmailAsync(userModel.Email);
                if (result.Succeeded)
                {
                    return Ok(new OkResult { });
                }
            }
            return BadRequest("Something went wrong.");
        }
        [HttpPost, Route("signup")]
        public async Task<IActionResult> Signup([FromBody] SignUpUserModel userModel)
        {
            if (userModel is null)
            {
                return BadRequest("Invalid client request");
            }

            if (ModelState.IsValid)
            {
                //var testUser = await this._accountRepository.GetUserByEmailAsync("jalal@powerbit.com");
                //if (testUser == null)
                if (true)
                {
                    var result = await _accountRepository.CreateUserAsync(userModel, false);
                    if (result.Succeeded)
                    { 
                        this._context.SaveChanges();
                        return Ok(new OkResult { });
                    }
                }
           
                ModelState.Clear();     
            }
            //return BadRequest("I dont know!");
            return BadRequest("Not Ok!");
        }

     
        [HttpPost, Route("login")]
        public async Task<IActionResult> Login([FromBody] SignInModel signInModel)
        {
            if (signInModel is null)
            {
                return BadRequest("Invalid client request");
            }

            if (ModelState.IsValid)
            {
                var result = await _accountRepository.PasswordSignInAsync(signInModel);
              //  var myUser = await _accountRepository.GetUserByEmailAsync(signInModel.Email);
                if (result.Succeeded)
                {
                    var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@345"));
                    var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);


                    var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, signInModel.Email),
                    new Claim(ClaimTypes.Role, "Manager")
                };

                    var tokeOptions = new JwtSecurityToken(
                        issuer: "https://powerbit.com:51042",
                        audience: "https://powerbit.com:51042",
                        claims: claims,
                        expires: DateTime.Now.AddMinutes(5),
                        signingCredentials: signinCredentials
                    );

                    var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);
                    //  return Ok(new AuthenticatedResponse { Token = tokenString});
                    // return Ok("PasswordSignInAsync:Succeeded");
                    //var myUser = await this._context.UsersData.FindAsync(signInModel.Email);
                    var userDetail = await _accountRepository.GetUserByEmailAsync(signInModel.Email);
                    return Ok(new { Token = tokenString, MyName = ((userDetail.FullName!=null)?userDetail.FullName:userDetail.Email), Image ="" ,MyRole=""});
                }
                if (result.IsNotAllowed)
                {
                   // ModelState.AddModelError("", "Not allowed to login");
                    return Ok("Not allowed to login");
                }
                else if (result.IsLockedOut)
                {
                   // ModelState.AddModelError("", "Account blocked. Try after some time.");
                    return Ok("Account blocked. Try after some time.");
                }
                else
                {
                   // ModelState.AddModelError("", "Invalid credentials");
                    return Ok("Invalid credentials");
                }

            }

            return Unauthorized();
        }

        [HttpGet, Route("logout")]
        public async Task<IActionResult> Logout()
        {
            await _accountRepository.SignOutAsync();
            // return RedirectToAction("Index", "Home");
            return Ok(new OkResult { });
            // return Ok("SignOutAsync");
        }


        [HttpPost, Route("change-password")]
        public async Task<IActionResult> ChangePassword([FromBody] ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {
               

                var result = await _accountRepository.ChangePasswordAsync(model);

                //if (this._context.UsersData.Find(model.Email).Name != model.Name)
                //{
                //    var newUserData = this._context.UsersData.Find(model.Email);
                //    newUserData.Name = model.Name;
                //    this._context.UsersData.Update(newUserData);
                //    await this._context.SaveChangesAsync();
                //}

                if (result.Succeeded)
                {
                   
                    ModelState.Clear();
                      return Ok(new OkResult { });
                   // return Ok(new { myResult = result });
                }
            }
            return BadRequest("Invalid client request");
        }

        [HttpGet("confirm-email")]
        public async Task<IActionResult> ConfirmEmail(string uid, string token, string email)
        {
            EmailConfirmModel model = new EmailConfirmModel
            {
                Email = email
            };

            if (!string.IsNullOrEmpty(uid) && !string.IsNullOrEmpty(token))
            {
                token = token.Replace(' ', '+');
                var result = await _accountRepository.ConfirmEmailAsync(uid, token);
                if (result.Succeeded)
                {
                    model.EmailVerified = true;
                    return Ok(new OkResult { });
                    //  return await this.ConfirmEmail(model);
                    // return Ok(model);
                }
                else return BadRequest("Sorry ,No ConfirmEmail!");
            }
          
            return BadRequest("Invalid client request");
            //return Ok(model);
        }

        [HttpPost("confirm-email")]
        public async Task<IActionResult> ConfirmEmail(EmailConfirmModel model)
        {
            var user = await _accountRepository.GetUserByEmailAsync(model.Email);
            if (user != null)
            {
                if (user.EmailConfirmed)
                {
                    model.EmailVerified = true;
                   // return Ok(model);
                }

                await _accountRepository.GenerateEmailConfirmationTokenAsync(user);
                model.EmailSent = true;
                ModelState.Clear();
            }
            else
            {
                //  ModelState.AddModelError("", "Something went wrong.");
                return BadRequest("Something went wrong.");
            }
            // return Ok(model);
            return Ok(new OkResult { });
        }

     
        [AllowAnonymous, HttpPost("fotgot-password")]
        public async Task<IActionResult> ForgotPassword(ForgotPasswordModel model)
        {
            if (ModelState.IsValid)
            {
                // code here
                var user = await _accountRepository.GetUserByEmailAsync(model.Email);
                if (user != null)
                {
                  await  _accountRepository.GenerateForgotPasswordTokenAsync(user);
                }

                ModelState.Clear();
                model.EmailSent = true;
            }
            return Ok(model);
        }

        [AllowAnonymous, HttpGet("reset-password")]
        public IActionResult ResetPassword(string uid, string token)
        {
            ResetPasswordModel resetPasswordModel = new ResetPasswordModel
            {
                Token = token,
                UserId = uid
            };
            return Ok(resetPasswordModel);
        }

        [AllowAnonymous, HttpPost("reset-password")]
        public async Task<IActionResult> ResetPassword(ResetPasswordModel model)
        {
            if (ModelState.IsValid)
            {
                model.Token = model.Token.Replace(' ', '+');
                var result = await  _accountRepository.ResetPasswordAsync(model);
                if (result.Succeeded)
                {
                    ModelState.Clear();
                    model.IsSuccess = true;
                    return Ok(model);
                }

                return BadRequest("result UnSucceeded!");
            }
            // return Ok(model);
            return BadRequest("Invalid client request");
        }
    }
}
