"""
Modello per il profilo di una singola colonna.

Contiene l'enum ColumnType per classificare il tipo di dato
e la dataclass ColumnProfile con tutte le statistiche raccolte.
"""

from dataclasses import dataclass, field
from enum import Enum
from typing import Any


class ColumnType(Enum):
    """Tipo di dato rilevato in una colonna del dataset.

    Attributes:
        NUMERIC: Valori numerici (interi o decimali).
        TEXT: Stringhe di testo generico.
        DATETIME: Date e orari.
        BOOLEAN: Valori vero/falso.
        UNKNOWN: Tipo non determinabile.
    """
    NUMERIC = "numeric"
    TEXT = "text"
    DATETIME = "datetime"
    BOOLEAN = "boolean"
    UNKNOWN = "unknown"


@dataclass
class ColumnProfile:
    """Profilo statistico di una singola colonna di un dataset.

    Raccoglie tutte le informazioni analizzate su una colonna:
    tipo di dato, conteggi, valori unici e statistiche specifiche
    per il tipo (media, mediana per numerici; lunghezze per testo, ecc.).

    Attributes:
        name: Nome della colonna.
        dtype: Tipo di dato rilevato.
        total_count: Numero totale di righe.
        missing_count: Numero di valori mancanti.
        unique_count: Numero di valori unici (non-null).
        stats: Dizionario con statistiche specifiche per il tipo.

    Esempio::

        col = ColumnProfile(
            name="età",
            dtype=ColumnType.NUMERIC,
            total_count=100,
            missing_count=5,
            unique_count=40,
            stats={"media": 25.3, "mediana": 24.0}
        )
        print(col.completeness)  # 95.0
    """
    name: str
    dtype: ColumnType = ColumnType.UNKNOWN
    total_count: int = 0
    missing_count: int = 0
    unique_count: int = 0
    stats: dict[str, Any] = field(default_factory=dict)

    @property
    def missing_percentage(self) -> float:
        """Percentuale di valori mancanti sulla colonna.

        Returns:
            Percentuale da 0.0 a 100.0.
        """
        if self.total_count == 0:
            return 0.0
        return (self.missing_count / self.total_count) * 100

    @property
    def completeness(self) -> float:
        """Percentuale di completezza (complemento dei mancanti).

        Returns:
            Percentuale da 0.0 a 100.0.
        """
        return 100.0 - self.missing_percentage

    def __str__(self) -> str:
        return (
            f"ColumnProfile('{self.name}', tipo={self.dtype.value}, "
            f"completo={self.completeness:.1f}%, unici={self.unique_count})"
        )
