"""Domain.services.comma_density_service
Where: Domain service module providing reusable business logic.
What: Houses service routines and helpers implemented in this module.
Why: Makes this service behaviour accessible to application workflows.
"""

from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True)
class CommaAvgFinding:
    """Result describing corpus-level comma average variance."""

    average: float
    min_avg: float
    max_avg: float


@dataclass(frozen=True)
class CommaOveruseFinding:
    """Result capturing a sentence that exceeds the comma usage threshold."""

    sentence_index: int
    count: int
    max_allowed: int


class CommaDensityService:
    """Analyse comma density across sentences to detect readability issues."""

    def analyze(
        self,
        sentences: list[str],
        *,
        min_avg: float,
        max_avg: float,
        per_sentence_max: int,
    ) -> tuple[CommaAvgFinding | None, list[CommaOveruseFinding]]:
        """Compute average comma usage and flag sentences exceeding limits.

        Args:
            sentences: Ordered collection of sentence strings to analyse.
            min_avg: Lower bound for acceptable average comma count.
            max_avg: Upper bound for acceptable average comma count.
            per_sentence_max: Maximum allowed commas in a single sentence.

        Returns:
            A tuple of optional corpus-level finding and a list of per-sentence
            overuse findings.
        """

        if not sentences:
            return None, []
        counts = [s.count("、") for s in sentences]
        avg = sum(counts) / max(len(counts), 1)
        avg_finding: CommaAvgFinding | None = None
        if avg < min_avg or avg > max_avg:
            avg_finding = CommaAvgFinding(average=avg, min_avg=min_avg, max_avg=max_avg)
        over: list[CommaOveruseFinding] = []
        for idx, c in enumerate(counts):
            if c > per_sentence_max:
                over.append(CommaOveruseFinding(sentence_index=idx, count=c, max_allowed=per_sentence_max))
        return avg_finding, over
