"""
Console helpers for ABRomics SDK.

These utilities are lightweight and optional, intended for examples, demos,
and simple CLI-style scripts. They are not required to use the core client.
"""

from typing import Iterable, List, Mapping, Sequence


def format_table(headers: Sequence[str], rows: Iterable[Sequence[object]]) -> str:
    """
    Format a simple text table.

    Parameters
    ----------
    headers:
        Column header labels.
    rows:
        Iterable of row sequences. Each row should have the same length as
        ``headers``. Cells are converted to string with ``str()``.

    Returns
    -------
    str
        A string containing the formatted table, suitable for printing
        to a terminal.
    """
    rows_list: List[Sequence[object]] = list(rows)
    if not rows_list:
        return ""

    widths = [len(str(h)) for h in headers]
    for row in rows_list:
        for i, cell in enumerate(row):
            widths[i] = max(widths[i], len(str(cell)))

    sep = "  "
    header_line = sep.join(str(h).ljust(widths[i]) for i, h in enumerate(headers))
    divider = "-" * len(header_line)

    lines = [header_line, divider]
    for row in rows_list:
        lines.append(sep.join(str(c).ljust(widths[i]) for i, c in enumerate(row)))

    return "\n".join(lines)


def build_batch_result_table(
    result: Mapping[str, object], max_error_len: int = 60
) -> str:
    """
    Build a text table summarizing a batch `process_tsv_and_upload` result.

    This inspects the typical structure returned by
    ``client.batch.process_tsv_and_upload`` and prefers upload-level details
    when available, otherwise falls back to sample-creation results.
    """
    tsv_results = (
        result.get("tsv_processing")  # type: ignore[assignment]
        or result.get("samples")  # type: ignore[assignment]
        or []
    )
    upload_results = (
        result.get("file_upload")  # type: ignore[assignment]
        or result.get("uploads")  # type: ignore[assignment]
        or []
    )

    # Prefer upload-level summary if there are uploads
    if upload_results:
        rows: List[Sequence[object]] = []
        for r in upload_results:  # type: ignore[assignment]
            project_name = getattr(r, "get", lambda k, d=None: d)(
                "project_name", ""
            )
            sample_name = getattr(r, "get", lambda k, d=None: d)("sample_name", "")
            file_path = getattr(r, "get", lambda k, d=None: d)("file_path", "") or ""
            success = bool(getattr(r, "get", lambda k, d=None: d)("success", False))
            error = getattr(r, "get", lambda k, d=None: d)("error", "") or ""
            rows.append(
                [
                    project_name or "",
                    sample_name or "",
                    str(file_path).split("/")[-1],
                    "OK" if success else "FAIL",
                    str(error)[:max_error_len],
                ]
            )
        return format_table(
            ["Project", "Sample", "File", "Status", "Error (truncated)"], rows
        )

    # Otherwise show sample creation status, if any
    if tsv_results:
        rows = []
        for r in tsv_results:  # type: ignore[assignment]
            sample_name = getattr(r, "get", lambda k, d=None: d)("sample_name", "")
            sample_id = getattr(r, "get", lambda k, d=None: d)("sample_id", "")
            success = bool(getattr(r, "get", lambda k, d=None: d)("success", False))
            error = getattr(r, "get", lambda k, d=None: d)("error", "") or ""
            rows.append(
                [
                    sample_name or "",
                    sample_id or "",
                    "OK" if success else "FAIL",
                    str(error)[:max_error_len],
                ]
            )
        return format_table(
            ["Sample", "Sample ID", "Status", "Error (truncated)"], rows
        )

    return ""

