This jq script should do the trick:
{ id, name: (first(.Tags[] | select(.Key == "Name").Value)? // "(none)")}| "\(.id) \(.name)"It works similar to your pseudocode, but it doesn't proactively defend against the .Tags array being absent or empty. There's no particular reason to treat that differently than the case where it exists but doesn't contain a Name entry. This program just tries to access .Value of the Name entry, and if that doesn't work for any reason at all, it substitutes "(none)".
You can use this either by putting it in a file, or directly with
$ jq -r '{id, name: ...} | "\(.id) \(.name)"' input.json