""" routes/nextcloud_auth.py """

import requests
from flask import redirect
from flask import render_template
from flask import request
from flask import session
from flask import url_for

from lib.logger import logset
from lib.project import env
from lib.project import oauth

log = logset(__name__)
log.propagate = False


def add_routes(app):
    app.add_url_rule("/nc", "nc_entry", nc_entry)
    app.add_url_rule("/auth/nextcloud/login", "nextcloud_login", nextcloud_login)
    app.add_url_rule(
        "/auth/nextcloud/callback",
        "nextcloud_callback",
        nextcloud_callback,
        methods=["GET", "POST"],
    )


def nc_entry():
    """Entry point for Nextcloud External Sites iframe embedding.

    If the user already has a session, go straight to the app.
    Otherwise render a tiny page that breaks out of the iframe and
    drives the Nextcloud OAuth2 flow, then returns here via NEXTCLOUD_RETURN_URL.
    """
    if session.get("user"):
        return redirect("/")

    nc_return = env.nextcloud.return_url
    login_url = url_for("nextcloud_login", _external=False)
    if nc_return:
        login_url = f"{login_url}?next={nc_return}"

    return render_template("nc_entry.html", login_url=login_url)


def nextcloud_login():
    """Initiate the Nextcloud OAuth2 authorisation flow."""
    next_url = request.args.get("next", "")
    if next_url:
        session["post_auth_redirect"] = next_url

    redirect_uri = url_for("nextcloud_callback", _external=True)
    return oauth.nextcloud.authorize_redirect(redirect_uri=redirect_uri)


def nextcloud_callback():
    """Receive the Nextcloud OAuth2 callback, fetch user info, and set the session."""
    token = oauth.nextcloud.authorize_access_token()
    access_token = token.get("access_token", "")

    nc_url = env.nextcloud.url
    user_info_url = f"{nc_url}/ocs/v2.php/cloud/user?format=json"
    headers = {
        "Authorization": f"Bearer {access_token}",
        "OCS-APIRequest": "true",
    }

    resp = requests.get(user_info_url, headers=headers, timeout=10)
    userinfo = {}
    if resp.status_code == 200:
        data = resp.json()
        ocs_data = data.get("ocs", {}).get("data", {})
        userinfo = {
            "name": ocs_data.get("displayname", ""),
            "email": ocs_data.get("email", ""),
            "sub": ocs_data.get("id", ""),
            "provider": "nextcloud",
        }
    else:
        log.error(f"Nextcloud user-info request failed: {resp.status_code}")

    session["user"] = {"userinfo": userinfo, "access_token": access_token}
    log.info(f"Nextcloud login: {userinfo.get('name', 'unknown')}")

    post_redirect = session.pop("post_auth_redirect", None)
    if post_redirect:
        return redirect(post_redirect)
    return redirect("/")
