using Microsoft.AspNetCore.Components;
using System.IdentityModel.Tokens.Jwt;
using System.Text.Json;
using TIAMWebApp.Shared.Application.Models.ClientSide;
using TIAMWebApp.Shared.Application.Models;
using TIAMWebApp.Shared.Application.Interfaces;
using TIAMWebApp.Shared.Application.Utility;
using Microsoft.JSInterop;
using AyCode.Interfaces.StorageHandlers;
using System.ComponentModel.DataAnnotations;
using TIAMSharedUI.Resources;
using System.Resources;
using Microsoft.Extensions.Localization;
using AyCode.Blazor.Components;
using AyCode.Core.Logger;
using Azure.Core;

namespace TIAMSharedUI.Pages
{
    public partial class Login : ComponentBase
    {
        
        [Inject]
        public NavigationManager navManager { get; set; }
        [Inject]
        public IUserDataService userDataService { get; set; }
        [Inject]
        public LogToBrowserConsole logToBrowserConsole { get; set; }
        [Inject]
        public IJSRuntime jsRuntime { get; set; }
        [Inject]
        public ISecureStorageHandler secureStorageHandler { get; set; }
        [Inject]
        public IStringLocalizer<MyResources> localizer { get; set; }
        [Inject]
        public ISessionService sessionService { get; set; }
        
        //fill loginmodel with fake but valid data
        
        //LoginModel loginModel = new();

        //[Display(Name = "LoginTitleText", ResourceType = typeof(MyResources))]
        public string TitleText { get; set; } = "dda,mnd,amn,a";
        private int currentStep = 1;
        bool loggedIn = false;


        private void GoToNextStep()
        {
            currentStep++;
        }

        private void GoToPreviousStep()
        {
            currentStep--;
        }

        private async void SubmitLogin()
        {
            currentStep = 1;
            logToBrowserConsole.LogToBC("Login started: " + "Email: " + loginModel.Email + ", Password: " + loginModel.Password);
            var response = await userDataService.AuthenticateUser(loginModel);
            //var response = await UserDataservice.TestUserApi(30);
            logToBrowserConsole.LogToBC("Login started");
            logToBrowserConsole.LogToBC(response);

            if (!string.IsNullOrEmpty(response))
            {
                //get token and save to local storage
                //parse to Mainresponse from json string


                //var Mainresponse = JsonSerializer.Deserialize<MainResponse>(response);
                var Mainresponse = JsonSerializer.Deserialize<MainResponse>(response, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

                if (Mainresponse != null)
                {

                    //check for bad request
                    //TODO: fix hacky solution
                    string AuthResponseJson = JsonSerializer.Serialize(Mainresponse.Content);

                    var AuthResponse = JsonSerializer.Deserialize<AuthenticationResponse>(AuthResponseJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

                    string accessToken = AuthResponse.AccessToken;

                    var token = ProcessToken(accessToken);

                    string _userId = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.NameId).Value;
                    string _email = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.Email).Value;

                    var myId = Guid.Parse(_userId);
                    //userDataService.User.Email = _email;

                    var userBasicDetails = new UserBasicDetails(_userId, _email, AuthResponse.AccessToken, AuthResponse.RefreshToken);

                    string userBasicDetailsJson = JsonSerializer.Serialize(userBasicDetails);


                    //save to local storage
                    await secureStorageHandler.SaveToSecureStorageAsync(nameof(Setting.UserBasicDetails), userBasicDetailsJson);

                    
                    

                    if (!Mainresponse.IsSuccess)
                    {
                        //await App.Current.MainPage.DisplayAlert("Error", "Invalid credentials", "Ok");
                        //display error message via jsinterop
                        logToBrowserConsole.LogToBC("Invalid credentials");
                        navManager.NavigateTo("login");
                    }
                    else
                    {
                        //await App.Current.MainPage.DisplayAlert("Success", "Successful login", "Ok");
                        //display success message via jsinterop
                        logToBrowserConsole.LogToBC("Successful login");
                        var user = await userDataService.IsLoggedInAsync(myId);
                        SaveToSessionInfo(user);
                        user.UserType = UserType.Admin;
                        navManager.NavigateTo("index");
                    }

                }

            }
            else
            {
                //api error
                //await App.Current.MainPage.DisplayAlert("Error", "An error occured while trying to login", "Ok");
                //display error message via jsinterop
                logToBrowserConsole.LogToBC("An error occured while trying to login");
                navManager.NavigateTo("login");
            }

        }

        protected override void OnInitialized()
        {
                        
            base.OnInitialized();
            if(sessionService.IsAuthenticated)
            {
                navManager.NavigateTo("index");
            }
            
        }

        public JwtSecurityToken ProcessToken(string accessToken)
        {
            var handler = new JwtSecurityTokenHandler();
            var token = handler.ReadJwtToken(accessToken) as JwtSecurityToken;
            return token;
        }
        /// <summary>
        /// This method stores the user data in the session service so we know during navigation that the user is logged in.
        /// </summary>
        /// <param name="user"></param>
        protected void SaveToSessionInfo(UserSessionModel user)
        {
            sessionService.User = user;
            sessionService.IsAuthenticated = true;
        }
    }
}
