"""
Step 2 — Settings Tests
- test_settings_page_loads: Settings page renders all sections
- test_language_change_to_french: Switching language to French updates all labels reactively
- test_language_change_persists_reload: Language preference survives page reload
- test_username_change: Changing user name persists to database
- test_username_persists_reload: User name survives page reload
- test_username_empty_rejected: Empty name shows validation error
- test_username_whitespace_only_rejected: Whitespace-only name is rejected
- test_uuid_displayed_readonly: UUID is displayed and the field is read-only
- test_theme_toggle_dark: Switching to dark theme applies data-theme attribute
- test_theme_persists_reload: Theme preference survives page reload
- test_download_db_button: Download DB button is present and triggers a download
- test_restore_db_button: Restore DB button is visible and enabled
- test_restore_db_cancel_dialog: Declining confirm dialog aborts the restore
- test_restore_db_flow: Full restore round-trip with spinner and report
- test_restore_db_keeps_current_schema_version: Restore keeps the live DB's schema_version stamp
- test_restore_db_invalid_file: Uploading a non-SQLite file shows error report
- test_restore_db_incomplete_db: Uploading a DB missing required tables shows error
- test_export_import_enabled: Export/Import buttons are present and enabled (wired in Step 3b)
- test_initialize_db_button: Initialize DB button is present and enabled
- test_initialize_db_dialog_requires_checkbox: Confirm button is disabled until checkbox is checked
- test_initialize_db_dialog_cancel: Canceling the dialog does not reset the database
- test_initialize_db_flow: Full initialize flow resets database and reloads page
"""
import os
import sqlite3
import tempfile
from playwright.sync_api import Page, expect


def _wait_for_db(page: Page, app_url: str):
    """Navigate and wait for the database to be ready."""
    page.goto(app_url)
    page.wait_for_function(
        "document.documentElement.getAttribute('data-db-ready') === 'true'",
        timeout=15000,
    )


def _go_to_settings(page: Page, app_url: str):
    """Navigate to the settings page and wait for DB."""
    _wait_for_db(page, app_url)
    page.click('a[href="#/settings"]')
    page.wait_for_selector('[data-testid="settings-language"]')


def _download_via_button(page: Page, trigger_selector: str):
    """Click a button that opens the save-filename dialog, accept the default name, return the Download."""
    page.locator(trigger_selector).click()
    page.wait_for_selector('[data-testid="save-file-confirm"]')
    with page.expect_download() as download_info:
        page.locator('[data-testid="save-file-confirm"]').click()
    return download_info.value


def test_settings_page_loads(page: Page, app_url: str):
    """Settings page renders all expected sections."""
    _go_to_settings(page, app_url)

    expect(page.locator('[data-testid="settings-language"]')).to_be_visible()
    expect(page.locator('[data-testid="settings-username"]')).to_be_visible()
    expect(page.locator('[data-testid="settings-uuid"]')).to_be_visible()
    expect(page.locator('[data-testid="settings-theme"]')).to_be_visible()
    expect(page.locator('[data-testid="settings-export"]')).to_be_visible()
    expect(page.locator('[data-testid="settings-import"]')).to_be_visible()


def test_language_change_to_french(page: Page, app_url: str):
    """Switching language to French updates nav labels reactively."""
    _go_to_settings(page, app_url)

    # Change to French
    page.select_option('[data-testid="settings-language"]', 'fr')
    page.wait_for_function(
        "window.__repos.settings.get('language').then(v => v === 'fr')",
        timeout=5000,
    )

    # Nav labels should now be in French
    expect(page.locator('a[href="#/home"] span')).to_have_text('Accueil')
    expect(page.locator('a[href="#/exercises"] span')).to_have_text('Exercices')
    expect(page.locator('a[href="#/settings"] span')).to_have_text('Réglages')

    # Reset to English for other tests
    page.select_option('[data-testid="settings-language"]', 'en')
    page.wait_for_function(
        "window.__repos.settings.get('language').then(v => v === 'en')",
        timeout=5000,
    )


