from __future__ import annotations

from fastapi import Form
from fastapi import Query
from fastapi import Request
from fastapi.responses import HTMLResponse
from fastapi.responses import RedirectResponse

from amsdal_ml.mcp_server.mcp_oauth import oauth_router
from amsdal_ml.mcp_server.mcp_oauth.services.errors import OAuthAuthUnavailableError
from amsdal_ml.mcp_server.mcp_oauth.services.errors import OAuthTokenGenerationError
from amsdal_ml.mcp_server.mcp_oauth.services.types import AUTH_COOKIE_NAME
from amsdal_ml.mcp_server.mcp_oauth.services.types import COOKIE_SAMESITE_LAX
from amsdal_ml.mcp_server.mcp_oauth.services.types import URL_SCHEME_HTTPS
from amsdal_ml.mcp_server.mcp_oauth.services.utils import normalize_next
from amsdal_ml.mcp_server.mcp_oauth.services.utils import render_login_html


@oauth_router.get('/auth/login')
async def login_page(next_url: str | None = Query(None, alias='next')):
    return HTMLResponse(render_login_html(next_url=next_url or '/'))


@oauth_router.post('/auth/login')
async def login_submit(
    request: Request,
    email: str = Form(...),
    password: str = Form(...),
    next_url: str | None = Form(None, alias='next'),
):
    try:
        from amsdal.contrib.auth.errors import AuthenticationError
        from amsdal.contrib.auth.models.login_session import LoginSession
        from amsdal.contrib.auth.settings import auth_settings
    except ImportError as exc:
        raise OAuthAuthUnavailableError() from exc

    session = LoginSession(
        email=email,
        password=password,
        token=None,
        mfa_code=None,
    )

    try:
        await session.asave()
    except AuthenticationError:
        return HTMLResponse(
            render_login_html(next_url=next_url or '/', error='Invalid email or password'),
            status_code=401,
        )
    except Exception:
        return HTMLResponse(
            render_login_html(next_url=next_url or '/', error='Login temporarily unavailable. Please try again later.'),
            status_code=500,
        )

    token = session.token
    if not token:
        raise OAuthTokenGenerationError()

    redirect_to = normalize_next(next_url, base_url=str(request.base_url))
    response = RedirectResponse(url=redirect_to, status_code=303)

    max_age = auth_settings.AUTH_TOKEN_EXPIRATION
    response.set_cookie(
        key=AUTH_COOKIE_NAME,
        value=token,
        httponly=True,
        samesite=COOKIE_SAMESITE_LAX,
        secure=request.url.scheme == URL_SCHEME_HTTPS,
        max_age=max_age,
    )

    return response
