using TechHelper.Client.AuthProviders;
using Entities.DTO;
using Microsoft.AspNetCore.Components.Authorization;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Net;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.JSInterop;

namespace TechHelper.Client.HttpRepository
{
	public class AuthenticationClientService : IAuthenticationClientService
	{
		private readonly HttpClient _client;
		private readonly JsonSerializerOptions _options =
			new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
		private readonly AuthenticationStateProvider _stateProvider;
		private readonly ILocalStorageService _localStorageService;
		private readonly NavigationManager _navigationManager;

		public AuthenticationClientService(HttpClient client, 
			AuthenticationStateProvider authenticationStateProvider,
			ILocalStorageService localStorageService,
			NavigationManager navigationManager)
		{
			_client = client; 
			_localStorageService = localStorageService;
			_stateProvider = authenticationStateProvider;
			_navigationManager = navigationManager;
		}

		public async Task<AuthResponseDto> LoginAsync(UserForAuthenticationDto userForAuthenticationDto)
		{
			var reponse = await _client.PostAsJsonAsync("account/login",
				userForAuthenticationDto);

			var content = await reponse.Content.ReadAsStringAsync();

			var result = JsonSerializer.Deserialize<AuthResponseDto>(content, _options);

			if (!reponse.IsSuccessStatusCode || result.Is2StepVerificationRequired)
				return result;

			_localStorageService.SetItem("authToken", result.Token);
			_localStorageService.SetItem("refreshToken", result.RefreshToken);
			((AuthStateProvider)_stateProvider).NotifyUserAuthentication(
				result.Token);

			// 直接在注入的 _client 实例上设置默认请求头
			_client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(
				"bearer", result.Token);

			return new AuthResponseDto { IsAuthSuccessful = true };
		}

		public async Task LogoutAsync()
		{
			// 移除 using (_client = _clientFactory.CreateClient("Default"))
			_localStorageService.RemoveItem("authToken");
			_localStorageService.RemoveItem("refreshToken");
			((AuthStateProvider)_stateProvider).NotifyUserLogout();

			// 直接在注入的 _client 实例上清除默认请求头
			_client.DefaultRequestHeaders.Authorization = null;
		}

		public async Task<string> RefreshTokenAsync()
		{
			var token = _localStorageService.GetItem<string>("authToken");
			var refreshToken = _localStorageService.GetItem<string>("refreshToken");

			var response = await _client.PostAsJsonAsync("token/refresh",
				new RefreshTokenDto
				{
					Token = token,
					RefreshToken = refreshToken
				});

			var content = await response.Content.ReadAsStringAsync();
			var result = JsonSerializer.Deserialize<AuthResponseDto>(content, _options);

			_localStorageService.SetItem("authToken", result.Token);
			_localStorageService.SetItem("refreshToken", result.RefreshToken);

			// 直接在注入的 _client 实例上设置默认请求头
			_client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", result.Token);

			return result.Token;
		}

		public async Task<ResponseDto> RegisterUserAsync(UserForRegistrationDto userForRegistrationDto)
		{
			//userForRegistrationDto.ClientURI = Path.Combine(
			//	_navigationManager.BaseUri, "emailconfirmation");

			var reponse = await _client.PostAsJsonAsync("account/register",
				userForRegistrationDto);

			if (!reponse.IsSuccessStatusCode)
			{
				var content = await reponse.Content.ReadAsStringAsync();
				var result = JsonSerializer.Deserialize<ResponseDto>(content, _options);
				return result;
			}

			return new ResponseDto { IsSuccessfulRegistration = true };
		}

		public async Task<HttpStatusCode> ForgotPasswordAsync(ForgotPasswordDto forgotPasswordDto)
		{
			// 移除 using (_client = _clientFactory.CreateClient("Default"))
			forgotPasswordDto.ClientURI = Path.Combine(_navigationManager.BaseUri, "resetpassword");
			var result = await _client.PostAsJsonAsync("account/forgotpassword",
				forgotPasswordDto);

			return result.StatusCode;
		}

		public async Task<ResetPasswordResponseDto> ResetPasswordAsync(ResetPasswordDto resetPasswordDto)
		{
			// 移除 using (_client = _clientFactory.CreateClient("Default"))
			var resetresult = await _client.PostAsJsonAsync("account/resetpassword",
				resetPasswordDto);

			var resetContent = await resetresult.Content.ReadAsStringAsync();
			var result = JsonSerializer.Deserialize<ResetPasswordResponseDto>(resetContent, _options);

			return result;
		}

		public async Task<HttpStatusCode> EmailConfirmationAsync(string email, string token)
		{
			var queryStringParam = new Dictionary<string, string>
			{
				["email"] = email,
				["token"] = token
			};
			// 移除 using (_client = _clientFactory.CreateClient("Default"))
			var response = await _client.GetAsync(QueryHelpers.AddQueryString(
				"account/emailconfirmation", queryStringParam));

			return response.StatusCode;
		}

		public async Task<AuthResponseDto> LoginVerfication(TwoFactorVerificationDto twoFactorVerificationDto)
		{
			// 移除 using (_client = _clientFactory.CreateClient("Default"))
			var reponse = await _client.PostAsJsonAsync("account/twostepverification",
				twoFactorVerificationDto);

			var content = await reponse.Content.ReadAsStringAsync();

			var result = JsonSerializer.Deserialize<AuthResponseDto>(content, _options);

			if (!reponse.IsSuccessStatusCode)
				return result;

			_localStorageService.SetItem("authToken", result.Token);
			_localStorageService.SetItem("refreshToken", result.RefreshToken);
			((AuthStateProvider)_stateProvider).NotifyUserAuthentication(
				result.Token);


			

			_client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(
				"bearer", result.Token);

			return new AuthResponseDto { IsAuthSuccessful = true };
		}
	}
}