"""DMS查询接口统一的带时区ISO 8601时间范围解析。"""

from __future__ import annotations

from datetime import datetime, timezone
from typing import Mapping

from dms.common.errors import InvalidArgumentError


def parse_datetime(value: str | None, *, name: str) -> datetime | None:
    """解析带明确时区的ISO 8601时间并转换为UTC无时区值。"""
    if value is None:
        return None
    if not isinstance(value, str) or not value.strip():
        raise InvalidArgumentError(f"{name}必须是包含时区的ISO 8601时间")
    normalized = value.strip()
    if normalized.endswith(("Z", "z")):
        normalized = normalized[:-1] + "+00:00"
    try:
        parsed = datetime.fromisoformat(normalized)
    except ValueError as exc:
        raise InvalidArgumentError(
            f"{name}必须是包含时区的ISO 8601时间"
        ) from exc
    if parsed.tzinfo is None or parsed.utcoffset() is None:
        raise InvalidArgumentError(f"{name}必须包含明确时区")
    return parsed.astimezone(timezone.utc).replace(tzinfo=None)


def parse_updated_range(
    params: Mapping[str, str],
) -> tuple[datetime | None, datetime | None]:
    """解析updatedFrom/updatedTo并校验闭区间方向。"""
    updated_from = parse_datetime(params.get("updatedFrom"), name="updatedFrom")
    updated_to = parse_datetime(params.get("updatedTo"), name="updatedTo")
    if (
        updated_from is not None
        and updated_to is not None
        and updated_from > updated_to
    ):
        raise InvalidArgumentError("updatedFrom不得晚于updatedTo")
    return updated_from, updated_to


__all__ = ["parse_datetime", "parse_updated_range"]
