@using Microsoft.Extensions.Localization
@using AliasVault.RazorComponents.Services
@using AliasVault.Client.Main.Components.Shared
@using AliasVault.Client.Main.Components.Layout
@using AliasVault.Client.Auth.Components
@using AliasVault.Client.Main.Constants
@using System.Timers
@inject IStringLocalizerFactory LocalizerFactory
@implements IDisposable

<FormModal
    IsOpen="@IsOpen"
    Title="@Title"
    MaxWidth="md"
    ShowDefaultFooter="false"
    OnClose="@OnClose"
    SubmitOnEnter="false">
    <Icon>
        <svg class="h-6 w-6 text-orange-600 dark:text-orange-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5" />
        </svg>
    </Icon>
    <ChildContent>
        <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">
            @Description
        </p>

        @if (!string.IsNullOrEmpty(ErrorMessage))
        {
            <AlertMessageError Message="@ErrorMessage" HasTopMargin="false" />
        }

        <div class="mb-4">
            <label for="exportPassword" class="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                @Localizer["ExportPasswordLabel"]
            </label>
            <PasswordInputField
                Id="exportPassword"
                @bind-Value="_exportPassword"
                Placeholder=""
                @onkeydown="HandleKeyDown"
                @onfocus="OnPasswordFocus"
                autofocus="true" />

            <PasswordStrengthIndicator Password="@_exportPassword" OnStrengthChanged="@HandleStrengthChanged" />
        </div>

        <div class="mb-4">
            <label for="confirmExportPassword" class="block text-sm font-medium text-gray-900 dark:text-white mb-2">
                @Localizer["ConfirmExportPasswordLabel"]
            </label>
            <PasswordInputField
                Id="confirmExportPassword"
                @bind-Value="_confirmPassword"
                Placeholder=""
                @onkeydown="HandleKeyDown"
                @onfocus="OnPasswordFocus" />
        </div>

        @if (!string.IsNullOrEmpty(_validationError))
        {
            <div class="mt-2 text-sm text-red-600 dark:text-red-400">
                @_validationError
            </div>
        }
    </ChildContent>
    <FooterContent>
        <button
            type="button"
            @onclick="HandleSubmit"
            disabled="@(!IsPasswordValid())"
            class="inline-flex w-full justify-center rounded-md bg-primary-600 hover:bg-primary-700 px-3 py-2 text-sm font-semibold text-white shadow-sm sm:w-auto disabled:opacity-50 disabled:cursor-not-allowed">
            @Localizer["CreateEncryptedExportButton"]
        </button>
        <button
            type="button"
            @onclick="OnClose"
            class="mt-3 inline-flex w-full justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:mt-0 sm:w-auto dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:hover:bg-gray-600">
            @SharedLocalizer["Cancel"]
        </button>
    </FooterContent>
</FormModal>

@code {
    [Parameter]
    public bool IsOpen { get; set; }

    [Parameter]
    public string Title { get; set; } = string.Empty;

    [Parameter]
    public string Description { get; set; } = string.Empty;

    [Parameter]
    public string ErrorMessage { get; set; } = string.Empty;

    [Parameter]
    public EventCallback<string> OnPasswordSubmitted { get; set; }

    [Parameter]
    public EventCallback OnClose { get; set; }

    private string _exportPasswordValue = string.Empty;
    private string _confirmPasswordValue = string.Empty;
    private int _passwordStrength = 0;
    private string _validationError = string.Empty;
    private Timer? _passwordDebounceTimer;

    private string _exportPassword
    {
        get => _exportPasswordValue;
        set
        {
            if (_exportPasswordValue != value)
            {
                _exportPasswordValue = value;
                ValidatePasswordWithDebounce();
            }
        }
    }

    private string _confirmPassword
    {
        get => _confirmPasswordValue;
        set
        {
            if (_confirmPasswordValue != value)
            {
                _confirmPasswordValue = value;
                ValidatePasswordImmediate();
            }
        }
    }

    private IStringLocalizer Localizer => LocalizerFactory.Create("Pages.Main.Settings.ImportExport.Components.ExportPasswordModal", "AliasVault.Client");
    private IStringLocalizer SharedLocalizer => LocalizerFactory.Create("Shared", "AliasVault.Client");
    private IStringLocalizer ValidationLocalizer => LocalizerFactory.Create("ValidationMessages", "AliasVault.Client");

    protected override void OnInitialized()
    {
        _passwordDebounceTimer = new Timer(800);
        _passwordDebounceTimer.Elapsed += async (sender, e) => await ValidatePasswordDebounced();
        _passwordDebounceTimer.AutoReset = false;
    }

    protected override void OnParametersSet()
    {
        if (!IsOpen)
        {
            _exportPasswordValue = string.Empty;
            _confirmPasswordValue = string.Empty;
            _passwordStrength = 0;
            _validationError = string.Empty;
        }
    }

    private void HandleStrengthChanged(int strength)
    {
        _passwordStrength = strength;
    }

    private void OnPasswordFocus(FocusEventArgs e)
    {
        _validationError = string.Empty;
        StateHasChanged();
    }

    private void ValidatePasswordWithDebounce()
    {
        _validationError = string.Empty;
        StateHasChanged();

        _passwordDebounceTimer?.Stop();
        _passwordDebounceTimer?.Start();
    }

    private async void ValidatePasswordImmediate()
    {
        await ValidatePasswordDebounced();
    }

    private async Task ValidatePasswordDebounced()
    {
        await InvokeAsync(() =>
        {
            var minLength = PasswordStrengthConstants.MinimumGoodPasswordLength;

            if (!string.IsNullOrWhiteSpace(_exportPasswordValue) &&
                _exportPasswordValue.Length < minLength)
            {
                _validationError = ValidationLocalizer["PasswordMinLengthGeneric", minLength];
                StateHasChanged();
                return;
            }

            if (!string.IsNullOrWhiteSpace(_confirmPasswordValue) &&
                _exportPasswordValue != _confirmPasswordValue)
            {
                _validationError = ValidationLocalizer["PasswordsDoNotMatchGeneric"];
                StateHasChanged();
                return;
            }

            _validationError = string.Empty;
            StateHasChanged();
        });
    }

    private bool IsPasswordValid()
    {
        return !string.IsNullOrEmpty(_exportPasswordValue) &&
               !string.IsNullOrEmpty(_confirmPasswordValue) &&
               _exportPasswordValue == _confirmPasswordValue &&
               string.IsNullOrEmpty(_validationError) &&
               _exportPasswordValue.Length >= PasswordStrengthConstants.MinimumGoodPasswordLength;
    }

    public void Dispose()
    {
        _passwordDebounceTimer?.Dispose();
    }

    private async Task HandleSubmit()
    {
        if (IsPasswordValid())
        {
            await OnPasswordSubmitted.InvokeAsync(_exportPasswordValue);
            _exportPasswordValue = string.Empty;
            _confirmPasswordValue = string.Empty;
            _validationError = string.Empty;
        }
    }

    private async Task HandleKeyDown(KeyboardEventArgs e)
    {
        if (e.Key == "Enter" && IsPasswordValid())
        {
            await HandleSubmit();
        }
        else if (e.Key == "Escape")
        {
            await OnClose.InvokeAsync();
        }
    }
}
