//
// POST /Users/AuthenticateByName  →  { AccessToken, User: { Id, Name } }
//
// Async via http_submit; on_login_response runs on the main thread.
//
// We also have a startup-time session probe (jellyfin_validate_session_async)
// that hits /System/Info with the saved token. On 401 we drop to the login
// screen instead of leaving the user staring at an empty library.
//

Login_User :: struct {
    Id:   string;
    Name: string;
}

Login_Response :: struct {
    AccessToken: string;
    User:        Login_User;
}

jellyfin_login_async :: (c: *Jellyfin_Client) {
    if c.login_pending  return;
    c.login_pending = true;
    body := tprint("{\"Username\":\"%\",\"Pw\":\"%\"}", c.username, c.password);
    log_info("auth: logging in as %", c.username);
    http_submit("POST", "/Users/AuthenticateByName", body, on_done=on_login_response);
}

jellyfin_logout :: (c: *Jellyfin_Client) {
    free(c.auth_token);
    free(c.user_id);
    c.auth_token = "";
    c.user_id    = "";
    c.logged_in  = false;
    config_clear();
}

// Token may have been revoked (re-login from another DeviceId match,
// password change, admin revoke). Clear the token but keep server_url,
// username, and the persisted device_id so the user can re-auth in one
// click — and so we don't burn a new device_id, which would orphan all
// prior session entries on the server.
jellyfin_force_logout :: () {
    log_warn("auth: clearing session (token rejected)");
    free(app.jellyfin.auth_token);
    free(app.jellyfin.user_id);
    app.jellyfin.auth_token = "";
    app.jellyfin.user_id    = "";
    app.jellyfin.logged_in  = false;
    config_save();
    app.current_view = .LOGIN;
}

// Hit a cheap authenticated endpoint with the saved token to check whether
// the server still honors it. /System/Info requires auth and is light.
jellyfin_validate_session_async :: () {
    log_info("auth: validating saved session");
    http_submit("GET", "/System/Info", on_done=on_validate_session);
}

#scope_file

on_login_response :: (task: *Http_Task) {
    app.jellyfin.login_pending = false;
    if !task.response.ok {
        log_error("login failed: status=% body=%", task.response.status_code, slice(task.response.body, 0, min(300, task.response.body.count)));
        return;
    }

    ok, parsed := Jaison.json_parse_string(task.response.body, Login_Response);
    if !ok {
        log_error("login: failed to parse JSON");
        return;
    }

    app.jellyfin.auth_token = copy_string(parsed.AccessToken);
    app.jellyfin.user_id    = copy_string(parsed.User.Id);
    app.jellyfin.logged_in  = true;
    log_info("auth: logged in as % (id=%)", parsed.User.Name, app.jellyfin.user_id);

    config_save();
    app.current_view = .LIBRARY;
    library_refresh_artists();
}

on_validate_session :: (task: *Http_Task) {
    if task.response.status_code == 401 {
        jellyfin_force_logout();
        return;
    }
    if !task.response.ok {
        // Network blip, server down, etc. — don't nuke the saved token over
        // a transient failure; keep the user on the login screen so they
        // can retry, but leave the credentials in place.
        log_error("auth: validate failed status=% (keeping saved token)", task.response.status_code);
        app.current_view = .LOGIN;
        return;
    }
    log_info("auth: saved session ok");
    app.current_view = .LIBRARY;
    library_refresh_artists();
}
