<reasoning_content>
*   Goal: Implement priority-based job scheduling for a `JobQueue` class.
    *   Requirements:
        1.  `add_job` needs an optional `priority` parameter (default 0).
        2.  Higher priority jobs processed first (Higher number = higher priority? Looking at example: `critical` is 2, `high` is 1, `normal` is 0. `critical` is returned first. So, Higher value = Higher priority).
        3.   Same priority = FIFO (First In, First Out).
        4.   `get_next_job()` returns `tuple[str, dict]` or `None`.

    *   I need a data structure that supports priority and order.
    *   Standard Python `heapq` is a min-heap.
    *   To implement a max-priority queue (higher number first):
        *   Store items as `(-priority, sequence_number, job_name, job_data)`.
        *   `sequence_number` ensures FIFO for same priority.
    *   Alternatively, I could use a dictionary of lists/deques indexed by priority, but `heapq` is more standard for "priority queue".

    *   `JobQueue` class.
    *   `self._heap`: list for `heapq`.
    *   `self._count`: integer to track sequence number for FIFO.
    *   `add_job(name, data, priority=0)`:
        *   Push `(-priority, self._count), (name, data))` into heap.
        *   Increment count.
    *   `get_next_job()`:
        *   Pop from heap.
        *   Return `(name, data)`.

    *   `pq.add_job("normal", ..., priority=0)` -> `(-0, 0, "normal", ...)`
    *   `pq.add_job("critical", ..., priority=2)` -> `(-2, 1, "critical", ...)`
    *   `pq.add_job("high", ..., priority=1)` -> `(-1, 2, "high", ...)`
    *   Heap order: `(-2, 1)` < `(-1, 2)` < `(-0, 0)`.
    *   Pop results in `(-2, 1)` which is `critical`. Correct.

    *   `heapq` is part of standard library.
    *   Type hints: `tuple[str, dict] | None`.

    ```python
    import heapq
    from typing import Tuple, Dict, Optional

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

        def add_job(self, name: str, data: Dict, priority: int = 0):
            # Use -priority to turn min-heap into max-priority
            # self._count ensures FIFO for same priority
            heapq.heappush(self._heap, (-priority, self._count, name, data))
            self._count += 1

        def get_next_job(self) -> Optional[Tuple[str, Dict]]:
            if not self._heap:
                return None
            _, _, name, data = heapq.heappop(self._heap)
            return (name, data)
    ```

    *   Does it handle `None`? Yes.
    *    Does it handle default priority? Yes.
    *    Does it handle FIFO? Yes, via `_count`.

    Wait, the prompt doesn't explicitly say to use `heapq`, but it's the most efficient way. Using a list and sorting every time would be O(N log N) per pop or O(N) per push. `heapq` is O(log N).

    Let's check the return type: `tuple[str, dict] | None`.

    Refining the type hints slightly to match the prompt's request exactly.

    ```python
    import heapq
    from typing import Tuple, Dict, Optional

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

        def add_job(self, name: str, data: Dict, priority: int = 0):
            heapq.heappush(self._heap, (-priority, self._count, name, data))
            self._count += 1

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

    Wait, `tuple[str, dict]` is Python 3.9+ syntax. If the user wants exactly that, I'll stick to it.

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

    Let's double check the prompt requirements.
    1. Modify `add_job` to accept an optional priority parameter (default=0).
    2. Higher priority jobs processed before lower.
    3. Same priority -> FIFO.
    4. `get_next_job() -> tuple[str, dict] | None`.

    Actually, looking at the prompt again, I should assume the class `JobQueue` already exists or I need to define it. Since the user asks to "Implement", I should provide the class structure.

    Wait, the `priority` levels:
    0: Normal
    1: High
    2: Critical
    So higher numbers = higher priority. Correct.

    Code:
    ```python
    import heapq
    from typing import Dict

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

        def add_job(self, name: str, data: Dict, priority: int = 0):
            # Higher priority numbers should come first.
            # Since heapq is a min-heap, we negate the priority.
            # counter ensures FIFO for identical priorities.
            heapq.heappush(self._heap, (-priority, self._counter, name, data))
            self._counter += 1

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

    One detail: `tuple[str, dict]` requires `from __future__ import annotations` or Python 3.9+. I'll just write it as requested.

    Final check:
    `queue.add_job("normal", {"type": " normal"}, priority=0)` -> `(0, 0, "normal", ...)`
    `queue.add_job("critical", {"type": "critical"}, priority=2)` -> `(-2, 1, "critical", ...)`
    `queue.add_job("high", {"type": "high"}, priority=1)` -> `(-1, 2, "high", ...)`

    Heap pops:
    1. `(-2, 1)` -> "critical"
    2. `(-1, 2)` -> "high"
    3. `(0, 0)` -> "normal"
    Matches example exactly.
</reasoning_content>

<content>
```python
import heapq
from typing import Dict

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

    def add_job(self, name: str, data: Dict, priority: int = 0):
        # Use negative priority to simulate a max-heap using heapq (min-heap).
        # self._counter ensures FIFO order for jobs with the same priority.
        heapq.heappush(self._heap, (-priority, self._counter, name, data))
        self._counter += 1

    def get_next_job(self) -> tuple[str, dict] | None:
        if not self._heap:
            return None
        
        # Pop the smallest element (highest priority due to negation).
        _, _, name, data = heapq.heappop(self._heap)
        return (name, data)
```
</content>