<reasoning_content>
The user wants a Python implementation of a priority-based job scheduling queue.
Requirements:
1. Class `JobQueue` (implied by the example)
2. `add_job(job_id: str, job_data: dict, priority: int = 0)`
3. Higher priority jobs processed first
4. FIFO for same priority
5. `get_next_job() -> tuple[str, dict] | None`
6. Priority levels: 0 (Normal), 1 (High), 2 (Critical)
7. Output only Python code, no explanations.

I can use `heapq` or `sortedcontainers` or just a list with sorting. Since it's a simple queue, a list with `heapq` is efficient, but maintaining FIFO for same priority with `heapq` requires a tie-breaker. I can use a counter to maintain insertion order.

Alternatively, since it's a simple implementation request, I can just use a list and sort/insert, or use `heapq` with a tuple `(priority, insertion_counter, job_id, job_data)`. Wait, higher priority should be processed first. In `heapq`, lower values come out first. So I should store `-priority` to get higher priority first, or use a custom comparison. Actually, storing `(-priority, counter, job_id, job_data)` works perfectly.

Let's define the class:
```python
import heapq

class JobQueue:
    def __init__(self):
        self._heap = []
        self._counter = 0
        
    def add_job(self, job_id: str, job_data: dict, priority: int = 0):
        heapq.heappush(self._heap, (-priority, self._counter, job_id, job_data))
        self._counter += 1
        
    def get_next_job(self) -> tuple[str, dict] | None:
        if not self._heap:
            return None
        _, _, job_id, job_data = heapq.heappop(self._heap)
        return (job_id, job_data)
```

Wait, the example shows:
```python
queue = JobQueue()
queue.add_job("normal", {"type": "normal"}, priority=0)
queue.add_job("critical", {"type": "critical"}, priority=2)
queue.add_job("high", {"type": "high"}, priority=1)

job = queue.get_next_job()  # Returns critical job first
```

This matches the logic. Higher priority (2) -> `-2` is smaller than `-1` and `0`, so it pops first. Correct.
FIFO for same priority: `_counter` increases, so smaller counter comes out first. Correct.
Type hints: `tuple[str, dict] | None` is valid in Python 3.10+. I'll use it as requested.

Let's double check requirements:
- Modify `add_job` to accept optional priority parameter (default=0) -> Done.
- Higher priority jobs processed before lower -> Done.
- Same priority maintain FIFO -> Done.
- `get_next_job() -> tuple[str, dict] | None` -> Done.
- Priority levels mentioned: 0, 1, 2. The code handles any int, which is fine.
- Write only Python code, no explanations. -> Done.

One minor point: `heapq` stores tuples, and comparing tuples compares element by element. `(-priority, counter)` works.
Should I include `import heapq`? Yes.
Should I include type hints? The prompt uses them, so I will.
The prompt says "Write only the Python code, no explanations."

I will structure it cleanly.

```python
import heapq
from typing import Optional, Tuple, Dict

class JobQueue:
    def __init__(self):
        self._heap = []
        self._counter = 0

    def add_job(self, job_id: str, job_data: dict, priority: int = 0) -> None:
        heapq.heappush(self._heap, (-priority, self._counter, job_id, job_data))
        self._counter += 1

    def get_next_job(self) -> Optional[Tuple[str, dict]]:
        if not self._heap:
            return None
        _, _, job_id, job_data = heapq.heappop(self._heap)
        return job_id, job_data
```

Wait, `tuple[str, dict] | None` is preferred if using Python 3.10+, but `Optional[Tuple[str, dict]]` is safer for compatibility. I'll stick to `tuple[str, dict] | None` as requested in the prompt signature. Actually, the prompt says `get_next_job() -> tuple[str, dict] | None`, so I'll use that exact signature.

Let's verify the exact signature requested: `get_next_job() -> tuple[str, dict] | None`
I'll use that.

One thing: `heapq` comparison might fail if `job_id` or `job_data` are compared when priority and counter are equal, but counter is unique and strictly increasing, so it will never reach `job_id` comparison. So it's safe.

Code looks solid.

I will output just the code.
Check requirements again:
1. Modify `add_job` to accept an optional priority parameter (default=0) -> `def add_job(self, job_id: str, job_data: dict, priority: int = 0)`
2. Higher priority jobs should be processed before lower priority jobs -> `-priority` handles this.
3. Jobs with the same priority should maintain FIFO order -> `_counter` handles this.
4. Add `get_next_job() -> tuple[str, dict] | None` -> done.
Priority levels mentioned but not strictly enforced, just context.

All good.
I'll produce the code now.
One minor adjustment: I'll make sure the class name matches the example `JobQueue`.
The example uses `queue = JobQueue()`, so class name is `JobQueue`.
I'll include necessary imports.
Done. 
Output matches request.✅
Proceed. 
Self-Correction/Verification during thought:
Does `heapq` handle negative priorities correctly? Yes, `-2 < -1 < 0`, so `-2` pops first, meaning priority 2 pops first. Correct.
FIFO: counter increments, so lower counter pops first. Correct.
Type hints: I'll use `from typing import Optional` to be safe, or just use the `|` syntax as requested. I'll stick to `tuple[str, dict] | None` as it's standard in 3.10+.
I'll write it out. 
All set. 
Output generation. 
```python
import heapq

class JobQueue:
    def __init__(self):
        self._heap = []
        self._counter = 0

    def add_job(self, job_id: str, job_data: dict, priority: int = 0) -> None:
        heapq.heappush(self._heap, (-priority, self._counter, job_id, job_data))
        self._counter += 1

    def get_next_job(self) -> tuple[str, dict] | None:
        if not self._heap:
            return None
        _, _, job_id, job_data = heapq.heappop(self._heap)
        return job_id, job_data
```
Matches exactly. No extra text. Proceeds. 
Note: I'll make sure indentation and syntax are perfect.
The prompt says "Write only the Python code, no explanations."
I will output exactly that.✅
Done. 
Output Generation. 
[Done]

</reasoning_content>

<content>
```python
import heapq

class JobQueue:
    def __init__(self):
        self._heap = []
        self._counter = 0

    def add_job(self, job_id: str, job_data: dict, priority: int = 0) -> None:
        heapq.heappush(self._heap, (-priority, self._counter, job_id, job_data))
        self._counter += 1

    def get_next_job(self) -> tuple[str, dict] | None:
        if not self._heap:
            return None
        _, _, job_id, job_data = heapq.heappop(self._heap)
        return job_id, job_data
```
</content>