"""Screenshot filename helpers: ``{utc_timestamp}_{ulid}.{ext}``."""

from __future__ import annotations

import datetime
import os
import re
import time

# Crockford Base32 (ULID alphabet) — no I, L, O, U
_CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"

# New: 1721228573_01ARZ3NDEKTSV4RRFFQ69G5FAV
_NEW_STEM_RE = re.compile(r"^(\d{10,13})_([0-9A-HJKMNP-TV-Z]{26})$", re.IGNORECASE)
# Legacy: 20260717_160153.834123
_LEGACY_STEM_RE = re.compile(r"^(\d{8})_(\d{6})(?:\.(\d+))?$")


def new_ulid() -> str:
    """Generate a 26-char Crockford Base32 ULID (timestamp-ms + entropy)."""
    ms = int(time.time() * 1000) & ((1 << 48) - 1)
    entropy = int.from_bytes(os.urandom(10), "big")
    value = (ms << 80) | entropy
    chars = []
    for _ in range(26):
        chars.append(_CROCKFORD[value & 31])
        value >>= 5
    return "".join(reversed(chars))


def make_screenshot_filename(ext: str, *, offset_seconds: int = 0) -> str:
    """Build ``{utc_timestamp}_{ulid}.{ext}`` (UTC unix seconds + ULID)."""
    utc_ts = int(time.time()) + int(offset_seconds)
    clean_ext = str(ext).lstrip(".").lower()
    return f"{utc_ts}_{new_ulid()}.{clean_ext}"


def parse_screenshot_stem(stem: str) -> tuple[int, datetime.datetime]:
    """Parse filename stem → ``(utc_unix_seconds, local datetime)``.

    Supports new ``{utc_timestamp}_{ulid}`` and legacy ``YYYYMMDD_HHMMSS.ffffff``.
    """
    stem = stem.strip()
    new_match = _NEW_STEM_RE.match(stem)
    if new_match:
        utc_ts = int(new_match.group(1))
        # Truncate ms timestamps to seconds for S3 / date folders
        if utc_ts > 10_000_000_000:
            utc_ts //= 1000
        return utc_ts, datetime.datetime.fromtimestamp(utc_ts)

    legacy_match = _LEGACY_STEM_RE.match(stem)
    if legacy_match:
        date_part, time_part, frac = legacy_match.group(1), legacy_match.group(2), legacy_match.group(3)
        fmt = "%Y%m%d_%H%M%S.%f" if frac else "%Y%m%d_%H%M%S"
        value = f"{date_part}_{time_part}.{frac}" if frac else f"{date_part}_{time_part}"
        dt = datetime.datetime.strptime(value, fmt)
        return int(dt.timestamp()), dt

    raise ValueError(f"Unrecognized screenshot filename stem: {stem!r}")


def parse_screenshot_datetime(filename: str) -> datetime.datetime:
    """Extract local datetime from a screenshot path or basename."""
    basename = os.path.basename(filename.replace("\\", "/"))
    stem, _ = os.path.splitext(basename)
    _, dt = parse_screenshot_stem(stem)
    return dt


def parse_screenshot_utc_timestamp(filename: str) -> int:
    """Extract UTC unix seconds from a screenshot path or basename."""
    basename = os.path.basename(filename.replace("\\", "/"))
    stem, _ = os.path.splitext(basename)
    utc_ts, _ = parse_screenshot_stem(stem)
    return utc_ts
