"""Timezone helpers. Everything is stored in UTC (timestamptz) and presented in Asia/Dhaka."""
from datetime import date, datetime, time, timedelta, timezone
from zoneinfo import ZoneInfo

from app.core.config import settings

DHAKA = ZoneInfo(settings.TIMEZONE)
UTC = timezone.utc


def utcnow() -> datetime:
    """Timezone-aware 'now' in UTC — the canonical storage value."""
    return datetime.now(UTC)


def now_local() -> datetime:
    """'Now' rendered in Asia/Dhaka."""
    return datetime.now(DHAKA)


def today_local() -> date:
    """Business 'today' in Asia/Dhaka (not the server's date)."""
    return now_local().date()


def to_local(dt: datetime | None) -> datetime | None:
    if dt is None:
        return None
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=UTC)
    return dt.astimezone(DHAKA)


def to_utc(dt: datetime | None) -> datetime | None:
    if dt is None:
        return None
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=DHAKA)
    return dt.astimezone(UTC)


def day_bounds_utc(day: date) -> tuple[datetime, datetime]:
    """UTC [start, end) covering a full Asia/Dhaka calendar day."""
    start = datetime.combine(day, time.min, tzinfo=DHAKA).astimezone(UTC)
    end = datetime.combine(day + timedelta(days=1), time.min, tzinfo=DHAKA).astimezone(UTC)
    return start, end


def range_bounds_utc(date_from: date | None, date_to: date | None) -> tuple[datetime | None, datetime | None]:
    """UTC bounds for an inclusive Asia/Dhaka date range."""
    start = datetime.combine(date_from, time.min, tzinfo=DHAKA).astimezone(UTC) if date_from else None
    end = (
        datetime.combine(date_to + timedelta(days=1), time.min, tzinfo=DHAKA).astimezone(UTC)
        if date_to
        else None
    )
    return start, end


def minutes_between(start: datetime | None, end: datetime | None) -> int | None:
    if start is None or end is None:
        return None
    if start.tzinfo is None:
        start = start.replace(tzinfo=UTC)
    if end.tzinfo is None:
        end = end.replace(tzinfo=UTC)
    return int((end - start).total_seconds() // 60)
