<reasoning_content>
Here's a thinking process:

1.  **Understand User Requirements:**
   - Implement a priority-based job scheduling queue.
   - Modify `add_job` to accept an optional `priority` parameter (default=0).
   - Higher priority jobs processed first.
   - Same priority jobs maintain FIFO order.
   - Add `get_next_job() -> tuple[str, dict] | None` to get the highest priority job.
   - Priority levels: 0 (Normal), 1 (High), 2 (Critical).
   - Example provided shows usage.
   - Output only Python code, no explanations.

2.  **Identify Key Data Structures:**
   - Need to store jobs with priorities.
   - Need to maintain FIFO order within the same priority.
   - A heap (min-heap or max-heap) is suitable for priority queues. Python's `heapq` implements a min-heap.
   - To use `heapq` for highest priority first, I can negate the priority or use a negative priority value.
   - To maintain FIFO for same priority, I need a tie-breaker: a sequence number/timestamp.
   - Each heap entry could be: `(-priority, sequence_number, job_id, job_data)`
   - Wait, the example shows `add_job("normal", {"type": "normal"}, priority=0)`. The return type of `get_next_job()` is `tuple[str, dict] | None`, which matches `(job_id, job_data)`.

3.  **Design the Class:**
   ```python
   import heapq
   from typing import Optional

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

       def add_job(self, job_id: str, job_data: dict, priority: int = 0) -> None:
           # Use negative priority so higher priority comes first in min-heap
           # Use _counter to maintain FIFO for same priority
           heapq.heappush(self._heap, (-priority, self._counter, job_id, job_data))
           self._counter += 1

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

4.  **Check Requirements:**
   - Modify `add_job` to accept optional priority (default=0) -> Yes.
   - Higher priority jobs processed first -> Yes, using `-priority`.
   - Same priority maintains FIFO -> Yes, using `_counter`.
   - Add `get_next_job() -> tuple[str, dict] | None` -> Yes.
   - Priority levels 0, 1, 2 -> Handled by integer comparison.
   - Example matches -> Yes.
   - Only Python code, no explanations -> Will output just the code.

   Wait, should I include type hints? The prompt shows `tuple[str, dict] | None`, which is Python 3.10+ syntax. I'll use it.
   Also, need to make sure the class name matches the example: `JobQueue`.
   The example shows:
   ```python
   queue = JobQueue()
   queue.add_job("normal", {"type": "normal"}, priority=0)
   ...
   job = queue.get_next_job()
   ```
   This matches my design.

   One minor point: `typing` imports might be needed for `Optional` or just use `| None` directly. I'll stick to modern Python syntax as requested.
   I'll add `import heapq` at the top.
   I'll make sure the code is complete and ready to run.

   Let's double-check the heap entry structure: `(-priority, self._counter, job_id, job_data)`
   When popping, `_, _, job_id, job_data = heapq.heappop(self._heap)` works.
   Returns `(job_id, job_data)`.
   Matches `tuple[str, dict] | None`.

   All good. I'll write the code now.
   One thing: The prompt says "Modify `add_job`", implying there might be an existing class, but I'll provide the full class definition as is standard.
   I'll include necessary imports.
   Code structure:
   ```python
   import heapq
   from typing import Optional

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

       def add_job(self, job_id: str, job_data: dict, priority: int = 0) -> None:
           heapq.heappush(self._heap, (-priority, self._counter, job_id, job_data))
           self._counter += 1

       def get_next_job(self) -> tuple[str, dict] | None:
           if not self._heap:
               return None
           _, _, job_id, job_data = heapq.heappop(self._heap)
           return job_id, job_data
   ```
   Wait, `tuple[str, dict] | None` is valid in Python 3.10+. I'll use it as requested.
   Should I add type hints to `__init__`? Not strictly necessary but good practice. I'll keep it simple.
   The prompt says "Write only the Python code, no explanations."
   I'll output exactly that.

   One detail: `from typing import Optional` isn't needed if I use `| None`. I'll just use `| None`.
   I'll make sure the code matches the example exactly.
   All set. Output matches requirements.✅
   Let's produce the response. 
   Self-Correction/Verification during thought:
   - Does `heapq` maintain FIFO for same priority? Yes, because tuples are compared element by element. `-priority` is same, then `self._counter` breaks ties in insertion order.
   - Higher priority first? Yes, `-priority` makes higher priorities more negative, so they come first in min-heap.
   - Return type matches? Yes.
   - Example works? Yes.
   - Code only? Yes.
   Ready. 
   Output matches the refined code.✅
   Proceeds. 
   [Output Generation] -> *Proceeds*
   *(Self-Correction/Refinement during generation prep)*: I should make sure the type hint `tuple[str, dict] | None` is valid. It is in Python 3.10+. I'll keep it. No extra imports needed except `heapq`. I'll add `import heapq` at the top. That's it. 
   Final code:
   ```python
   import heapq

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

       def add_job(self, job_id: str, job_data: dict, priority: int = 0) -> None:
           heapq.heappush(self._heap, (-priority, self._counter, job_id, job_data))
           self._counter += 1

       def get_next_job(self) -> tuple[str, dict] | None:
           if not self._heap:
               return None
           _, _, job_id, job_data = heapq.heappop(self._heap)
           return job_id, job_data
   ```
   Matches all constraints. Output matches exactly.✅
   Proceeds. 
   [Output Generation] -> *Done.* 
   *(Note: I'll output just the code block as requested.)*
   All good. 
   [Final Check of the Prompt]: "Write only the Python code, no explanations." -> I will strictly follow this.
   Code is ready.✅
   Output matches response. 
   [Proceeds]

</reasoning_content>

<content>
```python
import heapq

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

    def add_job(self, job_id: str, job_data: dict, priority: int = 0) -> None:
        heapq.heappush(self._heap, (-priority, self._counter, job_id, job_data))
        self._counter += 1

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