"""
Authentication API Endpoints für BreakPilot
Proxy für den Go Consent Service Authentication
"""

import httpx
from fastapi import APIRouter, HTTPException, Header, Request, Response
from typing import Optional
from pydantic import BaseModel, EmailStr
import os

# Consent Service URL
CONSENT_SERVICE_URL = os.getenv("CONSENT_SERVICE_URL", "http://localhost:8081")

router = APIRouter(prefix="/auth", tags=["authentication"])


# ==========================================
# Request/Response Models
# ==========================================

class RegisterRequest(BaseModel):
    email: EmailStr
    password: str
    name: Optional[str] = None


class LoginRequest(BaseModel):
    email: EmailStr
    password: str


class RefreshTokenRequest(BaseModel):
    refresh_token: str


class VerifyEmailRequest(BaseModel):
    token: str


class ForgotPasswordRequest(BaseModel):
    email: EmailStr


class ResetPasswordRequest(BaseModel):
    token: str
    new_password: str


class ChangePasswordRequest(BaseModel):
    current_password: str
    new_password: str


class UpdateProfileRequest(BaseModel):
    name: Optional[str] = None


class LogoutRequest(BaseModel):
    refresh_token: Optional[str] = None


# ==========================================
# Helper Functions
# ==========================================

def get_auth_headers(authorization: Optional[str]) -> dict:
    """Erstellt Header mit Authorization Token"""
    headers = {"Content-Type": "application/json"}
    if authorization:
        headers["Authorization"] = authorization
    return headers


async def proxy_to_consent_service(
    method: str,
    path: str,
    json_data: dict = None,
    headers: dict = None,
    params: dict = None
) -> dict:
    """
    Proxy-Aufruf zum Go Consent Service.
    Wirft HTTPException bei Fehlern.
    """
    url = f"{CONSENT_SERVICE_URL}/api/v1{path}"

    async with httpx.AsyncClient() as client:
        try:
            if method == "GET":
                response = await client.get(url, headers=headers, params=params, timeout=10.0)
            elif method == "POST":
                response = await client.post(url, headers=headers, json=json_data, timeout=10.0)
            elif method == "PUT":
                response = await client.put(url, headers=headers, json=json_data, timeout=10.0)
            elif method == "DELETE":
                response = await client.delete(url, headers=headers, params=params, timeout=10.0)
            else:
                raise ValueError(f"Unsupported HTTP method: {method}")

            # Parse JSON response
            try:
                data = response.json()
            except:
                data = {"message": response.text}

            # Handle error responses
            if response.status_code >= 400:
                error_msg = data.get("error", "Unknown error")
                raise HTTPException(status_code=response.status_code, detail=error_msg)

            return data

        except httpx.RequestError as e:
            raise HTTPException(
                status_code=503,
                detail=f"Consent Service nicht erreichbar: {str(e)}"
            )


# ==========================================
# Public Auth Endpoints (No Auth Required)
# ==========================================

@router.post("/register")
async def register(request: RegisterRequest, req: Request):
    """
    Registriert einen neuen Benutzer.
    Sendet eine Verifizierungs-E-Mail.
    """
    data = await proxy_to_consent_service(
        "POST",
        "/auth/register",
        json_data={
            "email": request.email,
            "password": request.password,
            "name": request.name
        }
    )
    return data


@router.post("/login")
async def login(request: LoginRequest, req: Request):
    """
    Meldet einen Benutzer an.
    Gibt Access Token und Refresh Token zurück.
    """
    # Get client info for session tracking
    client_ip = req.client.host if req.client else "unknown"
    user_agent = req.headers.get("user-agent", "unknown")

    data = await proxy_to_consent_service(
        "POST",
        "/auth/login",
        json_data={
            "email": request.email,
            "password": request.password
        },
        headers={
            "X-Forwarded-For": client_ip,
            "User-Agent": user_agent
        }
    )
    return data


@router.post("/logout")
async def logout(request: LogoutRequest):
    """
    Meldet den Benutzer ab und invalidiert den Refresh Token.
    """
    data = await proxy_to_consent_service(
        "POST",
        "/auth/logout",
        json_data={"refresh_token": request.refresh_token} if request.refresh_token else {}
    )
    return data


@router.post("/refresh")
async def refresh_token(request: RefreshTokenRequest):
    """
    Erneuert den Access Token mit einem gültigen Refresh Token.
    """
    data = await proxy_to_consent_service(
        "POST",
        "/auth/refresh",
        json_data={"refresh_token": request.refresh_token}
    )
    return data


