*** Keywords ***
Login Via HTTP
    [Documentation]    Login via HTTP and store session cookie for RequestsLibrary.
    ...    Call this before any RequestsLibrary keyword that needs auth.
    ${headers}=    Create Dictionary    X-BanGUI-Request    1
    Create Session    bangsess    ${BACKEND_URL}    headers=${headers}
    ${login_payload}=    Create Dictionary    password    Hallo123!
    ${login_resp}=    POST On Session    bangsess    /api/v1/auth/login
    ...    json=${login_payload}
    ...    expected_status=200
    Log    HTTP login done. cookies=${login_resp.cookies}
    RETURN    bangsess

Login As Admin
    [Documentation]    Creates a new context and page and logs in via UI.
    ...    Caller should NOT call New Context/New Page before this.
    # Check setup status via HTTP API.
    ${response}=    GET    ${BACKEND_URL}/api/v1/setup
    ${body}=    Set Variable    ${response.json()}
    Log    Setup completed: ${body}[completed]

    IF    not ${body}[completed]
        # Complete setup wizard via HTTP API.
        ${setup_payload}=    Create Dictionary
        ...    master_password=Hallo123!
        ...    database_path=bangui.db
        ...    fail2ban_socket=/var/run/fail2ban/fail2ban.sock
        ...    timezone=UTC
        ...    session_duration_minutes=${60}
        POST    ${BACKEND_URL}/api/v1/setup    json=${setup_payload}
        Log    Setup POST completed.
    END

    # Create browser context.
    New Context
    New Page
    Go To    ${FRONTEND_URL}
    Wait For Load State    domcontentloaded

    # Wait for React to fully initialize before login attempt
    Sleep    5s

    # Use fetch to call login API with browser credentials so the session cookie
    # gets stored in the browser context. Use relative URL so Vite proxy handles it.
    ${login_result}=    Evaluate JavaScript    ${None}
    ...    async () => {
    ...        try {
    ...            // Wait for React to fully initialize.
    ...            await new Promise(r => setTimeout(r, 2000));
    ...            const res = await fetch('/api/v1/auth/login', {
    ...                method: 'POST',
    ...                headers: { 'Content-Type': 'application/json' },
    ...                body: JSON.stringify({ password: 'Hallo123!' }),
    ...                credentials: 'include'
    ...            });
    ...            const data = await res.json().catch(() => ({}));
    ...            return { ok: res.ok, status: res.status, data };
    ...        } catch(e) {
    ...            return { ok: false, error: String(e) };
    ...        }
    ...    }
    Log    API login result: ${login_result}

    # Check if login actually succeeded before marking as authenticated
    ${login_ok}=    Set Variable    ${login_result}[ok]
    IF    not ${login_ok}
        Fatal Error    Login API failed: ${login_result}
    END

    # Set sessionStorage so AuthProvider considers us authenticated without waiting
    # for API re-validation on the next navigation.
    Evaluate JavaScript    ${None}    () => sessionStorage.setItem('bangui_authenticated', 'true')

    # Navigate directly to the dashboard instead of Reload. Reload causes a race
    # where useSessionValidation's API call may redirect to /login before main renders.
    # Going to / forces the SPA router to resolve routes while sessionStorage is already set.
    Go To    ${FRONTEND_URL}/
    Wait For Load State    domcontentloaded

    # Poll for main to appear. The SPA remounts on navigation so domcontentloaded fires
    # before React has finished authenticating and rendering the protected route.
    ${login_ok}=    Set Variable    ${TRUE}
    FOR    ${i}    IN RANGE    1    16
        ${url}=    Get URL
        IF    '/login' in '${url}'
            # Still on /login after navigation — login did not succeed.
            ${login_ok}=    Set Variable    ${FALSE}
            EXIT FOR LOOP
        END
        ${found}=    Run Keyword And Return Status    Wait For Elements State    css=main    visible    timeout=2s
        IF    ${found}
            BREAK
        END
    END

    IF    not ${login_ok}
        ${last_result}=    Set Variable    ${login_result}
        Fatal Error    Login failed: ${last_result}
    END

    ${final_url}=    Get URL
    Log    Login complete. URL: ${final_url}