"""COM value utilities — normalize COM return types.

COM returns different shapes depending on range dimensions:
- scalar for 1x1
- flat tuple for 1-row
- tuple of tuples for multi-row
These helpers normalize to consistent list-of-lists.
"""


def normalize_2d(raw, rows: int, cols: int) -> list[list]:
    """Normalize COM .Value/.Formula return to a list-of-lists.

    Always returns ``rows`` x ``cols`` list-of-lists, regardless
    of the COM return shape.
    """
    if raw is None:
        return [[None] * cols for _ in range(rows)]

    if not isinstance(raw, tuple):
        # Scalar (1x1 range)
        return [[raw]]

    if rows == 1 and cols == 1:
        if isinstance(raw, tuple) and len(raw) == 1:
            inner = raw[0]
            if isinstance(inner, tuple):
                return [list(inner)]
            return [[inner]]
        return [[raw]]

    # Single-row range: COM may return flat tuple instead of tuple-of-tuples
    if raw and not isinstance(raw[0], tuple):
        if rows == 1:
            return [list(raw)]
        return [[v] for v in raw]

    # Tuple-of-tuples (row-major) for multi-cell ranges
    return [list(row) for row in raw]


def make_range(ws, sr: int, sc: int, er: int, ec: int):
    """Build a COM Range from 0-based (start_row, start_col, end_row, end_col)."""
    return ws.Range(
        ws.Cells(sr + 1, sc + 1),
        ws.Cells(er + 1, ec + 1),
    )
