import uuid
from datetime import datetime, timezone
from typing import Tuple

from sqlalchemy.orm import Session as OrmSession

from app.core.errors import AppError
from app.core.security import verify_password, create_session_token, session_expires_at
from app.i18n.loader import t
from app.logging.activity_logger import ActivityLogger
from app.models.catalog import UserAccount, Session


class AuthService:
    def __init__(self, db: OrmSession) -> None:
        self._db = db
        self._logger = ActivityLogger(db)

    def login(self, username: str, password: str, ip: str | None = None) -> Tuple[UserAccount, str]:
        user = self._db.query(UserAccount).filter(UserAccount.username == username).first()
        if not user or not verify_password(password, user.password_hash):
            raise AppError(
                code="auth.login_failed",
                message=t("auth.login_failed"),
                status_code=401,
            )

        if not user.is_active:
            raise AppError(
                code="user.deactivated",
                message=t("user.deactivated"),
                status_code=403,
            )

        token = create_session_token()
        now = datetime.now(timezone.utc).isoformat()
        session = Session(
            id=token,
            user_id=user.id,
            created_at=now,
            expires_at=session_expires_at(),
        )
        self._db.add(session)
        self._db.commit()

        self._logger.log(
            actor_id=user.id,
            action="auth.login",
            resource_type="session",
            resource_id=token,
            ip_address=ip,
        )

        return user, token

    def logout(self, session_id: str, user_id: str, ip: str | None = None) -> None:
        session = self._db.query(Session).filter(Session.id == session_id).first()
        if session:
            self._db.delete(session)
            self._db.commit()

        self._logger.log(
            actor_id=user_id,
            action="auth.logout",
            resource_type="session",
            resource_id=session_id,
            ip_address=ip,
        )
