from __future__ import annotations

from datetime import datetime, timedelta, timezone
from zoneinfo import ZoneInfo

from config import settings

_KST = ZoneInfo('Asia/Seoul')
_BUCKET_MINUTES = 5


def normalize_bucket_kst(bucket: datetime) -> datetime:
    if bucket.tzinfo is None:
        return bucket
    return bucket.astimezone(_KST).replace(tzinfo=None)


def floor_bucket_kst(value: datetime, bucket_minutes: int = _BUCKET_MINUTES) -> datetime:
    if value.tzinfo is None:
        localized = value.replace(tzinfo=_KST)
    else:
        localized = value.astimezone(_KST)
    floored_minute = (localized.minute // bucket_minutes) * bucket_minutes
    return localized.replace(minute=floored_minute, second=0, microsecond=0)


def compute_safe_bucket(now: datetime | None = None) -> datetime:
    current = now or datetime.now(timezone.utc)
    if current.tzinfo is None:
        current = current.replace(tzinfo=timezone.utc)
    safe_point = current.astimezone(_KST) - timedelta(minutes=settings.SNPDB_SAFE_DELAY_MIN)
    return floor_bucket_kst(safe_point).replace(tzinfo=None)


def compute_initial_window_start(hours: int, safe_bucket: datetime | None = None) -> datetime:
    anchor = normalize_bucket_kst(safe_bucket or compute_safe_bucket())
    return anchor - timedelta(hours=hours)


def compute_incremental_window_start(last_bucket: datetime) -> datetime:
    normalized = normalize_bucket_kst(last_bucket)
    return normalized - timedelta(minutes=settings.SNPDB_BACKFILL_BUCKETS * _BUCKET_MINUTES)
