"""Tag reading, formatting, and resolution helpers."""

from typing import Any, List, Union

import pydicom
from pydicom import datadict, multival

from dicom_mcp.constants import COMMON_TAGS


def _safe_get_tag(
    ds: pydicom.Dataset, tag: Union[str, int, tuple[int, int]], default: str = "N/A"
) -> str:
    """Safely extract a DICOM tag value with fallback."""
    try:
        value = ds.get(tag, default)
        if value == default:
            return default
        if hasattr(value, "value"):
            return str(value.value)
        return str(value)
    except Exception:
        return default


def _format_tag_value(tag: tuple, value: Any) -> str:
    """Format a DICOM tag value for display."""
    if value is None or value == "":
        return "N/A"

    if isinstance(value, pydicom.sequence.Sequence):
        return f"[Sequence with {len(value)} items]"

    if isinstance(value, multival.MultiValue):
        return "\\".join(str(v) for v in value)

    return str(value)


def _resolve_tag(spec: str) -> tuple:
    """Resolve a tag keyword or hex pair to ((group, elem), display_name).

    Accepts:
      - Hex pairs: "0018,0081" or "0018, 0081"
      - Keywords: "EchoTime", "PatientName", etc.

    Returns:
        (tag_tuple, display_name) where tag_tuple is None if unresolvable.
    """
    spec = spec.strip()
    # Try hex pair first: "0018,0081" or "0018, 0081"
    if "," in spec:
        parts = spec.split(",")
        if len(parts) == 2:
            try:
                group = int(parts[0].strip(), 16)
                elem = int(parts[1].strip(), 16)
                tag_tuple = (group, elem)
                keyword = datadict.keyword_for_tag(tag_tuple)
                name = (
                    keyword if keyword else f"({parts[0].strip()},{parts[1].strip()})"
                )
                return tag_tuple, name
            except ValueError:
                pass
    # Try as keyword: "EchoTime", "PatientName", etc.
    try:
        tag_tuple = datadict.tag_for_keyword(spec)
        if tag_tuple is not None:
            return tag_tuple, spec
    except Exception:
        pass
    return None, spec


def _validate_tag_groups(requested: list[str]) -> list[str]:
    """Validate tag group names, returning list of invalid ones."""
    return [g for g in requested if g not in COMMON_TAGS]


def _format_markdown_table(headers: List[str], rows: List[List[str]]) -> str:
    """Format data as a Markdown table."""
    col_widths = [len(h) for h in headers]
    for row in rows:
        for i, cell in enumerate(row):
            col_widths[i] = max(col_widths[i], len(str(cell)))

    header_row = " | ".join(h.ljust(col_widths[i]) for i, h in enumerate(headers))
    separator = "-|-".join("-" * w for w in col_widths)

    data_rows = []
    for row in rows:
        data_rows.append(
            " | ".join(str(cell).ljust(col_widths[i]) for i, cell in enumerate(row))
        )

    return f"{header_row}\n{separator}\n" + "\n".join(data_rows)
