<reasoning_content>
*   Requirement 1: Modify `add_job` to accept `priority` (default=0).
    *   Requirement 2: Higher priority jobs first.
    *   Requirement 3: Same priority = FIFO (First-In-First-Out).
    *   Requirement 4: Add `get_next_job()` returning `tuple[str, dict] | None`.
    *   Data Structure: A priority queue is needed. Python's `heapq` is standard for this.
    *   Ordering logic: `heapq` is a min-heap. If I want higher priority (2) first, I should store priority as negative values or use a comparison logic.
    *   FIFO logic: To handle FIFO for same priority, I need a counter/sequence number.

    *   `self.jobs`: A list to be used with `heapq`.
    *   `self.counter`: An integer to track insertion order.

    *   `add_job(self, job_id: str, data: dict, priority: int = 0)`:
        *   Push a tuple `(-priority, self.counter, job_id, data)` into the heap.
        *   Increment `self.counter`.
    *   `get_next_job(self) -> tuple[str, dict] | None`:
        *   Pop from the heap.
        *   If empty, return `None`.
        *   Otherwise, return `(job_id, data)`.

    *   The requirement says:
        - 0: Normal
        - 1: High
        - 2: Critical
    *   Higher priority (2) should be processed before lower (0).
    *   `heapq` is a min-heap.
    *   By storing `-priority`, a value of `2` becomes `-2`. `-2 < -1 < 0`.
    *   So, `-2` will be at the top of the min-heap. Correct.

    *   Class name: `JobQueue`.
    *   `import heapq`.

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

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

        def add_job(self, job_id: str, data: dict, priority: int = 0):
            # Use negative priority for max-heap behavior using min-heap
            # Counter ensures FIFO for same priority
            heapq.heappush(self._queue, (-priority, self._counter, job_id, data))
            self._counter += 1

        def get_next_job(self) -> Optional[Tuple[str, dict]] :
            if not self._queue:
                return None
            priority_neg, counter, job_id, data = heapq.heappop(self._queue)
            return (job_id, data)
    ```

    Wait, is the Priority level strictly 0, 1, 2? The prompt says "Priority levels: 0... 1... 2...". Usually, high numbers = higher priority in these prompts.
    Let's re-read: "Higher priority jobs should be processed before lower priority jobs".
    Example: `queue.add_job("critical", ..., priority=2)` returns first.
    Yes, `2` is higher than `0`.

    Does the code fulfill all requirements?
    1. `add_job` modified with `priority` (default=0). Yes.
    2. Higher priority first. Yes (-2 < -1 < 0).
    3. Same priority FIFO. Yes (the `counter` handles this).
    4. `get_next_job()` returns `tuple[str, dict] | None`. Yes.

    *Self-correction*: The type hints and return types should match the prompt exactly.
    `get_next_job() -> tuple[str, dict] | None`

    ```python
    import heapq

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

        def add_job(self, job_id: str, data: dict, priority: int = 0):
            # Push (-priority, count) to ensure max-heap behavior and FIFO order
            heapq.heappush(self._queue, (-priority, self._count, job_id, data))
            self._count += 1

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

    Wait, the prompt didn't provide the base class `JobQueue`. I should assume a clean implementation or just the class itself.

    Let's double check the requirements.
    "Write only the Python code, no explanations."

    One detail: `tuple[str, dict]` is Python 3.9+ syntax. Standard.

    Let's write the final block.
</reasoning_content>

<content>
```python
import heapq
from typing import Dict, Tuple, Optional

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

    def add_job(self, job_id: str, data: Dict, priority: int = 0):
        # Use negative priority to turn heapq (min-heap) into a max-priority queue.
        # The counter ensures FIFO order for items with the same priority.
        heapq.heappush(self._queue, (-priority, self._counter, job_id, data))
        self._counter += 1

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