<reasoning_content>
The user wants a Python implementation of a priority-based job scheduling queue.
Key requirements:
1. `add_job(name, data, priority=0)` method
2. Higher priority values processed first (2 > 1 > 0)
3. FIFO for same priority
4. `get_next_job() -> tuple[str, dict] | None` method
5. Return only the Python code, no explanations.

I'll use `heapq` for efficient priority queue operations. Since `heapq` is a min-heap, I need to store negative priorities to get max-heap behavior, or store tuples with priority and a counter for FIFO ordering.

Let's use a counter to maintain insertion order for same priorities.
Tuple structure in heap: `(-priority, counter, job_data)`
Wait, the return type is `tuple[str, dict] | None`, which corresponds to `(name, data)`.

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

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

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

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

Check requirements:
1. `add_job` accepts optional priority parameter (default=0) -> Yes
2. Higher priority jobs processed before lower -> Yes, using `-priority`
3. Same priority maintains FIFO -> Yes, using `_counter`
4. `get_next_job() -> tuple[str, dict] | None` -> Yes
5. Priority levels: 0 normal, 1 high, 2 critical -> The logic handles any integer, but matches the example.
6. Only Python code, no explanations -> Will output just the code.

One minor thing: type hints. The prompt uses `tuple[str, dict] | None`, which is Python 3.10+ syntax. I'll stick to that or use `Optional[Tuple[str, dict]]` if needed, but the prompt uses `|`, so I'll assume Python 3.10+. I'll just use the exact signature requested.

Let's verify the example:
```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
```
Heap state after pushes:
1. `((0, 0, "normal", {"type": "normal"}))` -> `(-0, 0, "normal", ...)`
2. `((0, 0, "normal", ...), (-2, 1, "critical", ...))`
3. `((-2, 1, "critical", ...), (-1, 2, "high", ...), (-0, 0, "normal", ...))`
Pop returns `critical`, then `high`, then `normal`. Correct.

What if `add_job` is called with just `name` and `data`? The signature in the example is `queue.add_job("normal", {"type": "normal"}, priority=0)`. So it takes `name`, `data`, and `priority`. I'll define it as `def add_job(self, name: str, data: dict, priority: int = 0) -> None:`.

Wait, the prompt says `add_job` to accept an optional priority parameter (default=0). It doesn't specify the exact parameter names, but the example uses positional for name and data. I'll stick to `name, data, priority=0`.

Let's ensure type hints match Python 3.10+ style as requested, or use standard typing if needed. I'll just use the exact signature.

One detail: `tuple[str, dict] | None` is valid in Python 3.10+. I'll include `from __future__ import annotations` or just use it directly. It's fine.

Code structure:
```python
import heapq
from typing import Optional, Tuple

class JobQueue:
    def __init__(self) -> None:
        self._heap: list[tuple[int, int, str, dict]] = []
        self._counter: int = 0

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

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

Wait, the prompt says `tuple[str, dict] | None`. I'll use that exact syntax to be safe, assuming Python 3.10+.
Actually, I'll just write it cleanly.

Let's double check the FIFO requirement. `self._counter` increases monotonically. In a min-heap, smaller counter comes first. So earlier jobs get popped first. Correct.

One thing: `add_job` signature in prompt example: `queue.add_job("normal", {"type": "normal"}, priority=0)`
So `name` and `data` are positional, `priority` is keyword. My signature matches.

I will output only the code as requested.

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

class JobQueue:
    def __init__(self) -> None:
        self._heap: list[tuple[int, int, str, dict]] = []
        self._counter: int = 0

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

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

Wait, `tuple[str, dict] | None` might cause syntax error in older Python versions, but the prompt uses it, so I'll keep it. To be safe, I can use `Optional[tuple[str, dict]]` or just stick to the prompt's syntax. I'll stick to the prompt's syntax.

Actually, the prompt says: `get_next_job() -> tuple[str, dict] | None`
I'll use exactly that.

One minor point: `heapq` stores tuples. The comparison will first compare `-priority`, then `self._counter`, then `name`, then `data`. Since `self._counter` is unique and increases, it guarantees FIFO for same priorities. The comparison of `name` and `data` won't matter because counters are unique, but if they were not, comparing dicts would raise TypeError. To be strictly safe, I should ensure the tuple doesn't compare beyond the counter. I can use a large number or just rely on counter uniqueness. Since counter is unique, it's fine.

Wait, if two jobs have same priority and same counter (impossible here), it would compare name. But counter is unique per job, so it's fine.

I'll wrap it in a class as requested.

Final check of the code:
```python
import heapq

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

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

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

This meets all requirements. I will output only this code.
One thing: `tuple[str, dict] | None` is Python 3.10+ syntax. I'll assume it's fine. If I want to be strictly compatible, I could use `from typing import Optional, Tuple`, but the prompt uses `|`. I'll stick to `|`.

All good. Output matches request.✅
I will produce the code block now. 
Wait, let's consider if `data` could be anything, but the prompt says `dict`. It's fine.
The code is concise and correct.
Proceed. 
Output matches the final code block. 
Self-Correction/Refinement during thought: 
Should I include type hints exactly as requested? Yes.
Should I add `from __future__ import annotations`? Not necessary unless running on <3.10, but the prompt uses `|` directly. I'll just write it as is.
The prompt says "Write only the Python code, no explanations."
I will output exactly that.
Done. 
Generating. 
```python
import heapq

class JobQueue:
    def __init__(self) -> None:
        self._heap: list[tuple[int, int, str, dict]] = []
        self._counter: int = 0

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

    def get_next_job(self) -> tuple[str, dict] | None:
        if not self._heap:
            return None
        _, _, name, data = heapq.heappop(self._heap)
        return name, data
```
This looks solid. I'll output it. 
All constraints met. FIFO maintained via counter. Higher priority processed first via negation. Default priority 0. Returns tuple or None. Only code provided.✅
Done. 
Output matches response. 
Proceeds. 
[Output Generation] -> *Self-Correction/Verification during generation prep*: 
Wait, `tuple[str, dict] | None` might be better written as `Optional[tuple[str, dict]]` for broader compatibility, but I'll stick to the prompt's exact type hint. Actually, Python 3.10+ supports it. I'll keep it.
One detail: `heapq` compares tuples element by element. Since `self._counter` is strictly increasing and unique, it will always break ties before comparing `name` (str) and `data` (dict). So no `TypeError` from comparing dicts. Safe.
Code is ready.✅
Output matches. 
Proceeds. 
[Final Check of the Prompt]
"Write only the Python code, no explanations."
I will output just the code block.
Done. 
[Output Generation] -> *Proceeds*

</reasoning_content>

<content>
```python
import heapq

class JobQueue:
    def __init__(self) -> None:
        self._heap: list[tuple[int, int, str, dict]] = []
        self._counter: int = 0

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

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