"""
Module: src.transcription.diarization
Workorder: WO02
Purpose: Speaker diarization mapping for transcript segments.

Dependencies:
    - typing: Type annotations

Inputs:
    - segments: Transcription segments

Outputs:
    - Speaker-enriched segments

Key Functions/Classes:
    - apply_diarization: Applies speaker attribution

Tests: tests/unit/test_placeholder.py
"""
from typing import Any

from src.shared.errors import DiarizationError


def _segment_overlap(start_a: float, end_a: float, start_b: float, end_b: float) -> float:
    return max(0.0, min(end_a, end_b) - max(start_a, start_b))


def apply_diarization(
    segments: list[dict[str, Any]],
    diarization_segments: list[dict[str, Any]] | None = None,
) -> list[dict[str, Any]]:
    """Assign speaker labels to transcript segments.

    Args:
        segments: Transcript segments.
        diarization_segments: Optional diarization intervals with speaker labels.

    Returns:
        Enriched transcript segments with best-matching speaker labels.

    Raises:
        DiarizationError: If inputs are malformed.
    """
    if not isinstance(segments, list):
        raise DiarizationError("segments must be a list")

    if diarization_segments is None:
        diarization_segments = []

    enriched_segments: list[dict[str, Any]] = []
    for segment in segments:
        try:
            start = float(segment.get("start", 0.0))
            end = float(segment.get("end", 0.0))
        except (TypeError, ValueError) as error:
            raise DiarizationError("Invalid segment start/end values") from error

        best_speaker = str(segment.get("speaker", "Speaker 0"))
        best_overlap = 0.0

        for diarization_segment in diarization_segments:
            try:
                d_start = float(diarization_segment.get("start", 0.0))
                d_end = float(diarization_segment.get("end", 0.0))
            except (TypeError, ValueError) as error:
                raise DiarizationError("Invalid diarization start/end values") from error

            overlap = _segment_overlap(start, end, d_start, d_end)
            if overlap > best_overlap:
                best_overlap = overlap
                best_speaker = str(diarization_segment.get("speaker", "Speaker 0"))

        enriched = dict(segment)
        enriched["speaker"] = best_speaker
        enriched_segments.append(enriched)

    return enriched_segments
