"""Session create/validate/expire/touch."""

from __future__ import annotations

import secrets
from datetime import datetime, timedelta, timezone

from sqlalchemy import select

from cyclone.db import Session

SESSION_LIFETIME = timedelta(hours=24)


def create(db, *, user_id: int) -> tuple[str, Session]:
    sid = secrets.token_urlsafe(32)
    now = datetime.now(timezone.utc)
    expires_at = now + SESSION_LIFETIME
    sess = Session(
        id=sid,
        user_id=user_id,
        expires_at=expires_at,
        created_at=now,
    )
    db.add(sess)
    db.commit()
    db.refresh(sess)
    # SQLite strips tzinfo on roundtrip; restore it so callers don't have to.
    sess.expires_at = expires_at
    return sid, sess


def get_valid(db, sid: str) -> Session | None:
    sess = db.execute(
        select(Session).where(Session.id == sid)
    ).scalar_one_or_none()
    if sess is None:
        return None
    # SQLite drops tzinfo on roundtrip; normalize to UTC before comparing.
    if sess.expires_at.tzinfo is None:
        sess.expires_at = sess.expires_at.replace(tzinfo=timezone.utc)
    if sess.expires_at <= datetime.now(timezone.utc):
        return None
    return sess


def delete(db, sid: str) -> None:
    sess = db.get(Session, sid)
    if sess is None:
        return
    db.delete(sess)
    db.commit()


def touch(db, sid: str) -> None:
    sess = db.get(Session, sid)
    if sess is None:
        return
    sess.expires_at = datetime.now(timezone.utc) + SESSION_LIFETIME
    db.commit()