# meteo/quality.py
from __future__ import annotations

from dataclasses import dataclass
from typing import Dict

import pandas as pd


@dataclass(frozen=True)
class MissingValuesSummary:
    """
    Résumé des valeurs manquantes dans un DataFrame.
    """

    total_rows: int
    total_columns: int
    total_cells: int

    missing_cells: int
    missing_by_column: Dict[str, int]
    rows_with_missing: int
    rows_fully_complete: int

    @property
    def fraction_missing(self) -> float:
        return self.missing_cells / self.total_cells if self.total_cells else 0.0

    @property
    def fraction_rows_complete(self) -> float:
        return self.rows_fully_complete / self.total_rows if self.total_rows else 0.0


def summarize_missing_values(df: pd.DataFrame) -> MissingValuesSummary:
    """
    Calcule un résumé des valeurs manquantes d'un DataFrame.

    Ne modifie pas le DataFrame.
    """
    missing_mask = df.isna()

    total_rows, total_columns = df.shape
    total_cells = int(df.size)
    missing_cells = int(missing_mask.sum().sum())
    missing_by_column = missing_mask.sum().astype(int).to_dict()
    rows_with_missing = int(missing_mask.any(axis=1).sum())
    rows_fully_complete = int((~missing_mask.any(axis=1)).sum())

    return MissingValuesSummary(
        total_rows=total_rows,
        total_columns=total_columns,
        total_cells=total_cells,
        missing_cells=missing_cells,
        missing_by_column=missing_by_column,
        rows_with_missing=rows_with_missing,
        rows_fully_complete=rows_fully_complete,
    )
