@page "/settings/import-export"
@inherits MainBase
@inject ItemService ItemService
@inject ILogger<ImportExport> Logger
@inject ConfirmModalService ConfirmModalService
@using Microsoft.Extensions.Localization
@using AliasVault.RazorComponents.Services
@using AliasVault.Client.Main.Pages.Settings.ImportExport.Components
@using AliasVault.ImportExport

<LayoutPageTitle>@Localizer["PageTitle"]</LayoutPageTitle>

<PageHeader
    BreadcrumbItems="@BreadcrumbItems"
    Title="@Localizer["PageTitle"]"
    Description="@Localizer["PageDescription"]">
</PageHeader>

<div class="p-4 mx-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
    <h3 class="mb-4 text-xl font-semibold dark:text-white">@Localizer["ImportSectionTitle"]</h3>
    <div class="mb-4 text-sm text-gray-500 dark:text-gray-400">
        @((MarkupString)Localizer["ImportSectionDescription"].Value)
    </div>
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        <ImportService1Password />
        <ImportServiceBitwarden />
        <ImportServiceChrome />
        <ImportServiceDashlane />
        <ImportServiceDropbox />
        <ImportServiceFirefox />
        <ImportServiceKeePass />
        <ImportServiceKeePassXC />
        <ImportServiceLastPass />
        <ImportServiceNordPass />
        <ImportServiceProtonPass />
        <ImportServiceStrongbox />
        <ImportServiceAliasVault />
        <ImportServiceGenericCsv />
    </div>
</div>

<div class="p-4 mx-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
    <h3 class="mb-4 text-xl font-semibold dark:text-white">@Localizer["ExportSectionTitle"]</h3>
    <div class="mb-4">
        <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">
            @Localizer["ExportSectionDescription"]
        </p>
        <div>
            <Button OnClick="@(() => ShowExportConfirmation(ExportType.Csv))">@Localizer["ExportCsvButton"]</Button>
        </div>
        <div class="mt-6">
            <Button OnClick="@(() => ShowExportConfirmation(ExportType.Sqlite))">@Localizer["ExportSqliteButton"]</Button>
        </div>
    </div>
</div>

<ResetVaultSection />

@code {
    private IStringLocalizer Localizer => LocalizerFactory.Create("Pages.Main.Settings.ImportExport.ImportExport", "AliasVault.Client");
    private ExportType _currentExportType;

    private enum ExportType
    {
        Csv,
        Sqlite
    }

    /// <inheritdoc />
    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        BreadcrumbItems.Add(new BreadcrumbItem { DisplayName = Localizer["PageTitle"] });
    }

    private async Task ShowExportConfirmation(ExportType exportType)
    {
        _currentExportType = exportType;
        var confirmMessage = Localizer["ExportWarningMessage"];

        var result = await ConfirmModalService.ShowConfirmation(Localizer["ExportConfirmTitle"], confirmMessage, SharedLocalizer["Confirm"], SharedLocalizer["Cancel"]);
        if (!result)
        {
            return;
        }

        await HandleExportConfirmed();
    }

    private async Task HandleExportConfirmed()
    {
        switch (_currentExportType)
        {
            case ExportType.Csv:
                await ExportVaultCsv();
                break;
            case ExportType.Sqlite:
                await ExportVaultSqlite();
                break;
        }
    }

    private async Task ExportVaultSqlite()
    {
        try
        {
            // Decode the base64 string to a byte array.
            byte[] fileBytes = Convert.FromBase64String(await DbService.ExportSqliteToBase64Async());

            // Create a memory stream from the byte array.
            using (MemoryStream memoryStream = new MemoryStream(fileBytes))
            {
                // Invoke JavaScript to initiate the download.
                await JsInteropService.DownloadFileFromStream($"{await GetExportFileName("sqlite")}", memoryStream.ToArray());
            }
        }
        catch (Exception ex)
        {
            Logger.LogError(ex, "Error downloading file");
        }
    }

    private async Task ExportVaultCsv()
    {
        try
        {
            var items = await ItemService.LoadAllAsync();

            var csvBytes = ItemCsvService.ExportItemsToCsv(items);

            // Create a memory stream from the byte array.
            using (MemoryStream memoryStream = new MemoryStream(csvBytes))
            {
                // Invoke JavaScript to initiate the download with date and username in filename
                await JsInteropService.DownloadFileFromStream($"{await GetExportFileName("csv")}", memoryStream.ToArray());
            }
        }
        catch (Exception ex)
        {
            Logger.LogError(ex, "Error downloading file");
        }
    }

    /// <summary>
    /// Creates a filename for the export file based on the current date and username.
    /// </summary>
    /// <param name="extension">The extension of the file.</param>
    /// <returns>The export file name.</returns>
    private async Task<string> GetExportFileName(string extension)
    {
        var dateStr = DateTime.UtcNow.ToString("yyyy-MM-dd");
        var username = await GetUsernameAsync();
        return $"aliasvault-export-{username}-{dateStr}.{extension}";
    }
}
