<reasoning_content>
The user wants a Python implementation of a priority-based job queue.
Requirements:
1. `add_job` accepts `name` (str), `data` (dict), and `priority` (int, default=0).
2. Higher priority values should be processed first.
3. FIFO order for same priority.
4. `get_next_job` returns a tuple `(name, data)` or `None`.
5. Priority levels: 0=Normal, 1=High, 2=Critical.
6. Output only Python code.

I will use a priority queue (heapq) to implement this efficiently.
Since `heapq` is a min-heap, I need to invert the priority or use negative priorities to get higher priority values first.
To maintain FIFO order for same priorities, I will add a counter to the heap tuples.
The heap will store tuples: `(-priority, counter, name, data)`.
Counter ensures FIFO.
`add_job` will push to heap.
`get_next_job` will pop from heap and return `(name, data)`.

Let's draft the class:

```python
import heapq

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

    def add_job(self, name: str, data: dict, priority: int = 0):
        # Invert priority for min-heap to process higher priority first
        heapq.heappush(self._queue, (-priority, self._counter, name, data))
        self._counter += 1

    def get_next_job(self) -> tuple[str, dict] | None:
        if not self._queue:
            return None
        _, _, name, data = heapq.heappop(self._queue)
        return (name, data)
```

Check requirements:
1. `add_job` accepts optional priority (default=0) - Yes.
2. Higher priority processed first - Yes, using negative priority.
3. Same priority FIFO - Yes, using counter.
4. `get_next_job` returns `tuple[str, dict] | None` - Yes.
5. Priority levels 0, 1, 2 - Handled naturally.
6. Only Python code - Yes.

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
```
My implementation matches this.

One minor point: `tuple[str, dict] | None` syntax requires Python 3.10+. I'll use it as requested, or `typing.Tuple` if needed, but the prompt uses `tuple[str, dict] | None`. I'll stick to that.

Let's verify imports. `heapq` is standard.
The code looks solid.

I will output just the code as requested.
No extra text.
Done. 
Let's double check the exact signature: `get_next_job() -> tuple[str, dict] | None`
Yes.

One thing: `dict` in type hints might need `from typing import Dict` or just `dict` in newer Python. I'll use `dict` as in the prompt.
The prompt says: `get_next_job() -> tuple[str, dict] | None`
I'll write exactly that.

Code structure:
```python
import heapq

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

    def add_job(self, name: str, data: dict, priority: int = 0) -> None:
        heapq.heappush(self._queue, (-priority, self._counter, name, data))
        self._counter += 1

    def get_next_job(self) -> tuple[str, dict] | None:
        if not self._queue:
            return None
        _, _, name, data = heapq.heappop(self._queue)
        return (name, data)
```
This meets all requirements. I will output it.
No explanations.
Ready. 
One minor consideration: Should I handle type hints compatibility? The prompt uses `tuple[str, dict] | None`, which is Python 3.10+. I'll assume modern Python.
All good.✅
Output matches request. 
Proceeds. 
[Output Generation] -> *Python code block only*
```python
import heapq

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

    def add_job(self, name: str, data: dict, priority: int = 0) -> None:
        heapq.heappush(self._queue, (-priority, self._counter, name, data))
        self._counter += 1

    def get_next_job(self) -> tuple[str, dict] | None:
        if not self._queue:
            return None
        _, _, name, data = heapq.heappop(self._queue)
        return (name, data)
```
Looks correct. I'll provide exactly this. 
Self-Correction/Verification during thought:
- Does `heapq` handle tuples correctly? Yes, compares element by element. `-priority` first, then `counter`.
- Higher priority (2) becomes -2, which is less than -1 and 0, so it pops first. Correct.
- FIFO for same priority: `counter` increases, so smaller counter pops first. Correct.
- Returns `None` if empty. Correct.
- Type hints match. Correct.
- Only code. Correct.

All set. Output matches. 
Proceeds. 
[Output Generation] -> *Code*
(Note: I'll make sure formatting is exact)
```python
import heapq

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

    def add_job(self, name: str, data: dict, priority: int = 0) -> None:
        heapq.heappush(self._queue, (-priority, self._counter, name, data))
        self._counter += 1

    def get_next_job(self) -> tuple[str, dict] | None:
        if not self._queue:
            return None
        _, _, name, data = heapq.heappop(self._queue)
        return (name, data)
```
Done. 
Output matches response. 
Proceeds. 
[Final Check]
The prompt asks for "Write only the Python code, no explanations."
I will output exactly the code block.
All good. 
✅

</reasoning_content>

<content>
```python
import heapq

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

    def add_job(self, name: str, data: dict, priority: int = 0) -> None:
        heapq.heappush(self._queue, (-priority, self._counter, name, data))
        self._counter += 1

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