"""
Authentication service with OIDC and social media support
"""
from datetime import datetime, timedelta
from typing import Optional
from jose import jwt
from fastapi import HTTPException, status
from sqlalchemy.orm import Session

from ..config.settings import settings
from ..models import User
from ..database import SessionLocal


def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    """Create a JWT access token"""
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
    return encoded_jwt


def verify_token(token: str) -> dict:
    """Verify a JWT token and return the payload"""
    try:
        payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
        return payload
    except jwt.JWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Could not validate credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )


def authenticate_user(db: Session, username: str, password: str) -> Optional[User]:
    """Authenticate a user with username and password"""
    user = db.query(User).filter(User.username == username).first()
    if not user or not verify_password_correct(password, user.hashed_password):
        return None
    if not user.is_active:
        return None
    return user


async def get_oidc_config():
    """Get OIDC configuration"""
    return {
        "issuer": settings.OIDC_ISSUER,
        "authorization_endpoint": f"{settings.OIDC_ISSUER}/authorize" if settings.OIDC_ISSUER else None,
        "token_endpoint": f"{settings.OIDC_ISSUER}/token" if settings.OIDC_ISSUER else None,
        "userinfo_endpoint": f"{settings.OIDC_ISSUER}/userinfo" if settings.OIDC_ISSUER else None,
        "jwks_uri": f"{settings.OIDC_ISSUER}/.well-known/jwks.json" if settings.OIDC_ISSUER else None,
        "client_id": settings.OIDC_CLIENT_ID,
        "redirect_uri": settings.OIDC_REDIRECT_URI,
    }


async def handle_oidc_callback(code: str) -> User:
    """
    Handle OIDC callback and return or create a user
    This is a simplified implementation - in a real app you'd exchange the code
    for tokens and fetch user info from the OIDC provider
    """
    # In a real implementation, you would:
    # 1. Exchange the authorization code for access/id tokens
    # 2. Validate the ID token
    # 3. Fetch user info from the userinfo endpoint
    # 4. Create or update the user in your database
    # 5. Return the user object
    
    # For now, return a placeholder - this would be replaced with real OIDC logic
    raise NotImplementedError("OIDC callback handling not fully implemented")


async def handle_social_login(provider: str, access_token: str) -> User:
    """
    Handle social media login (Google, Facebook, etc.)
    This is a simplified implementation
    """
    # In a real implementation, you would:
    # 1. Validate the access token with the social provider
    # 2. Fetch user info from the provider's API
    # 3. Create or update the user in your database
    # 4. Return the user object
    
    # For now, return a placeholder - this would be replaced with real social login logic
    raise NotImplementedError("Social login handling not fully implemented")


def hash_password(password: str) -> str:
    """
    Hash a password using bcrypt
    """
    from ..utils.security import get_password_hash
    return get_password_hash(password)


def verify_password_correct(plain_password: str, hashed_password: str) -> bool:
    """
    Verify a plain password against its hash
    """
    from ..utils.security import verify_password as verify_password_util
    return verify_password_util(plain_password, hashed_password)