<reasoning_content>
Here's a thinking process:

1.  **Understand User Requirements:**
   - Implement a priority-based job 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 Components:**
   - Need a `JobQueue` class.
   - Need to store jobs with their priority, name, and data.
   - Need to maintain FIFO order for same priority.
   - Need efficient retrieval of highest priority job.
   - `add_job(name: str, data: dict, priority: int = 0)`
   - `get_next_job() -> tuple[str, dict] | None`

3.  **Choose Data Structure:**
   - A heap (priority queue) is suitable for priority-based retrieval.
   - Python's `heapq` module implements a min-heap. Since we want higher priority first, we can negate the priority or use a custom comparison.
   - To maintain FIFO for same priority, we need a tie-breaker: insertion order/sequence number.
   - So, heap elements can be `(-priority, sequence_number, job_name, job_data)`.
   - `heapq` compares tuples element by element, so `(-priority, seq)` will correctly order by highest priority first, then by insertion order.

4.  **Design the Class:**
   ```python
   import heapq
   from typing import Optional, Tuple, Dict

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

       def add_job(self, name: str, data: dict, priority: int = 0) -> None:
           # Use negative priority for max-heap behavior
           # Use counter for FIFO ordering among same priorities
           heapq.heappush(self._heap, (-priority, self._counter, name, data))
           self._counter += 1

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

5.  **Check Requirements:**
   - Modify `add_job` to accept optional priority parameter (default=0) -> Done.
   - Higher priority jobs processed before lower -> Done (using `-priority`).
   - Same priority maintains FIFO -> Done (using `_counter`).
   - Add `get_next_job() -> tuple[str, dict] | None` -> Done.
   - Priority levels 0, 1, 2 -> Handled naturally by integer comparison.
   - Example matches -> Let's trace:
     - add normal (0) -> heap: `[(0, 0, "normal", {...})]` (negated: 0)
     - add critical (2) -> heap: `[(-2, 1, "critical", {...}), (0, 0, "normal", {...})]` -> heapify puts -2 first
     - add high (1) -> heap: `[(-2, 1, "critical", ...), (0, 0, "normal", ...), (-1, 2, "high", ...)]` -> wait, heap order might vary but pop gives -2 first.
     - Actually, `heapq` is a min-heap. `-2 < -1 < 0`, so `-2` (priority 2) comes out first. Correct.
     - FIFO for same priority: counter ensures earlier insertions have smaller counter, so they come out first. Correct.
   - Return type matches `tuple[str, dict] | None`.
   - Only Python code, no explanations.

6.  **Refine Code:**
   Add type hints as requested. Ensure it's clean and matches the example exactly.
   The example shows:
   ```python
   queue = JobQueue()
   queue.add_job("normal", {"type": "normal"}, priority=0)
   queue.add_job("critical", {"type": "critical"}, priority=2)
   queue.add_job("high", {"type": "high"}, priority=1)

   job = queue.get_next_job()  # Returns critical job first
   ```
   I'll make sure the class definition matches.

   One minor point: The prompt says `get_next_job() -> tuple[str, dict] | None`. I'll use `Optional[tuple[str, dict]]` or just `tuple[str, dict] | None` as per Python 3.10+ syntax. I'll stick to `tuple[str, dict] | None`.

   Let's write it out carefully.

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

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

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

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

   Wait, should I include imports? Yes, standard practice.
   Check type hints: `tuple[str, dict] | None` is valid in Python 3.10+. I'll use it as requested.
   The prompt says "Write only the Python code, no explanations."
   I'll output exactly that.

   One thing: `heapq` stores tuples, and when popping, we get `(-priority, counter, name, data)`. The return is `(name, data)`. This matches the requirement.
   All constraints met.
   Ready.✅
   Output matches response. 
   I will produce just the code block.
   Double-checking: "Modify `add_job` to accept an optional priority parameter (default=0)" - done.
   "Higher priority jobs should be processed before lower priority jobs" - done via negative priority in min-heap.
   "Jobs with the same priority should maintain FIFO order" - done via counter.
   "Add `get_next_job() -> tuple[str, dict] | None`" - done.
   Example works.
   Code is concise.
   Proceed. 
   Output generation. 
   [Self-Correction/Verification during thought]
   - Should I use `typing` module for compatibility? The prompt uses `tuple[str, dict] | None` which is 3.10+ syntax. I'll stick to that as it's in the prompt.
   - I'll add `import heapq` at the top.
   - The class name isn't specified but `JobQueue` is used in the example.
   - All good.
   Output matches exactly.✅
   Proceeds. 
   [Output Generation] -> *produces the code*
   ```python
   import heapq

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

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

       def get_next_job(self) -> tuple[str, dict] | None:
           if self._heap:
               _, _, name, data = heapq.heappop(self._heap)
               return (name, data)
           return None
   ```
   This matches all requirements. No extra text. Done. 
   Self-Correction/Note during generation: I should make sure the type hint matches exactly `tuple[str, dict] | None`. Python 3.10+ supports it. It's fine.
   All good.✅
   Output matches response. 
   [Final Check of the Prompt]
   "Write only the Python code, no explanations."
   I will output exactly the code block.
   Done. 
   [Output Generation] (proceeds)
   *(Note: I'll wrap it in a code block as standard, but ensure no extra text surrounds it.)*
   Actually, the prompt says "Write only the Python code, no explanations." I will just provide the code.
   Ready. 
   [Output] -> *code block*
   *(Done.)*

</reasoning_content>

<content>
```python
import heapq

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

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

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