<reasoning_content>
*   Goal: Implement priority-based job scheduling for a `JobQueue`.
    *   Requirements:
        1.  `add_job(name, data, priority=0)`: Accepts priority.
        2.  Ordering: Higher priority first.
        3.  Same priority: FIFO order.
        4.  `get_next_job() -> tuple[str, dict] | None`: Retrieve highest priority.
    *   Priority levels: 0 (Normal), 1 (High), 2 (Critical).
    *   Constraints: Write only Python code, no explanations.

    *   A simple way to handle priority + FIFO is to use a priority queue (heapq).
    *   In Python, `heapq` is a min-heap. To make it a max-priority heap (where 2 > 1 > 0), we can negate the priority value (e.g., `-priority`).
    *   To maintain FIFO for same priorities, we can use a sequence counter (an incrementing integer). The tuple in the heap would be `(-priority, sequence_number, job_name, job_data)`.
    *   `sequence_number` ensures that if `priority` is the same, the one with the smaller `sequence_number` (the one added earlier) comes first.

    ```python
    import heapq

    class JobQueue:
        def __init__(self):
            self.queue = []
            self.counter = 0

        def add_job(self, name, data, priority=0):
            # heapq is a min-heap.
            # To get max priority (2 > 1 > 0), we use -priority.
            # To maintain FIFO for same priority, we use self.counter.
            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
            # Pop the smallest element (highest priority because of negative sign)
            _, _, name, data = heapq.heappop(self.queue)
            return name, data
    ```

    *   `add_job` signature matches? Yes.
    *   Higher priority first? Yes (2 becomes -2, 1 becomes -1, 0 becomes 0. -2 is smaller than -1).
    *   FIFO for same priority? Yes (counter).
    *   `get_next_job` signature matches? Yes.
    *   Return type `tuple[str, dict] | None`? Yes.
</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):
        # heapq is a min-heap. To implement max-priority (2 > 1 > 0),
        # we store the priority as a negative value.
        # The counter ensures FIFO order 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>