def test_language_change_persists_reload(page: Page, app_url: str):
    """Language preference is persisted and restored after reload."""
    _go_to_settings(page, app_url)

    # Change to French and wait for DB confirmation
    page.select_option('[data-testid="settings-language"]', 'fr')
    page.wait_for_function(
        "window.__repos.settings.get('language').then(v => v === 'fr')",
        timeout=5000,
    )

    # Reload
    page.reload()
    page.wait_for_function(
        "document.documentElement.getAttribute('data-db-ready') === 'true'",
        timeout=15000,
    )

    # Nav should still be in French
    expect(page.locator('a[href="#/home"] span')).to_have_text('Accueil')

    # Navigate to settings to check the dropdown value
    page.click('a[href="#/settings"]')
    page.wait_for_selector('[data-testid="settings-language"]')
    expect(page.locator('[data-testid="settings-language"]')).to_have_value('fr')

    # Reset to English
    page.select_option('[data-testid="settings-language"]', 'en')
    page.wait_for_function(
        "window.__repos.settings.get('language').then(v => v === 'en')",
        timeout=5000,
    )


def test_username_change(page: Page, app_url: str):
    """Changing user name persists to the database."""
    _go_to_settings(page, app_url)

    username_input = page.locator('[data-testid="settings-username"]')
    username_input.fill('Alice')
    username_input.blur()
    page.wait_for_function(
        "window.__repos.settings.get('user_name').then(v => v === 'Alice')",
        timeout=5000,
    )

    # Verify in DB
    stored = page.evaluate("async () => await window.__repos.settings.get('user_name')")
    assert stored == 'Alice', f"Expected 'Alice', got '{stored}'"

    # Cleanup: restore default
    username_input.fill('User')
    username_input.blur()
    page.wait_for_function(
        "window.__repos.settings.get('user_name').then(v => v === 'User')",
        timeout=5000,
    )


def test_username_persists_reload(page: Page, app_url: str):
    """User name survives page reload."""
    _go_to_settings(page, app_url)

    username_input = page.locator('[data-testid="settings-username"]')
    username_input.fill('Bob')
    username_input.blur()
    page.wait_for_function(
        "window.__repos.settings.get('user_name').then(v => v === 'Bob')",
        timeout=5000,
    )

    # Reload and go back to settings
    page.reload()
    page.wait_for_function(
        "document.documentElement.getAttribute('data-db-ready') === 'true'",
        timeout=15000,
    )
    page.click('a[href="#/settings"]')
    page.wait_for_selector('[data-testid="settings-username"]')

    expect(page.locator('[data-testid="settings-username"]')).to_have_value('Bob')

    # Cleanup
    username_input = page.locator('[data-testid="settings-username"]')
    username_input.fill('User')
    username_input.blur()
    page.wait_for_function(
        "window.__repos.settings.get('user_name').then(v => v === 'User')",
        timeout=5000,
    )


def test_username_empty_rejected(page: Page, app_url: str):
    """Empty name shows a validation error and is not saved."""
    _go_to_settings(page, app_url)

    # Get original name
    original = page.evaluate("async () => await window.__repos.settings.get('user_name')")

    username_input = page.locator('[data-testid="settings-username"]')
    username_input.fill('')
    username_input.blur()
    page.wait_for_timeout(500)

    # Error should be visible
    expect(page.locator('[data-testid="settings-name-error"]')).to_be_visible()

    # DB should still have the original name
    stored = page.evaluate("async () => await window.__repos.settings.get('user_name')")
    assert stored == original, f"Name should not have changed, got '{stored}'"


def test_username_whitespace_only_rejected(page: Page, app_url: str):
    """Whitespace-only name is rejected."""
    _go_to_settings(page, app_url)

    original = page.evaluate("async () => await window.__repos.settings.get('user_name')")

    username_input = page.locator('[data-testid="settings-username"]')
    username_input.fill('   ')
    username_input.blur()
    page.wait_for_timeout(500)

    expect(page.locator('[data-testid="settings-name-error"]')).to_be_visible()

    stored = page.evaluate("async () => await window.__repos.settings.get('user_name')")
    assert stored == original, f"Name should not have changed, got '{stored}'"


def test_uuid_displayed_readonly(page: Page, app_url: str):
    """UUID is displayed and the field is read-only."""
    _go_to_settings(page, app_url)

    uuid_input = page.locator('[data-testid="settings-uuid"]')
    expect(uuid_input).to_be_visible()

    # Should have readonly attribute
    expect(uuid_input).to_have_attribute('readonly', '')

    # Value should be a valid UUID
    value = uuid_input.input_value()
    import re
    assert re.match(
        r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$',
        value,
    ), f"UUID field does not contain a valid UUID: {value}"


