<reasoning_content>
*   Goal: Implement priority-based job scheduling for a `JobQueue` class.
    *   Requirements:
        1.  `add_job` must accept `priority` (default=0).
        2.  Higher priority (higher number) processed first.
        3.  Same priority -> FIFO (First In, First Out).
        4.  `get_next_job()` returns the highest priority job as a tuple `(name, data)`.
        5.  Priority levels: 0 (Normal), 1 (High), 2 (Critical).

    *   Priority Queue structure: Since we need to handle both priority and FIFO order, a standard heap/priority queue in Python (`heapq`) is suitable.
    *   However, `heapq` is a min-heap. We want a max-priority system (Higher number = Higher priority).
    *   To maintain FIFO for same priority: We need a tie-breaker (like a sequence counter).

    *   `self.jobs`: A list (heap).
    *   `self.counter`: An integer to act as the tie-breaker.

    *   `add_job(self, name, data, priority=0)`:
        *   Push tuple: `(-priority, self.counter, name, data)` into the heap.
        *   Increment `self.counter`.
    *   `get_next_job(self)`:
        *   Pop from heap.
        *   Return `(name, data)`.

    *   `heapq.heappush(heap, item)`
    *   `heapq.heappop(heap)`

    *   Requirement: Higher priority processed first.
    *   Input priorities: 0, 1, 2.
    *   If I use `-priority`, then:
        *   Priority 2 -> -2
        *   Priority 1 -> -1
        *   Priority 0 -> 0
    *   Min-heap will pop -2 first, then -1, then 0. Correct.
    *   FIFO for same priority: If two jobs have priority 1, the one with lower `counter` value comes first. Correct.

    ```python
    import heapq

    class JobQueue:
        def __init__(self):
            self.jobs = []
            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 self.counter to ensure FIFO for same priorities
            heapq.heappush(self.jobs, (-priority, self.counter, name, data))
            self.counter += 1

        def get_next_job(self) -> tuple[str, dict] | None:
            if not self.jobs:
                return None
            _, _, name, data = heapq.heappop(self.jobs)
            return (name, data)
    ```

    *   `add_job` accept `priority`? Yes.
    *   Higher priority first? Yes (via negative values in min-heap).
    *   Same priority FIFO? Yes (via counter).
    *   `get_next_job` return tuple or None? Yes.

    Wait, the prompt says `get_next_job() -> tuple[str, dict] | None`.
    I should ensure the syntax is correct.

    Let's re-check the requirements one last time.
    - 0: Normal
    - 1: High
    - 2: Critical
    Higher priority (2) should be before lower priority (0).

    Example check:
    - "normal", p=0 -> `(0, 0, "normal", {...})` -> heap pushed.
    - "critical", p=2 -> `(-2, 1, "critical", {...})`
    - "high", p=1 -> `(-1, 2, "high", {...})`
    Heap state: `[(-2, 1, "critical", {...}), (-1, 2, "high", {...}), (0, 0, "normal", {...})]` (roughly, order depends on heap structure).
    Pop will give `(-2, 1, "critical", {...})`. Correct.
</reasoning_content>

<content>
```python
import heapq

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

    def add_job(self, name: str, data: dict, priority: int = 0):
        # Use -priority to turn min-heap into max-priority behavior
        # Use self.counter to ensure FIFO order for equal priorities
        heapq.heappush(self.jobs, (-priority, self.counter, name, data))
        self.counter += 1

    def get_next_job(self) -> tuple[str, dict] | None:
        if not self.jobs:
            return None
        
        _, _, name, data = heapq.heappop(self.jobs)
        return (name, data)
```
</content>