"""JSON reporter for CI/CD integration."""

from __future__ import annotations

import json
import sys
from typing import TYPE_CHECKING, Any, TextIO

from django_safe_migrations.reporters.base import BaseReporter

if TYPE_CHECKING:
    from django_safe_migrations.rules.base import Issue


class JsonReporter(BaseReporter):
    """Reporter that outputs issues as JSON.

    Useful for CI/CD pipelines and integration with other tools.
    """

    def __init__(
        self,
        stream: TextIO | None = None,
        pretty: bool = False,
    ):
        """Initialize the JSON reporter.

        Args:
            stream: Output stream. Defaults to sys.stdout.
            pretty: Whether to pretty-print the JSON.
        """
        super().__init__(stream or sys.stdout)
        self.pretty = pretty

    def report(self, issues: list[Issue]) -> str:
        """Generate a JSON report for the issues.

        Args:
            issues: List of issues to report.

        Returns:
            The JSON report as a string.
        """
        data: dict[str, Any] = {
            "total": len(issues),
            "issues": [issue.to_dict() for issue in issues],
            "summary": self._get_summary(issues),
        }

        if self.pretty:
            output = json.dumps(data, indent=2, sort_keys=True)
        else:
            output = json.dumps(data)

        self.write(output)
        return output

    @staticmethod
    def _get_summary(issues: list[Issue]) -> dict[str, Any]:
        """Generate a summary of the issues.

        Delegates to MigrationAnalyzer.get_summary() and remaps keys
        to the JSON reporter's flat format for backward compatibility.

        Args:
            issues: List of issues to summarize.

        Returns:
            Summary dictionary.
        """
        from django_safe_migrations.analyzer import MigrationAnalyzer

        raw = MigrationAnalyzer.get_summary(issues)
        by_sev = raw.get("by_severity", {})
        return {
            "errors": by_sev.get("error", 0),
            "warnings": by_sev.get("warning", 0),
            "info": by_sev.get("info", 0),
            "by_rule": raw.get("by_rule", {}),
            "by_app": raw.get("by_app", {}),
        }
