<reasoning_content>
*   Goal: Implement priority-based job scheduling for a queue.
    *   Requirements:
        1.  `add_job(name, data, priority=0)`: Add job with priority.
        2.  Higher priority (higher number) processed first.
        3.  Tie-breaker: Same priority uses FIFO (First-In, First-Out).
        4.  `get_next_job() -> tuple[str, dict] | None`: Returns the highest priority job or `None`.
    *   Priority Levels: 0 (Normal), 1 (High), 2 (Critical).
    *   Constraint: Write only Python code.

    *   A standard `heapq` (min-heap) is usually the go-to for priority queues in Python.
    *   However, `heapq` is a min-heap. We need a max-heap behavior for the priority (2 > 1 > 0).
    *   To handle the FIFO requirement for equal priorities, we can use a sequence counter.
    *   The heap element structure should be: `(-priority, sequence_number, job_name, job_data)`.
        *   `-priority` makes it a max-heap for priority (largest number becomes smallest negative).
        *   `sequence_number` ensures FIFO for the same priority.
    *   Wait, if I use `-priority`, then `2` becomes `-2`, `1` becomes `-1`, `0` becomes `0`. In a min-heap, `-2` comes before `-1` and `0`. This correctly processes Critical (2) first.
    *   `sequence_number` increments with every `add_job`.

    *   `self.heap = []`
    *   `self.counter = 0`

    *   `self.counter += 1`
    *   `heapq.heappush(self.heap, (-priority, self.counter, name, data))`

    *   `if not self.heap: return None`
    *   `_, _, name, data = heapq.heappop(self.heap)`
    *   `return name, data`

    *   `import heapq`
    *   `class JobQueue:`
    *   ...

    *   `queue.add_job("normal", {"type": "normal"}, priority=0)` -> `heap: [ (0, 1, "normal", {...}) ]`
    *   `queue.add_job("critical", {"type": "critical"}, priority=2)` -> `heap: [ (-2, 2, "critical", {...}), (0, 1, "normal", {...}) ]`
    *   `queue.add_job("high", {"type": "high"}, priority=1)` -> `heap: [ (-2, 2, "critical", {...}), (0, 1, "normal", {...}), (-1, 3, "high", {...}) ]`
    *   `get_next_job()`:
        1. Pops `(-2, 2, "critical", {...})`. Returns `("critical", {"type": "critical"})`.
        2. Next pop: `(-1, 3, "high", {...})`. Returns `("high", {"type": "high"})`.
        3. Next pop: `(0, 1, "normal", {...})`. Returns `("normal", {"type": "normal"})`.
    *   This logic is sound.

    *   Python code only.
    *   No explanations.
</reasoning_content>

<content>
```python
import heapq

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

    def add_job(self, name: str, data: dict, priority: int = 0):
        # We use -priority because heapq is a min-heap, but we want high priority first.
        # We use self._counter to ensure FIFO order for jobs with the same priority.
        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>