@router.post("/verify-email")
async def verify_email(request: VerifyEmailRequest):
    """
    Verifiziert die E-Mail-Adresse mit dem Token aus der E-Mail.
    """
    data = await proxy_to_consent_service(
        "POST",
        "/auth/verify-email",
        json_data={"token": request.token}
    )
    return data


@router.post("/resend-verification")
async def resend_verification(email: EmailStr):
    """
    Sendet die Verifizierungs-E-Mail erneut.
    """
    data = await proxy_to_consent_service(
        "POST",
        "/auth/resend-verification",
        json_data={"email": email}
    )
    return data


@router.post("/forgot-password")
async def forgot_password(request: ForgotPasswordRequest, req: Request):
    """
    Initiiert den Passwort-Reset-Prozess.
    Sendet eine E-Mail mit Reset-Link.
    """
    client_ip = req.client.host if req.client else "unknown"

    data = await proxy_to_consent_service(
        "POST",
        "/auth/forgot-password",
        json_data={"email": request.email},
        headers={"X-Forwarded-For": client_ip}
    )
    return data


@router.post("/reset-password")
async def reset_password(request: ResetPasswordRequest):
    """
    Setzt das Passwort mit dem Token aus der E-Mail zurück.
    """
    data = await proxy_to_consent_service(
        "POST",
        "/auth/reset-password",
        json_data={
            "token": request.token,
            "new_password": request.new_password
        }
    )
    return data


# ==========================================
# Protected Profile Endpoints (Auth Required)
# ==========================================

@router.get("/profile")
async def get_profile(authorization: Optional[str] = Header(None)):
    """
    Gibt das Profil des angemeldeten Benutzers zurück.
    """
    if not authorization:
        raise HTTPException(status_code=401, detail="Authorization header required")

    data = await proxy_to_consent_service(
        "GET",
        "/profile",
        headers=get_auth_headers(authorization)
    )
    return data


@router.put("/profile")
async def update_profile(
    request: UpdateProfileRequest,
    authorization: Optional[str] = Header(None)
):
    """
    Aktualisiert das Profil des angemeldeten Benutzers.
    """
    if not authorization:
        raise HTTPException(status_code=401, detail="Authorization header required")

    data = await proxy_to_consent_service(
        "PUT",
        "/profile",
        json_data={"name": request.name},
        headers=get_auth_headers(authorization)
    )
    return data


@router.put("/profile/password")
async def change_password(
    request: ChangePasswordRequest,
    authorization: Optional[str] = Header(None)
):
    """
    Ändert das Passwort des angemeldeten Benutzers.
    """
    if not authorization:
        raise HTTPException(status_code=401, detail="Authorization header required")

    data = await proxy_to_consent_service(
        "PUT",
        "/profile/password",
        json_data={
            "current_password": request.current_password,
            "new_password": request.new_password
        },
        headers=get_auth_headers(authorization)
    )
    return data


@router.get("/profile/sessions")
async def get_sessions(authorization: Optional[str] = Header(None)):
    """
    Gibt alle aktiven Sessions des Benutzers zurück.
    """
    if not authorization:
        raise HTTPException(status_code=401, detail="Authorization header required")

    data = await proxy_to_consent_service(
        "GET",
        "/profile/sessions",
        headers=get_auth_headers(authorization)
    )
    return data


@router.delete("/profile/sessions/{session_id}")
async def revoke_session(
    session_id: str,
    authorization: Optional[str] = Header(None)
):
    """
    Beendet eine bestimmte Session.
    """
    if not authorization:
        raise HTTPException(status_code=401, detail="Authorization header required")

    data = await proxy_to_consent_service(
        "DELETE",
        f"/profile/sessions/{session_id}",
        headers=get_auth_headers(authorization)
    )
    return data


# ==========================================
# Health Check
# ==========================================

@router.get("/health")
async def auth_health():
    """
    Prüft die Verbindung zum Auth Service.
    """
    try:
        async with httpx.AsyncClient() as client:
            response = await client.get(
                f"{CONSENT_SERVICE_URL}/health",
                timeout=5.0
            )
            is_healthy = response.status_code == 200
    except:
        is_healthy = False

    return {
        "auth_service": "healthy" if is_healthy else "unavailable",
        "connected": is_healthy
    }
