"""
Exporter per report in formato JSON.

Genera un file .json strutturato con tutti i dati del profilo,
utile per l'integrazione con altri strumenti o per analisi automatizzate.
"""

import json
from datetime import datetime

from .base import BaseExporter
from dataprofiler.models.dataset_profile import DatasetProfile
from dataprofiler.exceptions import ExportError


class JsonExporter(BaseExporter):
    """Esporta il profilo del dataset in formato JSON.

    Il JSON generato contiene tutte le informazioni del profilo
    in un formato strutturato e machine-readable.

    Esempio::

        exporter = JsonExporter()
        exporter.export(profile, "report.json")

        # Oppure come stringa
        json_string = exporter.to_string(profile)
    """

    def export(self, profile: DatasetProfile, output_path: str) -> None:
        """Scrive il report JSON su file.

        Args:
            profile: Profilo del dataset.
            output_path: Percorso del file .json da creare.

        Raises:
            ExportError: Se la scrittura del file fallisce.
        """
        try:
            content = self.to_string(profile)
            with open(output_path, "w", encoding="utf-8") as f:
                f.write(content)
        except OSError as e:
            raise ExportError(f"Impossibile scrivere il file '{output_path}': {e}")

    def to_string(self, profile: DatasetProfile) -> str:
        """Genera il report JSON come stringa.

        Args:
            profile: Profilo del dataset.

        Returns:
            Stringa JSON formattata con indentazione.
        """
        data = self._profile_to_dict(profile)
        return json.dumps(data, indent=2, ensure_ascii=False, default=str)

    def _profile_to_dict(self, profile: DatasetProfile) -> dict:
        """Converte un DatasetProfile in un dizionario serializzabile.

        Args:
            profile: Profilo del dataset.

        Returns:
            Dizionario pronto per la serializzazione JSON.
        """
        return {
            "dataprofiler_version": "0.1.0",
            "generato_il": profile.created_at.isoformat(),
            "dataset": {
                "file": profile.filename,
                "dimensione_bytes": profile.file_size_bytes,
                "righe": profile.row_count,
                "colonne": profile.column_count,
                "completezza_percentuale": round(profile.overall_completeness, 2),
                "valori_mancanti_totali": profile.total_missing,
                "celle_totali": profile.total_cells,
            },
            "warnings": profile.warnings,
            "colonne": [
                {
                    "nome": col.name,
                    "tipo": col.dtype.value,
                    "totale": col.total_count,
                    "mancanti": col.missing_count,
                    "mancanti_percentuale": round(col.missing_percentage, 2),
                    "completezza": round(col.completeness, 2),
                    "unici": col.unique_count,
                    "statistiche": col.stats,
                }
                for col in profile.columns
            ],
        }