def test_theme_toggle_dark(page: Page, app_url: str):
    """Switching to dark theme applies the data-theme attribute on <html>."""
    _go_to_settings(page, app_url)

    # Switch to dark
    page.select_option('[data-testid="settings-theme"]', 'dark')
    page.wait_for_function(
        "window.__repos.settings.get('theme').then(v => v === 'dark')",
        timeout=5000,
    )

    theme_attr = page.evaluate("document.documentElement.getAttribute('data-theme')")
    assert theme_attr == 'dark', f"Expected data-theme='dark', got '{theme_attr}'"

    # Verify CSS variables changed (bg should be dark)
    bg = page.evaluate(
        "getComputedStyle(document.documentElement).getPropertyValue('--bg-color1').trim()"
    )
    assert bg == '#1a1a1a', f"Expected dark bg '#1a1a1a', got '{bg}'"

    # Reset to light
    page.select_option('[data-testid="settings-theme"]', 'light')
    page.wait_for_function(
        "window.__repos.settings.get('theme').then(v => v === 'light')",
        timeout=5000,
    )


def test_theme_persists_reload(page: Page, app_url: str):
    """Theme preference survives page reload."""
    _go_to_settings(page, app_url)

    # Switch to dark and wait for DB confirmation
    page.select_option('[data-testid="settings-theme"]', 'dark')
    page.wait_for_function(
        "window.__repos.settings.get('theme').then(v => v === 'dark')",
        timeout=5000,
    )

    # Reload
    page.reload()
    page.wait_for_function(
        "document.documentElement.getAttribute('data-db-ready') === 'true'",
        timeout=15000,
    )

    # data-theme should still be dark (applied at startup)
    theme_attr = page.evaluate("document.documentElement.getAttribute('data-theme')")
    assert theme_attr == 'dark', f"Expected data-theme='dark' after reload, got '{theme_attr}'"

    # Go to settings, dropdown should show dark
    page.click('a[href="#/settings"]')
    page.wait_for_selector('[data-testid="settings-theme"]')
    expect(page.locator('[data-testid="settings-theme"]')).to_have_value('dark')

    # Reset to light
    page.select_option('[data-testid="settings-theme"]', 'light')
    page.wait_for_function(
        "window.__repos.settings.get('theme').then(v => v === 'light')",
        timeout=5000,
    )


def test_download_db_button(page: Page, app_url: str):
    """Download DB button is present and triggers a download."""
    _go_to_settings(page, app_url)

    download_btn = page.locator('[data-testid="settings-download-db"]')
    expect(download_btn).to_be_visible()
    expect(download_btn).to_be_enabled()

    # Click and verify a download is initiated
    download = _download_via_button(page, '[data-testid="settings-download-db"]')
    assert download.suggested_filename.startswith('trainus-')
    assert download.suggested_filename.endswith('.sqlite3')


def test_restore_db_button(page: Page, app_url: str):
    """Restore DB button is visible and enabled."""
    _go_to_settings(page, app_url)

    restore_btn = page.locator('[data-testid="settings-restore-db"]')
    expect(restore_btn).to_be_visible()
    expect(restore_btn).to_be_enabled()


def test_restore_db_cancel_dialog(page: Page, app_url: str, tmp_path_factory):
    """Declining the confirm dialog aborts the restore (data unchanged)."""
    _go_to_settings(page, app_url)

    # Set a known username
    page.locator('[data-testid="settings-username"]').fill('KeepMe')
    page.locator('[data-testid="settings-username"]').blur()
    page.wait_for_function(
        "window.__repos.settings.get('user_name').then(v => v === 'KeepMe')",
        timeout=5000,
    )

    # Download DB so we have a file to upload
    tmp_dir = tmp_path_factory.mktemp("cancel_dialog")
    db_path = str(tmp_dir / "backup.sqlite3")
    download = _download_via_button(page, '[data-testid="settings-download-db"]')
    download.save_as(db_path)

    # Change username after download
    page.locator('[data-testid="settings-username"]').fill('Changed')
    page.locator('[data-testid="settings-username"]').blur()
    page.wait_for_function(
        "window.__repos.settings.get('user_name').then(v => v === 'Changed')",
        timeout=5000,
    )

    # Dismiss the confirm dialog
    page.once('dialog', lambda dialog: dialog.dismiss())

    # Open file chooser and supply the downloaded file
    with page.expect_file_chooser() as fc_info:
        page.locator('[data-testid="settings-restore-db"]').click()
    file_chooser = fc_info.value
    file_chooser.set_files(db_path)

    # Give a moment for any (unwanted) action — should NOT happen
    page.wait_for_timeout(1000)

    # Username should still be the changed value
    expect(page.locator('[data-testid="settings-username"]')).to_have_value('Changed')
    # No report should appear
    expect(page.locator('[data-testid="restore-report"]')).not_to_be_visible()


