<reasoning_content>
*   Goal: Implement priority-based job scheduling for a `JobQueue` class.
    *   Requirements:
        1.  `add_job(name, data, priority=0)`: New method signature.
        2.  Priority order: Higher priority (2) comes before lower priority (0).
        3.  FIFO for same priority: Order of insertion matters within same priority levels.
        4.  `get_next_job() -> tuple[str, dict] | None`: Method to retrieve and remove the highest priority job.
    *   Example usage provided.

    *   A priority queue is best implemented using a heap (priority queue data structure).
    *   Standard `heapq` in Python is a min-heap.
    *   Since higher numbers = higher priority, we can store priorities as negative values or use a custom comparison logic.
    *   To handle FIFO for same priority, we need a counter (sequence number) to ensure that if priorities are equal, the one with the smaller sequence number comes first.

    *   `self.queue`: A list to be used with `heapq`.
    *   `self.counter`: An integer to track insertion order.

    *   `add_job(name, data, priority=0)`:
        *   Push `(-priority, counter, name, data)` into the heap.
        *   Increment counter.
    *   `get_next_job()`:
        *   Pop from heap.
        *   Return `(name, data)` or `None` if empty.

    *   Wait, if I use `(-priority, counter, name, data)`, a min-heap will pick the most negative priority (which is the highest original priority).
    *   Example:
        *   Job A: Priority 0 (Normal) -> `(0, 0, "normal", {...})`
        *   Job B: Priority 2 (Critical) -> `(-2, 1, "critical", {...})`
        *   Job C: Priority 1 (High) -> `(-1, 2, "high", {...})`
    *   Min-heap pops:
        1. `(-2, 1, "critical", {...})`
        2. `(-1, 2, "high", {...})`
        3. `(0, 0, "normal", {...})`
    *   This satisfies both requirements (Priority and FIFO).

    ```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 using heapq min-heap
            # Use 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
            priority_neg, counter, name, data = heapq.heappop(self.queue)
            return (name, data)
    ```

    *   Requirements met?
        1. `add_job` takes optional priority=0. Yes.
        2. Higher priority before lower. Yes (via negative numbers in min-heap).
        3. Same priority FIFO. Yes (via counter).
        4. `get_next_job` returns tuple or None. Yes.

    *   "Write only the Python code, no explanations."
</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):
        # Use negative priority to simulate a max-heap using heapq (min-heap)
        # 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>