"""Shared utilities for Scout checks."""

from __future__ import annotations

import re
from datetime import datetime, timezone
from typing import Iterable, List, TypeVar

T = TypeVar("T")


def parse_sf_datetime(value: str | None) -> datetime | None:
    if not value:
        return None
    text = str(value).strip()
    if not text:
        return None
    if text.isdigit():
        try:
            num = int(text)
        except Exception:
            num = 0
        if num:
            # HubSpot timestamps are milliseconds since epoch.
            if num > 10**11:
                return datetime.fromtimestamp(num / 1000.0, tz=timezone.utc)
            return datetime.fromtimestamp(num, tz=timezone.utc)
    if len(text) == 10:
        try:
            return datetime.fromisoformat(text)
        except Exception:
            return None
    if text.endswith("Z"):
        text = text[:-1] + "+00:00"
    if re.match(r".*[+-]\d{4}$", text):
        text = text[:-5] + text[-5:-2] + ":" + text[-2:]
    try:
        dt = datetime.fromisoformat(text)
    except Exception:
        return None
    if dt.tzinfo is None:
        return dt.replace(tzinfo=timezone.utc)
    return dt


def days_since(value: str | None) -> int | None:
    dt = parse_sf_datetime(value)
    if not dt:
        return None
    now = datetime.now(timezone.utc)
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=timezone.utc)
    return (now - dt).days


def hours_since(value: str | None) -> float | None:
    dt = parse_sf_datetime(value)
    if not dt:
        return None
    now = datetime.now(timezone.utc)
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=timezone.utc)
    return (now - dt).total_seconds() / 3600.0


def chunked(items: List[T], size: int = 150) -> Iterable[List[T]]:
    for i in range(0, len(items), size):
        yield items[i : i + size]


__all__ = ["parse_sf_datetime", "days_since", "hours_since", "chunked"]
