<reasoning_content>
*   Goal: Implement priority-based job scheduling for a `JobQueue`.
    *   Functionality:
        *   `add_job(name, data, priority=0)`: Add job with priority.
        *   `get_next_job()`: Retrieve highest priority job (highest number = highest priority).
        *   Tie-breaking: FIFO for same priority.
    *   Priority levels: 0 (Normal), 1 (High), 2 (Critical).
    *   Output: Python code only.

    *   I need a data structure that supports O(log n) insertion and O(log n) removal of the highest priority element. A Heap (Priority Queue) is ideal.
    *   Python's `heapq` module implements a min-heap. To simulate a max-priority heap (where 2 > 1 > 0), I can store priorities as negative values (e.g., -2, -1, 0).
    *   To maintain FIFO order for identical priorities, I need a sequence number (counter).

    *   `__init__`: Initialize the list (heap) and a counter.
    *   `add_job(name, data, priority=0)`: Push `(-priority, counter, name, data)` onto the heap.
    *   `get_next_job()`: Pop the smallest element from the heap (which corresponds to highest priority due to negation) and return `(name, data)`.

    *   Class Name: `JobQueue`.
    *   Imports: `import heapq`.
    *   Initialization: `self._queue = []`, `self._counter = 0`.

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

    *   Is `heapq` the right choice? Yes.
    *   Is `priority` handled correctly? If priority 2 is higher than 0, then `heapq.heappush(self._queue, (-priority, self._counter, name, data)))` works because -2 < -1 < 0.
    *   Does it maintain FIFO? Yes, because `self._counter` increases monotonically. If priorities are equal, the counter dictates the order.

    ```python
    import heapq

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

        def add_job(self, name: str, data: dict, priority: int = 0):
            # Use negative priority for max-heap behavior with heapq (min-heap)
            # Use counter to maintain FIFO order for 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)
    ```

    *   Requirements:
        1. `add_job` with optional priority (default=0). Yes.
        2. Higher priority first. Yes (handled by `-priority`).
        3. Same priority FIFO. Yes (handled by `self._counter`).
        4. `get_next_job()` returns `tuple[str, dict] | None`. Yes.

    Wait, let me double check the priority values.
    0: Normal
    1: High
    2: Critical
    Requirement: "Higher priority jobs should be processed before lower priority jobs".
    Since 2 > 1 > 0, using `-priority` means:
    -2 is smallest (highest priority).
    -1 is next.
    0 is largest (lowest priority).
    Correct.
</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):
        # Using negative priority because heapq is a min-heap, 
        # but we want higher numbers to have higher priority.
        # self._counter ensures FIFO order for identical priorities.
        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>