<reasoning_content>
*   Implement priority-based job scheduling for a `JobQueue`.
    *   Requirements:
        1.  `add_job(name, data, priority=0)`: Add job with priority.
        2.  Priority order: 2 (Critical) > 1 (High) > 0 (Normal).
        3.  Tie-breaker: FIFO (First-In, First-Out) for same priority.
        4.  `get_next_job() -> tuple[str, dict] | None`: Return the highest priority job.
    *   Data Structure Choice:
        *   A `heapq` (priority queue) is standard for priority-based scheduling.
        *   To maintain FIFO for identical priorities in a min-heap (Python's `heapq` is a min-heap):
            *   Since we want *higher* numbers to have *higher* priority, we can store the priority as a negative value.
            *   To maintain FIFO, we should include a counter (sequence number) in the tuple stored in the heap.

    *   `heapq` module is necessary.
    *   State needed:
        *   `self._queue`: The heap.
        *   `self._counter`: A monotonically increasing integer to handle the FIFO tie-breaker.
    *   `add_job(name, data, priority=0)`:
        *   `counter = self._counter`
        *   `self._counter += 1`
        *   `heapq.heappush(self._queue, (-priority, counter, name, data))`
        *   Wait, if I use `-priority`, a priority of 2 becomes -2, priority 1 becomes -1. Min-heap will pick -2 first. That's correct.
        *   If priorities are equal (e.g., both -2), it compares `counter`. The smaller counter (inserted first) will be picked first. That satisfies FIFO.
    *   `get_next_job()`:
        *   If queue is empty, return `None`.
        *   `_, _, name, data = heapq.heappop(self._queue)`
        *   Return `(name, data)`.

    *   `heapq.heappush(heap, (-priority, self._counter, name, data))`
    *   `(-2, 0, "crit", ...)`
    *   `(-2, 1, "crit2", ...)`
    *   `(-1, 2, "high", ...)`
    *   `heappop` will give `(-2, 0, "crit", ...)` then `(-2, 1, "crit2", ...)` then `(-1, 2, "high", ...)`.
    *   This logic is sound.

    *   `add_job` signature: `add_job(self, name: str, data: dict, priority: int = 0)`
    *   `get_next_job` signature: `get_next_job(self) -> tuple[str, dict] | None`

    ```python
    import heapq

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

        def add_job(self, name: str, data: dict, priority: int = 0):
            # Use negative priority for max-heap behavior with heapq (min-heap)
            # Use self._counter to ensure FIFO for same priority
            heapq.heappush(self._queue, (-priority, self._counter, name, data))
            self._counter += 1

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

    *   `add_job` accepts `priority` (default 0).
    *   Higher priority first? Yes (-2 < -1).
    *   Same priority FIFO? Yes (counter).
    *   `get_next_job` returns `tuple[str, dict] | None`.
    *   Example check:
        *   "normal" (0) -> `(0, 0, "normal", ...)`
        *   "critical" (2) -> `(-2, 1, "critical", ...)`
        *   "high" (1) -> `(-1, 2, "high", ...)`
        *   Heap: `[(-2, 1, ...), (0, 0, ...), (-1, 2, ...)]` (roughly)
        *   Pop 1: `(-2, 1, ...)` -> critical. Correct.

    The user wants "Write only the Python code, no explanations."

    Final implementation structure:
    ```python
    import heapq

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

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

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

<content>
```python
import heapq

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

    def add_job(self, name: str, data: dict, priority: int = 0) -> None:
        # heapq is a min-heap. To treat higher priority numbers as higher priority,
        # we store the priority as a negative value.
        # The counter ensures FIFO order for jobs with the same priority.
        heapq.heappush(self._queue, (-priority, self._counter, name, data))
        self._counter += 1

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