"""Calculate row-level completeness scores."""

from __future__ import annotations

from typing import Any, Dict, Iterable, List, Sequence


def _normalize_headers(headers: Sequence[Any], length: int) -> List[str]:
    normalized: List[str] = []
    for idx in range(length):
        raw = "" if headers is None or idx >= len(headers) else headers[idx]
        label = str(raw).strip() if raw is not None else ""
        if not label:
            label = f"Column {idx + 1}"
        normalized.append(label)
    return normalized


def _is_non_empty(value: Any) -> bool:
    if value is None:
        return False
    if isinstance(value, str):
        return value.strip() != ""
    return True


def _calculate_completeness(
    row: Sequence[Any], headers: Sequence[Any], ignore_columns: Iterable[int]
) -> Dict[str, Any]:
    length = len(row)
    normalized_headers = _normalize_headers(headers, length)
    ignored = {int(i) for i in (ignore_columns or [])}

    considered_indexes = [idx for idx in range(length) if idx not in ignored]
    if not considered_indexes:
        return {
            "value": ["", ""],
            "meta": {
                "filled": 0,
                "total": 0,
                "missing_indexes": [],
                "missing_headers": [],
            },
        }

    filled = 0
    missing_headers: List[str] = []
    missing_indexes: List[int] = []

    for idx in considered_indexes:
        if _is_non_empty(row[idx]):
            filled += 1
        else:
            missing_indexes.append(idx)
            missing_headers.append(normalized_headers[idx])

    percentage = (
        round((filled / len(considered_indexes)) * 100) if considered_indexes else 0
    )
    missing_summary = ", ".join(missing_headers)

    return {
        "value": [f"{percentage}%", missing_summary],
        "meta": {
            "filled": filled,
            "total": len(considered_indexes),
            "missing_indexes": missing_indexes,
            "missing_headers": missing_headers,
        },
    }


def calculate_completeness(payload: Dict[str, Any]) -> Dict[str, Any]:
    row = payload.get("row") or []
    headers = payload.get("headers") or []
    ignore = payload.get("ignore_columns") or []

    if payload.get("is_header"):
        return {"value": ["", ""], "meta": {"reason": "header_row"}}

    return _calculate_completeness(row, headers, ignore)
