<reasoning_content>
*   Objective: Implement priority-based job scheduling for a queue.
    *   Requirements:
        1. `add_job` accepts `priority` (default=0).
        2. Higher priority first (2 > 1 > 0).
        3. Same priority = FIFO (First-In-First-Out).
        4. `get_next_job()` returns the highest priority job or `None`.
    *   Priority Levels: 0: Normal, 1: High, 2: Critical.
    *   Technical constraint: Write *only* the Python code, no explanations.

    *   Python's `heapq` module is the standard way to implement a priority queue.
    *   `heapq` is a min-heap (lowest value comes out first).
    *   Since higher priority values (2, 1, 0) should come out first, I can either:
        a) Store values as negative numbers (e.g., -2, -1, 0).
        b) Store them as they are but use a max-heap approach (not natively in `heapq`).
        c) Just use `heapq` and negate the priority.
    *   To maintain FIFO for same priorities, I need a tie-breaker (a counter). If two jobs have the same priority, the one added earlier should have a smaller counter value.

    *   Class `JobQueue`.
    *   `self.heap`: A list to store items.
    *   `self.counter`: An integer to ensure FIFO.
    *   `add_job(self, name, data, priority=0)`:
        *   Push `(-priority, self.counter, name, data)` into `heapq`.
        *   Increment `self.counter`.
    *   `get_next_job(self)`:
        *   Pop from `heapq` if not empty.
        *   Return `(name, data)`.

    *   Priority 2 -> -2 (Smallest)
    *   Priority 1 -> -1
    *   Priority 0 -> 0 (Largest)
    *   `heapq.heappush` will put -2 at the root. This works.

    *   `heapq` is in `heapq` module.
    *   Return type hint for `get_next_job`.

    ```python
    import heapq

    class JobQueue:
        def __init__(self):
            self.heap = []
            self.counter = 0

        def add_job(self, name: str, data: dict, priority: int = 0):
            # Higher priority values mean higher priority, so use -priority
            # to make it a min-heap behavior for the highest value.
            # Use counter to ensure FIFO for same priorities.
            heapq.heappush(self.heap, (-priority, self.counter, name, data))
            self.counter += 1

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

    *   `add_job` signature: `(self, name, data, priority=0)`? The prompt says "Modify `add_job` to accept an optional priority parameter".
    *   `get_next_job` return type: `tuple[str, dict] | None`.
    *   Example usage:
        *   `add_job("normal", ..., priority=0)`
        *   `add_job("critical", ..., priority=2)`
        *   `add_job("high", ..., priority=1)`
        *   `get_next_job()` returns "critical".

    Let's refine the code.
</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):
        # Using negative priority because heapq is a min-heap.
        # Higher priority numbers (e.g., 2) become smaller numbers (e.g., -2).
        # counter ensures FIFO order for items with the same priority.
        heapq.heappush(self.heap, (-priority, self.counter, name, data))
        self.counter += 1

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