"""
Authentication service for business logic.
Handles user registration, login, and session management.
"""

import logging
from datetime import timedelta
from typing import Optional

from fastapi import HTTPException, status
from sqlalchemy.orm import Session

from auth_utils import (
    create_access_token, 
    get_password_hash, 
    get_token_expiration, 
    verify_password
)
from config import settings
from models import User, UserSession
from schemas import UserLogin, UserRegister, TokenResponse, UserResponse

logger = logging.getLogger(__name__)


class AuthService:
    """Service for authentication operations."""
    
    @staticmethod
    def register_user(user_data: UserRegister, db: Session) -> dict:
        """Register new user."""
        logger.info(f"📝 Registration attempt: {user_data.email}")
        
        # Check if user already exists
        if db.query(User).filter(User.email == user_data.email).first():
            logger.warning(f"❌ Registration attempt with existing email: {user_data.email}")
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="User with this email already exists"
            )
        
        # Create new user
        new_user = User(
            email=user_data.email,
            name=user_data.name,
            password=get_password_hash(user_data.password),
            user_type="partner",
            rate="free"
        )
        
        try:
            db.add(new_user)
            db.commit()
            db.refresh(new_user)
            logger.info(f"✅ User registered successfully: {user_data.email} (ID: {new_user.id})")
        except Exception as e:
            logger.error(f"❌ Registration error for {user_data.email}: {e}")
            db.rollback()
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Error creating user"
            )
        
        return {"message": "User registered successfully", "success": True}
    
    @staticmethod
    def login_user(user_data: UserLogin, db: Session) -> TokenResponse:
        """Authenticate user and create session."""
        logger.info(f"🔐 Login attempt: {user_data.email}")
        
        # Find user by email
        user = db.query(User).filter(User.email == user_data.email).first()
        if not user:
            logger.warning(f"❌ Login attempt with non-existent email: {user_data.email}")
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Invalid email or password"
            )
        
        # Verify password
        if not verify_password(user_data.password, user.password):
            logger.warning(f"❌ Invalid password for user: {user_data.email}")
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Invalid email or password"
            )
        
        # Create access token
        access_token = create_access_token(
            data={"sub": str(user.id)},
            expires_delta=timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        )
        
        # Save session
        session = UserSession(
            user_id=user.id,
            token_hash=access_token,
            expires_at=get_token_expiration()
        )
        
        try:
            db.add(session)
            db.commit()
            logger.info(f"✅ Login successful: {user_data.email} (ID: {user.id})")
        except Exception as e:
            logger.error(f"❌ Session creation error for {user_data.email}: {e}")
            db.rollback()
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Error creating session"
            )
        
        return TokenResponse(
            access_token=access_token,
            expires_in=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60,
            user=UserResponse.from_orm(user)
        )
    
    @staticmethod
    def logout_user(current_user: User) -> dict:
        """Logout user."""
        logger.info(f"🚪 Logout: {current_user.email} (ID: {current_user.id})")
        # TODO: Invalidate token in production
        return {"message": "Logout successful", "success": True}
    
    @staticmethod
    def change_password(
        password_data, 
        current_user: User, 
        db: Session
    ) -> dict:
        """Change user password."""
        # Verify current password
        if not verify_password(password_data.current_password, current_user.password):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Invalid current password"
            )
        
        # Update password
        current_user.password = get_password_hash(password_data.new_password)
        db.commit()
        
        return {"message": "Password changed successfully", "success": True}
    
    @staticmethod
    def create_user_session(user: User, db: Session) -> str:
        """Create user session and return access token."""
        access_token = create_access_token(
            data={"sub": str(user.id)},
            expires_delta=timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        )
        
        session = UserSession(
            user_id=user.id,
            token_hash=access_token,
            expires_at=get_token_expiration()
        )
        
        try:
            db.add(session)
            db.commit()
        except Exception as e:
            logger.error(f"❌ Session creation error for user {user.email}: {e}")
            db.rollback()
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Error creating session"
            )
        
        return access_token 