def test_restore_db_flow(page: Page, app_url: str, tmp_path_factory):
    """Full restore: download DB, change data, restore, verify report and restored data."""
    _go_to_settings(page, app_url)

    # 1. Set a known username and wait for persistence
    page.locator('[data-testid="settings-username"]').fill('BeforeRestore')
    page.locator('[data-testid="settings-username"]').blur()
    page.wait_for_function(
        "window.__repos.settings.get('user_name').then(v => v === 'BeforeRestore')",
        timeout=5000,
    )

    # 2. Download the DB (contains 'BeforeRestore')
    tmp_dir = tmp_path_factory.mktemp("restore_flow")
    db_path = str(tmp_dir / "backup.sqlite3")
    download = _download_via_button(page, '[data-testid="settings-download-db"]')
    download.save_as(db_path)

    # 3. Change username to something else
    page.locator('[data-testid="settings-username"]').fill('AfterChange')
    page.locator('[data-testid="settings-username"]').blur()
    page.wait_for_function(
        "window.__repos.settings.get('user_name').then(v => v === 'AfterChange')",
        timeout=5000,
    )

    # 4. Accept the confirm dialog automatically
    page.once('dialog', lambda dialog: dialog.accept())

    # 5. Trigger restore with the downloaded file
    with page.expect_file_chooser() as fc_info:
        page.locator('[data-testid="settings-restore-db"]').click()
    file_chooser = fc_info.value
    file_chooser.set_files(db_path)

    # 6. Report should appear with success
    report = page.locator('[data-testid="restore-report"]')
    expect(report).to_be_visible(timeout=15000)

    # Check report indicates success (green header text)
    report_header = report.locator('.report-success')
    expect(report_header).to_be_visible()

    # 7. Username should now reflect the restored data
    expect(page.locator('[data-testid="settings-username"]')).to_have_value('BeforeRestore')

    # 8. Dismiss the report
    page.locator('[data-testid="restore-report-dismiss"]').click()
    expect(report).not_to_be_visible()

    # 2. Download the DB (contains 'BeforeRestore')
    tmp_dir2 = tmp_path_factory.mktemp("restore_flow2")
    db_path2 = str(tmp_dir2 / "backup2.sqlite3")
    download = _download_via_button(page, '[data-testid="settings-download-db"]')
    download.save_as(db_path2)

    # 3. Change username to something else
    page.locator('[data-testid="settings-username"]').fill('AfterChange')
    page.locator('[data-testid="settings-username"]').blur()
    page.wait_for_function(
        "window.__repos.settings.get('user_name').then(v => v === 'AfterChange')",
        timeout=5000,
    )

    # 4. Accept the confirm dialog automatically
    page.once('dialog', lambda dialog: dialog.accept())

    # 5. Trigger restore with the downloaded file
    with page.expect_file_chooser() as fc_info:
        page.locator('[data-testid="settings-restore-db"]').click()
    file_chooser = fc_info.value
    file_chooser.set_files(db_path2)

    # 6. Report should appear with success
    report = page.locator('[data-testid="restore-report"]')
    expect(report).to_be_visible(timeout=15000)

    # Debug: print report contents if error
    report_text = report.text_content()
    error_msg = page.locator('[data-testid="restore-error-message"]')
    if error_msg.count() > 0:
        assert False, f"Restore failed with error report: {report_text}"

    # Check report indicates success (green header text)
    report_header = report.locator('.report-success')
    expect(report_header).to_be_visible()

    # 7. Username should now reflect the restored data
    expect(page.locator('[data-testid="settings-username"]')).to_have_value('BeforeRestore')

    # 8. Dismiss the report
    page.locator('[data-testid="restore-report-dismiss"]').click()
    expect(report).not_to_be_visible()


