# app/modules/tenancy/services/user_account_service.py
"""
Self-service account management for logged-in users.

Allows users to view/update their own profile and change password.
Used by admin, store, and merchant frontends.
"""

import logging

from sqlalchemy.orm import Session

from app.modules.tenancy.exceptions import (
    InvalidCredentialsException,
    UserAlreadyExistsException,
    UserNotFoundException,
)
from app.modules.tenancy.models import User
from middleware.auth import AuthManager

logger = logging.getLogger(__name__)


class UserAccountService:
    """Service for self-service account operations."""

    def __init__(self):
        self.auth_manager = AuthManager()

    def get_account(self, db: Session, user_id: int) -> User:
        """Get the logged-in user's account info."""
        user = db.query(User).filter(User.id == user_id).first()
        if not user:
            raise UserNotFoundException(str(user_id))
        return user

    def update_account(self, db: Session, user_id: int, update_data: dict) -> User:
        """Update the logged-in user's account info."""
        user = db.query(User).filter(User.id == user_id).first()
        if not user:
            raise UserNotFoundException(str(user_id))

        # Check email uniqueness if email is being changed
        new_email = update_data.get("email")
        if new_email and new_email != user.email:
            existing = (
                db.query(User)
                .filter(User.email == new_email, User.id != user_id)
                .first()
            )
            if existing:
                raise UserAlreadyExistsException(
                    "Email already registered", field="email"
                )

        # Apply updates (only provided fields)
        for field, value in update_data.items():
            if value is not None:
                setattr(user, field, value)

        db.flush()
        db.refresh(user)

        logger.info(f"User {user.username} updated account: {list(update_data.keys())}")
        return user

    def change_password(self, db: Session, user_id: int, password_data: dict) -> None:
        """Change the logged-in user's password."""
        user = db.query(User).filter(User.id == user_id).first()
        if not user:
            raise UserNotFoundException(str(user_id))

        current_password = password_data["current_password"]
        new_password = password_data["new_password"]
        confirm_password = password_data["confirm_password"]

        # Verify current password
        if not self.auth_manager.verify_password(current_password, user.hashed_password):
            raise InvalidCredentialsException("Current password is incorrect")

        # Validate new != current
        if self.auth_manager.verify_password(new_password, user.hashed_password):
            raise InvalidCredentialsException(
                "New password must be different from current password"
            )

        # Validate confirmation match
        if new_password != confirm_password:
            raise InvalidCredentialsException(
                "New password and confirmation do not match"
            )

        # Hash and save
        user.hashed_password = self.auth_manager.hash_password(new_password)
        db.flush()

        logger.info(f"User {user.username} changed password")  # noqa: SEC021


user_account_service = UserAccountService()
