<reasoning_content>
*   Goal: Implement priority-based job scheduling for a queue.
    *   Requirements:
        1.  `add_job(name, data, priority=0)`: Add job with optional priority.
        2.  Priority order: Higher number = higher priority (2: Critical, 1: High, 0: Normal).
        3.  Tie-breaker: FIFO (First-In-First-Out) for same priority.
        4.  `get_next_job() -> tuple[str, dict] | None`: Retrieve and remove the highest priority job.
    *   Constraint: Python code only, no explanation.

    *   To handle priority + FIFO, a standard approach is using a priority queue (e.g., `heapq` module).
    *   `heapq` is a min-heap. To make it a max-heap (higher priority first), we can store priority as its negation (e.g., -2, -1, 0).
    *   To handle FIFO for same priority, we need a secondary key: an incrementing counter.
    *   Structure of items in heap: `(-priority, counter, job_name, job_data)`.

    *   `import heapq`
    *   `import itertools` (to get a counter for tie-breaking).
    *   Class `JobQueue`:
        *   `__init__`: initialize heap and counter.
        *   `add_job`: push `(-priority, counter, name, data)`.
        *   `get_next_job`: pop from heap, return `(name, data)` or `None`.

    *   Priority 2 (Critical) -> `-2`
    *   Priority 1 (High) -> `-1`
    *   Priority 0 (Normal) -> `0`
    *   Heap property: `-2 < -1 < 0`. So `-2` comes first. This matches the requirement.

    *   Class `JobQueue`.
    *   `add_job(self, name: str, data: dict, priority: int = 0)`
    *   `get_next_job(self) -> tuple[str, dict] | None`

    *   `queue = JobQueue()`
    *   `add_job("normal", {"type": "normal"}, 0)` -> heap: `[(0, 0, "normal", {...})]`
    *   `add_job("critical", {"type": "critical"}, 2)` -> heap: `[(-2, 1, "critical", {...}), (0, 0, "normal", {...})]`
    *   `add_job("high", {"type": "high"}, 1)` -> heap: `[(-2, 1, "critical", {...}), (-1, 2, "high", {...}), (0, 0, "normal", {...})]`
    *   `get_next_job()` -> pops `(-2, 1, "critical", {...})` -> returns `("critical", {...})`.

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

    *   Requirements check:
        1. `add_job` accepts `priority=0`. Yes.
        2. Higher priority first. Yes (via negation).
        3. Same priority FIFO. Yes (via counter).
        4. `get_next_job` returns `tuple[str, dict] | None`. Yes.
</reasoning_content>

<content>
```python
import heapq
from itertools import count

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

    def add_job(self, name: str, data: dict, priority: int = 0):
        # Using -priority because heapq is a min-heap, 
        # but we want higher numbers to be processed first.
        # The counter ensures FIFO order for items with the same priority.
        count_val = next(self._counter)
        heapq.heappush(self._queue, (-priority, count_val, name, data))

    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>