def test_restore_db_keeps_current_schema_version(page: Page, app_url: str, tmp_path_factory):
    """After a restore, the live DB keeps its current schema_version stamp
    instead of inheriting the backup's (F3). A backup stamped with an older
    version must not leave the live DB looking migration-pending, or the next
    launch would re-run migrations against an already-adapted schema.

    Note: while only schema v1 exists this can only simulate an older stamp;
    the first real v2 migration must ship a full end-to-end restore test of an
    actual older-version backup.
    """
    _go_to_settings(page, app_url)

    current_version = page.evaluate(
        "async () => (await window.__db.selectOne("
        "'SELECT MAX(version) AS v FROM schema_version')).v"
    )

    tmp_dir = tmp_path_factory.mktemp("restore_version")
    db_path = str(tmp_dir / "old-stamp.sqlite3")
    download = _download_via_button(page, '[data-testid="settings-download-db"]')
    download.save_as(db_path)

    # Stamp the backup with an older schema version, as if it were taken
    # before a (future) migration
    conn = sqlite3.connect(db_path)
    conn.execute("UPDATE schema_version SET version = 0")
    conn.commit()
    conn.close()

    page.once('dialog', lambda dialog: dialog.accept())
    with page.expect_file_chooser() as fc_info:
        page.locator('[data-testid="settings-restore-db"]').click()
    file_chooser = fc_info.value
    file_chooser.set_files(db_path)

    report = page.locator('[data-testid="restore-report"]')
    expect(report).to_be_visible(timeout=15000)
    expect(report.locator('.report-success')).to_be_visible()
    page.locator('[data-testid="restore-report-dismiss"]').click()

    restored_version = page.evaluate(
        "async () => (await window.__db.selectOne("
        "'SELECT MAX(version) AS v FROM schema_version')).v"
    )
    assert restored_version == current_version, (
        f"Live DB schema_version must stay {current_version} after restore, "
        f"got {restored_version}"
    )


def test_restore_db_invalid_file(page: Page, app_url: str):
    """Uploading a non-SQLite file shows an error report."""
    _go_to_settings(page, app_url)

    # Create a temp file with garbage content
    tmp = tempfile.NamedTemporaryFile(suffix='.sqlite3', delete=False)
    tmp.write(b'this is not a sqlite database at all')
    tmp.close()

    try:
        # Accept the confirm dialog
        page.once('dialog', lambda dialog: dialog.accept())

        # Trigger restore with the invalid file
        with page.expect_file_chooser() as fc_info:
            page.locator('[data-testid="settings-restore-db"]').click()
        file_chooser = fc_info.value
        file_chooser.set_files(tmp.name)

        # Report should appear with error
        report = page.locator('[data-testid="restore-report"]')
        expect(report).to_be_visible(timeout=10000)

        # Check it's an error report
        report_header = report.locator('.report-error')
        expect(report_header).to_be_visible()

        # Error message should be visible
        expect(page.locator('[data-testid="restore-error-message"]')).to_be_visible()
    finally:
        os.unlink(tmp.name)


def test_restore_db_incomplete_db(page: Page, app_url: str):
    """Uploading a SQLite DB missing required tables shows an error report."""
    _go_to_settings(page, app_url)

    # Create a minimal SQLite DB with no TrainUs tables via the browser
    # (we use page.evaluate to build bytes for a valid but empty SQLite DB)
    db_bytes = page.evaluate("""
        () => {
            // SQLite header for an empty database (100 bytes minimum)
            // We'll use a known minimal valid SQLite file
            const header = new Uint8Array([
                0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66,
                0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x33, 0x00
            ]);
            // Return as array for transfer
            return Array.from(header);
        }
    """)

    # Instead use a simpler approach: create a valid empty SQLite DB file
    # by letting the browser do it
    tmp = tempfile.NamedTemporaryFile(suffix='.sqlite3', delete=False)
    tmp.close()

    # Write a valid but empty SQLite DB using sqlite3 from Python
    import sqlite3
    conn = sqlite3.connect(tmp.name)
    conn.execute('CREATE TABLE dummy (id INTEGER PRIMARY KEY)')
    conn.commit()
    conn.close()

    try:
        page.once('dialog', lambda dialog: dialog.accept())

        with page.expect_file_chooser() as fc_info:
            page.locator('[data-testid="settings-restore-db"]').click()
        file_chooser = fc_info.value
        file_chooser.set_files(tmp.name)

        # Report should appear with error
        report = page.locator('[data-testid="restore-report"]')
        expect(report).to_be_visible(timeout=10000)

        report_header = report.locator('.report-error')
        expect(report_header).to_be_visible()

        expect(page.locator('[data-testid="restore-error-message"]')).to_be_visible()
    finally:
        os.unlink(tmp.name)


