<reasoning_content>
*   Goal: Implement priority-based job scheduling for a queue.
    *   Requirements:
        1. `add_job` must accept `priority` (default=0).
        2. Higher priority jobs first.
        3. FIFO for same priority.
        4. `get_next_job()` returns `tuple[str, dict] | None`.
    *   Priority Levels: 0 (Normal), 1 (High), 2 (Critical).
    *   Constraint: Write only Python code, no explanations.

    *   The standard way to implement a priority queue in Python is using the `heapq` module.
    *   `heapq` implements a min-heap.
    *   To handle priority (where higher number = higher priority), I should store the priority as a negative number (e.g., -2 for critical, -1 for high, 0 for normal).
    *   To maintain FIFO for the same priority, I need an entry count/sequence number.

    *   `JobQueue` class.
    *   `self._queue`: A list for `heapq`.
    *   `self._count`: An integer to track order.
    *   `add_job(job_id, job_data, priority=0)`:
        *   Push `(-priority, self._count, job_id, job_data)` onto the heap.
        *   Increment `self._count`.
    *   `get_next_job()`:
        *   Pop from heap if not empty, return `(job_id, job_data)`.
        *   Return `None` if empty.

    *   Requirement 1: `add_job` signature checked.
    *   Requirement 2: Higher priority first? Yes, if I use negative numbers with `heapq`.
    *   Requirement 3: FIFO for same priority? Yes, `self._count` handles this.
    *   Requirement 4: `get_next_job()` signature and return type checked.

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

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

        def add_job(self, job_id: str, job_data: Dict, priority: int = 0):
            # heapq is a min-heap. To make higher priority numbers pop first,
            # we negate the priority.
            # We include self._count to ensure FIFO for identical priorities.
            heapq.heappush(self._queue, (-priority, self._count, job_id, job_data)))
            self._count += 1

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

    *   Wait, the prompt asks for the implementation. I should probably provide the class definition.
</reasoning_content>

<content>
```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, job_data: Dict, priority: int = 0) -> None:
        # heapq is a min-heap. To treat higher priority numbers as "smaller" 
        # (higher priority), we negate the priority value.
        # self._counter ensures FIFO order for jobs with the same priority.
        heapq.heappush(self._queue, (-priority, self._counter, job_id, job_data))
        self._counter += 1

    def get_next_job(self) -> Optional[Tuple[str, Dict]]:
        if not self._queue:
            return None
        
        _, _, job_id, job_data = heapq.heappop(self._queue)
        return (job_id, job_data)
```
</content>