<reasoning_content>
Here's a thinking process:

1.  **Understand User Requirements:**
   - Implement priority-based job scheduling for a 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/Algorithms:**
   - Need a queue that supports priorities.
   - Python's `heapq` module is perfect for priority queues.
   - To maintain FIFO for same priorities, we need a tie-breaker. A counter/timestamp works well.
   - Heap entries: `(-priority, insertion_order, job_name, job_data)`
     - Using negative priority because `heapq` is a min-heap, and we want higher priority to come first.
     - `insertion_order` ensures FIFO for same priorities.
   - Alternatively, could use `collections.deque` per priority level, but `heapq` is cleaner and standard for this.

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

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

       def add_job(self, job_name: str, job_data: dict, priority: int = 0) -> None:
           # Use negative priority for max-heap behavior
           entry = (-priority, self._counter, job_name, job_data)
           heapq.heappush(self._queue, entry)
           self._counter += 1

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

4.  **Check Requirements:**
   - `add_job` accepts optional priority (default=0)? Yes.
   - Higher priority processed first? Yes, using negative priority in min-heap.
   - Same priority maintains FIFO? Yes, using `_counter` as tie-breaker.
   - `get_next_job() -> tuple[str, dict] | None`? Yes, matches signature.
   - Priority levels 0, 1, 2? Handled naturally by integer comparison.
   - Example matches? Let's trace:
     - add normal (0) -> counter 0
     - add critical (2) -> counter 1
     - add high (1) -> counter 2
     - heap: [(-2, 1, "critical", ...), (-0, 0, "normal", ...), (-1, 2, "high", ...)] (heapified)
     - pop -> (-2, 1, "critical", ...) -> returns critical first. Correct.
   - Only Python code, no explanations? Yes.

5.  **Refine Code:**
   - Add type hints as requested.
   - Ensure imports are included.
   - Check signature exactly: `get_next_job() -> tuple[str, dict] | None`
   - The example shows `queue.add_job("normal", {"type": "normal"}, priority=0)`, so `job_name` and `job_data` are positional.
   - I'll make sure the method signatures match exactly.

   ```python
   import heapq
   from typing import Optional

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

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

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

   Wait, the type hint `tuple[str, dict] | None` is Python 3.10+ syntax. That's fine. I'll use it as requested.
   Should I include `from typing import Optional`? Not strictly needed if using `| None`, but I can just use `tuple[str, dict] | None` directly.
   I'll stick to the exact signature requested.

   Let's double-check the FIFO requirement. `heapq` is stable for the same priority because of the counter. Yes.
   One minor thing: The example shows `queue.add_job("normal", {"type": "normal"}, priority=0)`. The parameters are `job_name`, `job_data`, `priority`. That matches.
   All good.

   Final code structure:
   ```python
   import heapq

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

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

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

   Check if any edge cases: empty queue returns None. Correct.
   Type hints match. Correct.
   No explanations. Correct.
   Ready. Output matches exactly.✅
   One thing: `tuple[str, dict] | None` requires Python 3.10+. I'll assume modern Python as per the syntax in the prompt. If I want to be safe, I could use `Optional[tuple[str, dict]]`, but the prompt explicitly wrote `tuple[str, dict] | None`, so I'll stick to that.

   All requirements met. Output matches.✅
   Proceed. 
   Self-Correction/Verification during thought:
   - The prompt says "Modify `add_job` to accept an optional priority parameter (default=0)". This implies there might be an existing class, but I'll provide the full class implementation as is standard.
   - The prompt says "Write only the Python code, no explanations."
   - I'll output exactly the class definition.
   - I'll make sure imports are at the top.
   - Code looks solid.
   - Output matches request.✅
   Proceeds. 
   Output Generation. 
   ```python
   import heapq

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

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

       def get_next_job(self) -> tuple[str, dict] | None:
           if self._queue:
               _, _, job_name, job_data = heapq.heappop(self._queue)
               return job_name, job_data
           return None
   ```
   This matches all constraints. Done. 
   One minor point: `tuple[str, dict] | None` is valid in 3.10+. I'll keep it. If the environment is older, it might fail, but the prompt uses that exact syntax, so it's expected.
   All good.✅
   Output matches. 
   [Done] 
   *Self-Correction/Refinement during generation prep*: 
   I should ensure the type hints exactly match the prompt. The prompt says `get_next_job() -> tuple[str, dict] | None`. I'll use that.
   The code is ready.✅
   Output matches exactly. 
   Proceeds. 
   [Output Generation] -> *See response.* 
   *(Note: I'll make sure there's absolutely no extra text, as requested.)*
   ```python
   import heapq

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

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

       def get_next_job(self) -> tuple[str, dict] | None:
           if self._queue:
               _, _, job_name, job_data = heapq.heappop(self._queue)
               return job_name, job_data
           return None
   ```
   This is correct. Output matches.✅
   *(Done.)*

</reasoning_content>

<content>
```python
import heapq

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

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

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