def test_export_import_enabled(page: Page, app_url: str):
    """Export and Import buttons are present and enabled (wired in Step 3b)."""
    _go_to_settings(page, app_url)

    export_btn = page.locator('[data-testid="settings-export"]')
    import_btn = page.locator('[data-testid="settings-import"]')

    expect(export_btn).to_be_visible()
    expect(import_btn).to_be_visible()
    expect(export_btn).to_be_enabled()
    expect(import_btn).to_be_enabled()


def test_initialize_db_button(page: Page, app_url: str):
    """Initialize DB button is present and enabled."""
    _go_to_settings(page, app_url)

    init_btn = page.locator('[data-testid="settings-initialize-db"]')
    expect(init_btn).to_be_visible()
    expect(init_btn).to_be_enabled()


def test_initialize_db_dialog_requires_checkbox(page: Page, app_url: str):
    """Confirm button is disabled until the confirmation checkbox is checked."""
    _go_to_settings(page, app_url)

    # Open the initialize dialog
    page.locator('[data-testid="settings-initialize-db"]').click()

    # Dialog should be visible
    dialog = page.locator('[data-testid="initialize-confirm-label"]')
    expect(dialog).to_be_visible()

    # Confirm button should be disabled initially
    confirm_btn = page.locator('[data-testid="initialize-confirm"]')
    expect(confirm_btn).to_be_disabled()

    # Check the checkbox
    page.locator('[data-testid="initialize-confirm-checkbox"]').check()

    # Confirm button should now be enabled
    expect(confirm_btn).to_be_enabled()

    # Cancel the dialog
    page.locator('[data-testid="initialize-cancel"]').click()
    expect(dialog).not_to_be_visible()


def test_initialize_db_dialog_cancel(page: Page, app_url: str):
    """Canceling the initialize dialog does not reset the database."""
    _go_to_settings(page, app_url)

    # Set a known username
    page.locator('[data-testid="settings-username"]').fill('TestUser')
    page.locator('[data-testid="settings-username"]').blur()
    page.wait_for_function(
        "window.__repos.settings.get('user_name').then(v => v === 'TestUser')",
        timeout=5000,
    )

    # Open the initialize dialog
    page.locator('[data-testid="settings-initialize-db"]').click()

    # Dialog should be visible
    expect(page.locator('[data-testid="initialize-confirm-label"]')).to_be_visible()

    # Cancel the dialog
    page.locator('[data-testid="initialize-cancel"]').click()

    # Dialog should close
    expect(page.locator('[data-testid="initialize-confirm-label"]')).not_to_be_visible()

    # Username should still be present (database not reset)
    expect(page.locator('[data-testid="settings-username"]')).to_have_value('TestUser')


def test_initialize_db_flow(page: Page, app_url: str):
    """Full initialize flow: check confirmation, click confirm, page reloads with fresh DB."""
    _go_to_settings(page, app_url)

    # Set a known username
    page.locator('[data-testid="settings-username"]').fill('WillBeDeleted')
    page.locator('[data-testid="settings-username"]').blur()
    page.wait_for_function(
        "window.__repos.settings.get('user_name').then(v => v === 'WillBeDeleted')",
        timeout=5000,
    )

    # Open the initialize dialog
    page.locator('[data-testid="settings-initialize-db"]').click()

    # Dialog should be visible
    expect(page.locator('[data-testid="initialize-confirm-label"]')).to_be_visible()

    # Check the confirmation checkbox
    page.locator('[data-testid="initialize-confirm-checkbox"]').check()

    # Click confirm - this will trigger a page reload
    page.locator('[data-testid="initialize-confirm"]').click()

    # Wait for the page to reload and DB to be ready
    page.wait_for_function(
        "document.documentElement.getAttribute('data-db-ready') === 'true'",
        timeout=15000,
    )

    # Navigate back to settings
    page.click('a[href="#/settings"]')
    page.wait_for_selector('[data-testid="settings-username"]')

    # Username should be reset to default 'User'
    expect(page.locator('[data-testid="settings-username"]')).to_have_value('User')
