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

    *   A Priority Queue is usually implemented using a heap.
    *   Python's `heapq` module provides a min-heap.
    *   Since we want *higher* priority numbers to come first, we can store priorities as negative values (e.g., priority 2 becomes -2).
    *   To maintain FIFO for the same priority, we need a counter to act as a tie-breaker. If two items have the same priority, the one added earlier (smaller counter) should be served first.
    *   Structure in heap: `(priority_value, entry_count, job_name, job_data)`.

    *   Initialize `heap` list.
    *   Initialize `counter` to 0.
    *   `add_job(name, data, priority=0)`:
        *   Push `(-priority, counter, name, data)` into heap.
        *   Increment `counter`.
    *   `get_next_job()`:
        *   If heap is empty, return `None`.
        *   Pop from heap.
        *   Return `(name, data)`.

    ```python
    import heapq

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

        def add_job(self, name: str, data: dict, priority: int = 0):
            # We use -priority because heapq is a min-heap
            # counter ensures FIFO 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
            priority_neg, count, name, data = heapq.heappop(self.queue)
            return (name, data)
    ```

    *   Does `add_job` accept priority (default=0)? Yes.
    *    Does higher priority process first? Yes (-2 < -1 < 0).
    *    Does same priority maintain FIFO? Yes (counter is unique and increasing).
    *    Does `get_next_job` return `tuple[str, dict] | None`? Yes.

    Wait, the user prompt says "Write only the Python code, no explanations."

    Check types: `tuple[str, dict] | None` requires Python 3.10+ syntax. I'll use that.

    One detail: The prompt asks for a `JobQueue` class based on the example.

    ```python
    import heapq

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

        def add_job(self, name: str, data: dict, priority: int = 0):
            # Priority levels: 0 (Normal), 1 (High), 2 (Critical)
            # heapq is a min-heap, so we use -priority to prioritize higher numbers
            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)
    ```

    Double check requirement 2: "Higher priority jobs should be processed before lower priority jobs".
    Priority 2 is higher than 1.
    In my code: `heappush(..., -2, ...)` vs `heappush(..., -1, ...)`.
    Min-heap will pop `-2` first. Correct.

    Double check requirement 3: "Jobs with the same priority should maintain FIFO order".
    If two jobs have priority 1:
    Job A: `(-1, 0, ...)`
    Job B: `(-1, 1, ...)`
    Min-heap pops `(-1, 0, ...)` first. 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):
        # Use negative priority because heapq is a min-heap
        # 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>