# app/api/v1/admin/auth.py
"""
Admin authentication endpoints.

Implements dual token storage with path restriction:
- Sets HTTP-only cookie with path=/admin (restricted to admin routes only)
- Returns token in response for localStorage (API calls)

This prevents admin cookies from being sent to vendor routes.
"""

import logging

from fastapi import APIRouter, Depends, Response
from sqlalchemy.orm import Session

from app.api.deps import get_current_admin_api
from app.core.database import get_db
from app.core.environment import should_use_secure_cookies
from app.exceptions import InvalidCredentialsException
from app.services.auth_service import auth_service
from models.database.user import User
from models.schema.auth import LoginResponse, LogoutResponse, UserLogin, UserResponse

router = APIRouter(prefix="/auth")
logger = logging.getLogger(__name__)


@router.post("/login", response_model=LoginResponse)
def admin_login(
    user_credentials: UserLogin, response: Response, db: Session = Depends(get_db)
):
    """
    Admin login endpoint.

    Only allows users with 'admin' role to login.
    Returns JWT token for authenticated admin users.

    Sets token in two places:
    1. HTTP-only cookie with path=/admin (for browser page navigation)
    2. Response body (for localStorage and API calls)

    The cookie is restricted to /admin/* routes only to prevent
    it from being sent to vendor or other routes.
    """
    # Authenticate user
    login_result = auth_service.login_user(db=db, user_credentials=user_credentials)

    # Verify user is admin
    if login_result["user"].role != "admin":
        logger.warning(
            f"Non-admin user attempted admin login: {user_credentials.email_or_username}"
        )
        raise InvalidCredentialsException("Admin access required")

    logger.info(f"Admin login successful: {login_result['user'].username}")

    # Set HTTP-only cookie for browser navigation
    # CRITICAL: path=/admin restricts cookie to admin routes only
    response.set_cookie(
        key="admin_token",
        value=login_result["token_data"]["access_token"],
        httponly=True,  # JavaScript cannot access (XSS protection)
        secure=should_use_secure_cookies(),  # HTTPS only in production/staging
        samesite="lax",  # CSRF protection
        max_age=login_result["token_data"]["expires_in"],  # Match JWT expiry
        path="/admin",  # RESTRICTED TO ADMIN ROUTES ONLY
    )

    logger.debug(
        f"Set admin_token cookie with {login_result['token_data']['expires_in']}s expiry "
        f"(path=/admin, httponly=True, secure={should_use_secure_cookies()})"
    )

    # Also return token in response for localStorage (API calls)
    return LoginResponse(
        access_token=login_result["token_data"]["access_token"],
        token_type=login_result["token_data"]["token_type"],
        expires_in=login_result["token_data"]["expires_in"],
        user=login_result["user"],
    )


@router.get("/me", response_model=UserResponse)
def get_current_admin(current_user: User = Depends(get_current_admin_api)):
    """
    Get current authenticated admin user.

    This endpoint validates the token and ensures the user has admin privileges.
    Returns the current user's information.

    Token can come from:
    - Authorization header (API calls)
    - admin_token cookie (browser navigation, path=/admin only)
    """
    logger.info(f"Admin user info requested: {current_user.username}")
    return current_user


@router.post("/logout", response_model=LogoutResponse)
def admin_logout(response: Response):
    """
    Admin logout endpoint.

    Clears the admin_token cookie.
    Client should also remove token from localStorage.
    """
    logger.info("Admin logout")

    # Clear the cookie (must match path used when setting)
    response.delete_cookie(
        key="admin_token",
        path="/admin",
    )

    logger.debug("Deleted admin_token cookie")

    return LogoutResponse(message="Logged out successfully")
