<reasoning_content>
*   Goal: Implement priority-based job scheduling in a queue.
    *   Requirements:
        1.  `add_job` accepts `priority` (default 0).
        2.  Higher priority numbers are processed first (0 = Normal, 1 = High, 2 = Critical). Wait, "Higher priority jobs should be processed before lower priority jobs". Usually, in a priority queue, the *highest* priority value is served first. Looking at the example: `critical` has priority 2, `high` has priority 1, `normal` has priority 0. The example says `get_next_job()` returns `critical` first. So, high numerical value = high priority.
        3.  FIFO for equal priorities.
        4.  `get_next_job()` returns `tuple[str, dict]` or `None`.

    *   Data Structure: A Min-Heap/Max-Heap is standard for priority queues. However, since we need FIFO for equal priorities, we need a secondary tie-breaker (like a sequence number).
    *   Library: `heapq` in Python implements a min-heap. To make it a max-heap for priorities, I can store values as negative numbers or reverse the logic.
    *   Wait, if I use `heapq`, it's a min-heap.
        *   Priority 2 (Critical) > Priority 1 (High) > Priority 0 (Normal).
        *   To use `heapq` (min-heap) to act like a max-heap, I can store negative priorities.
        *   For tie-breaking (FIFO): I need a counter to store the order of insertion.
    *   Structure of an entry in the heap: `(-priority, counter, job_name, job_data)`.

    *   `JobQueue` class.
    *   `__init__`: Initialize the heap (`self._queue`) and a counter (`self._count`).
    *   `add_job(name, data, priority=0)`:
        *   Push `(-priority, self._count, name, data)` to heap.
        *   Increment counter.
    *   `get_next_job()`:
        *   Pop from heap.
        *   Return `(name, data)` or `None` if empty.

    *   Input: `queue.add_job("normal", ..., priority=0)`, `queue.add_job("critical", ..., priority=2)`, `queue.add_job("high", ..., priority=1)`.
    *   Heap entries:
        1. `(0, 0, "normal", ...)`
        2. `(-2, 1, "critical", ...)`
        3. `(-1, 2, "high", ...)`
    *   `heapq.heappop` will return the smallest first: `(-2, 1, "critical", ...)`. Correct.
    *   If priorities are same: `(-1, 2, ...)` and `(-1, 3, ...)`. `heapq` returns the smaller counter first. Correct (FIFO).

    ```python
    import heapq

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

        def add_job(self, name: str, data: dict, priority: int = 0):
            # Use negative priority for max-heap behavior using heapq (min-heap)
            # Use self._count as a tie-breaker for FIFO
            heapq.heappush(self._queue, (-priority, self._count, name, data))
            self._count += 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)
    ```

    *   Requirement 1: `add_job` accepts `priority` (default 0). (Yes)
    *   Requirement 2: Higher priority jobs processed first. (Yes, -2 < -1 < 0).
    *   Requirement 3: Same priority = FIFO. (Yes, counter handles this).
    *   Requirement 4: `get_next_job() -> tuple[str, dict] | None`. (Yes).

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

<content>
```python
import heapq

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

    def add_job(self, name: str, data: dict, priority: int = 0):
        # heapq is a min-heap. To simulate a max-priority queue, 
        # we store priority as a negative number.
        # The self._count ensures FIFO order for equal priorities.
        heapq.heappush(self._queue, (-priority, self._count, name, data))
        self._count += 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>