<reasoning_content>
The user wants a Python class `JobQueue` that implements priority-based job scheduling.
Requirements:
1. `add_job` accepts an optional `priority` parameter (default=0).
2. Higher priority jobs are processed first.
3. FIFO order for same priority.
4. `get_next_job()` returns a tuple `(name, job_data)` or `None`.
Priority levels: 0 (Normal), 1 (High), 2 (Critical).

I'll use a priority queue. Python's `heapq` module is suitable for this.
Since `heapq` is a min-heap, and we want higher priority first, I can store negative priorities, or use a tuple `(priority, counter, name, job_data)` and negate the priority.
Wait, the requirement says "Higher priority jobs should be processed before lower priority jobs". So priority 2 > priority 1 > priority 0.
Using `heapq`, I can store `(-priority, counter, name, job_data)`. The counter ensures FIFO order for same priority.
Alternatively, I can just use a list and keep it sorted, but `heapq` is more efficient.

Let's design the class:
```python
import heapq
from typing import Optional, Tuple, Dict

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

    def add_job(self, name: str, job_data: dict, priority: int = 0) -> None:
        # Store as (-priority, counter, name, job_data)
        # Negate priority because heapq is a min-heap
        heapq.heappush(self._queue, (-priority, self._counter, name, job_data))
        self._counter += 1

    def get_next_job(self) -> Optional[Tuple[str, dict]]:
        if not self._queue:
            return None
        _, _, name, job_data = heapq.heappop(self._queue)
        return (name, 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.

Let's double check type hints. The requirement says `get_next_job() -> tuple[str, dict] | None`. I'll use that syntax or `Optional[Tuple[str, dict]]`. I'll stick to `Optional[Tuple[str, dict]]` for broader compatibility, or just use `tuple[str, dict] | None` as requested. Python 3.10+ supports `|`. I'll use `Optional` to be safe, or just follow the prompt exactly.

The prompt says: `get_next_job() -> tuple[str, dict] | None`
I'll write:
```python
import heapq
from typing import Optional, Tuple

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

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

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

Wait, should I include `import heapq`? Yes.
Should I include type hints as requested? The prompt gives `get_next_job() -> tuple[str, dict] | None`. I'll use that.

One minor point: `heapq` compares tuples element-wise. `(-priority, self._counter, ...)` will correctly order by priority descending, then by counter ascending (FIFO). This satisfies all requirements.

Let's verify the example:
add_job("normal", ..., 0) -> pushes (0, 0, "normal", ...)
add_job("critical", ..., 2) -> pushes (-2, 1, "critical", ...)
add_job("high", ..., 1) -> pushes (-1, 2, "high", ...)
Heap order: (-2, 1, ...), (-1, 2, ...), (0, 0, ...)
pop returns (-2, 1, "critical", ...) -> returns ("critical", {"type": "critical"})
Correct.

What about imports? I'll include `import heapq` at the top.
The prompt says "Write only the Python code, no explanations."
I will provide just the class definition.

One thing: `tuple[str, dict] | None` requires Python 3.10+. I'll use it as requested.
I'll also add `from typing import Optional` if needed, but not strictly necessary.

Let's structure it cleanly.

```python
import heapq

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

Wait, should `job_data` be a copy to avoid mutation issues? The prompt doesn't specify, but it's generally good practice. I'll just return it as is, or make a copy. The example doesn't imply mutation issues. I'll stick to returning the reference as is, it's simpler and matches typical coding challenge expectations.

Check requirement 3: "Jobs with the same priority should maintain FIFO order". The counter ensures this because `heapq` compares the second element of the tuple when the first elements are equal. Since counter increases monotonically, lower counter comes first, maintaining FIFO.

All requirements met.
I will output only the code.
One detail: `tuple[str, dict] | None` is valid in Python 3.10+. I'll use it exactly as requested.
I'll add `from typing import Optional` just in case, but it's fine without.
I'll keep it minimal.

Final code:
```python
import heapq

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

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

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

Wait, should I include type hints for `add_job`? The prompt says `add_job` should accept an optional priority parameter. I'll add type hints for consistency, but it's not strictly required. I'll keep them clean.

One thing: `tuple[str, dict] | None` might cause a syntax error in older Python versions, but the prompt explicitly uses it, so I'll keep it.

All good. Output matches request.
I will produce the code block now. 
Self-Correction/Verification during thought:
Does `heapq` handle tuples correctly with mixed types? Yes, `int`, `int`, `str`, `dict` - comparison stops at first difference. Since priorities and counters are ints, dict comparison won't happen unless priority and counter are identical, which is impossible due to counter. So it's safe.
The code is solid.
Output matches exactly.
Proceed. 
I'll format it properly.
No extra text.
Done. 
Output Generation. 
```python
import heapq

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

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

    def get_next_job(self) -> tuple[str, dict] | None:
        if not self._queue:
            return None
        _, _, name, job_data = heapq.heappop(self._queue)
        return name, job_data
```
Looks good. Matches all constraints. Returns only code. No explanations. Done. 
One minor point: `tuple[str, dict] | None` is Python 3.10+. I'll assume modern Python. If needed, I could use `Optional[Tuple[str, dict]]`, but the prompt explicitly wrote `tuple[str, dict] | None`. I'll stick to the prompt.
All set. 
Output matches response. 
Proceeds. 
[Done]

</reasoning_content>

<content>
```python
import heapq

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

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

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