<reasoning_content>
*   Goal: Implement a priority-based job queue.
    *   Requirements:
        1.  `add_job(name, data, priority=0)`: Add job with priority.
        2.  Higher priority processed first (Critical=2, High=1, Normal=0).
        3.  Same priority $\rightarrow$ FIFO (First-In, First-Out).
        4.  `get_next_job() -> tuple[str, dict] | None`: Retrieve highest priority.
    *   Constraints: Write only Python code.

    *   A standard priority queue (like `heapq`) processes elements based on priority.
    *   Problem: `heapq` is a min-heap. To handle high priority numbers (2 > 1 > 0) being "higher priority", I should either negate the priority or use a max-heap logic.
    *   Problem: `heapq` is not stable by default (doesn't guarantee FIFO for equal priorities).
    *   Solution for FIFO: Include a sequence counter (entry number) in the heap tuple.
    *   Tuple structure for `heapq`: `(-priority, sequence_number, job_name, job_data)`.
        *   `-priority`: Since `heapq` is a min-heap, using `-2` makes it smaller than `-1`, so it comes out first.
        *   `sequence_number`: Ensures FIFO when priorities are equal.
        *   `job_name`, `job_data`: The actual job content.

    *   Class `JobQueue`:
        *   `__init__`: `self.heap = []`, `self.count = 0`.
        *   `add_job(name, data, priority=0)`:
            *   `heapq.heappush(self.heap, (-priority, self.count, name, data))`
            *   `self.count += 1`
        *   `get_next_job()`:
            *   If heap empty, return `None`.
            *   `priority, seq, name, data = heapq.heappop(self.heap)`
            *   Return `(name, data)`.

    *   Requirement 1: `add_job` accepts `priority=0`. Checked.
    *   Requirement 2: Higher priority first. (Critical 2 > High 1 > Normal 0).
        *   Heap stores `-2`, `-1`, `0`. Min-heap pulls `-2` first. Correct.
    *   Requirement 3: Same priority -> FIFO.
        *   `seq` counter increments. For same `-priority`, `seq` 1 < `seq` 2. Correct.
    *   Requirement 4: `get_next_job` returns `tuple[str, dict] | None`. Checked.

    ```python
    import heapq

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

        def add_job(self, name: str, data: dict, priority: int = 0) -> None:
            # Use -priority because heapq is a min-heap
            # Use self._index to maintain FIFO order for same priority
            heapq.heappush(self._queue, (-priority, self._index, name, data))
            self._index += 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
    ```

    *   No explanations.
    *   Only Python code.

    Wait, the user prompt asks for:
    `get_next_job() -> tuple[str, dict] | None`

    Let's check the types in my implementation.
    `name` is `str`. `data` is `dict`. Returning `(name, data)` is `tuple[str, dict]`. Correct.

    One edge case: If I use `heapq`, I must import it.

    Final 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)
    ```

    Let's double check priority logic.
    Priority 2 (Critical) -> `-2` in heap.
    Priority 1 (High) -> `-1` in heap.
    Priority 0 (Normal) -> `0` in heap.
    Min-heap order: `-2, -1, 0`.
    Correct.

    Let's double check FIFO logic.
    Job A (Pri 1, Counter 0) -> `(-1, 0, ...)`
    Job B (Pri 1, Counter 1) -> `(-1, 1, ...)`
    Heap pops `(-1, 0, ...)` first. Correct.

    Final check on Return type signature:
    `get_next_job() -> tuple[str, dict] | None`
    Matches.
</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 is a min-heap. To treat higher numbers as higher priority,
        # we negate the priority. We include a counter to ensure FIFO 
        # stability for jobs with the same priority.
        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>