How is block hash calculated?
You create a block hashing blob (which is the block header, the tree root hash of the blocks transactions and a varint of the transaction count), then hash this using the RandomX1 hashing algorithm.
The hash blob returned for get_block(1)["blob"] is...
That is not a block hashing blob, that's the block blob as returned from the RPC get_block.
How do I calculate the hashes for an existing block?
For an existing block, obtain the block blob (per above), parse it to extract the header and transactions, construct your hashing blob (per above) and hash that.
...then to combine it with nonce
An existing block already has the nonce data, which can be in both the block header / in the miner transaction. Thus you don't need to do anything particular with the nonce data for an existing block - rather what you need is the block blob data and a way to parse it (extract the header and transactions) so you can construct a hashing blob.
1 Note you need to use the correct PoW hashing algorithm based on the block height you are checking as the algorithm bas changed over time. The current algorithm is RandomX, but if you want to validate block 1 (which is something you mentioned) you'd need to use the original CryptoNight algorithm in that case.
UPDATE (based on comments below)
Note the term "block hash" can refer to either the PoW hash or the block ID (as used by block explorers etc). These use the same input data as described above but use different hash functions. For the latter you need to use Keccak-256.