# app/auth/routes.py
from flask import Blueprint, render_template, request, redirect, url_for, flash, session
from flask_login import login_user, logout_user, login_required

from app.utils.extensions import User, get_client_from_session
from app.services.appwrite_client import AppwriteAccountClient

auth_bp = Blueprint("auth", __name__, url_prefix="")

@auth_bp.route("/register", methods=["GET", "POST"])
def register():
    if request.method == "POST":
        email = request.form.get("email", "").strip()
        password = request.form.get("password", "")
        name = (request.form.get("name") or "").strip() or None

        if not email or not password:
            flash("Email and password are required.", "error")
            return redirect(url_for("auth.register"))

        try:
            # Create user (no bound session needed)
            aw = AppwriteAccountClient(use_admin=True)
            aw.create_user(email=email, password=password, name=name)

            # Create a session and STORE THE SECRET in Flask session
            sess_obj = aw.create_email_password_session(email=email, password=password)
            secret = sess_obj.get("secret")        

            session["appwrite_cookies"] = secret

            # Bind and fetch profile (either reuse aw with binding or make a new instance)
            aw = AppwriteAccountClient(cookies=secret)
            profile = aw.get_account()
            session["user_profile"] = profile

            # (Optional) Create a JWT for short-lived API calls
            jwt = aw.create_jwt()
            session["appwrite_jwt"] = jwt

            login_user(User(id=profile["$id"], email=profile["email"], name=profile.get("name")))
            flash("Account created and you are now logged in.", "success")
            return redirect(url_for("main.dashboard"))
        
        except Exception as e:
            flash(str(e), "error")
            return redirect(url_for("auth.register"))

    return render_template("auth/register.html")


@auth_bp.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "POST":
        email = request.form.get("email", "").strip()
        password = request.form.get("password", "")
        if not email or not password:
            flash("Email and password are required.", "error")
            return redirect(url_for("auth.login"))

        try:
            # 1) Create session once
            aw = AppwriteAccountClient(use_admin=True)
            sess_obj = aw.create_email_password_session(email=email, password=password)
            secret = sess_obj.get("secret")

            # 2) Save the secret for SSR calls
            session["appwrite_cookies"] = secret

            # 3) Bind and load profile
            aw = AppwriteAccountClient(cookies=secret)
            profile = aw.get_account()
            session["user_profile"] = profile

            # optional: create a JWT now if your dashboard expects it
            try:
                session["appwrite_jwt"] = aw.create_jwt()
            except Exception:
                session["appwrite_jwt"] = {}

            usersname = profile.get("name")

            login_user(User(id=profile["$id"], email=profile["email"], name=profile.get("name")))
            flash(f"Welcome back {usersname}!", "success")
            return redirect(url_for("main.dashboard"))
        except Exception as e:
            flash(str(e), "error")
            return redirect(url_for("auth.login"))
        
    # Get method
    return render_template("auth/login.html")


@auth_bp.route("/logout", methods=["GET", "POST"])
@login_required
def logout():
    secret = session.get("appwrite_cookies")
    if secret:
        try:
            aw = AppwriteAccountClient(cookies=secret)
            aw.logout_current()  # best effort
        except Exception:
            pass
    session.clear()
    logout_user()
    flash("Signed out.", "success")
    return redirect(url_for("auth.login"))

@auth_bp.route("/send", methods=["POST"])
@login_required
def send():
    """
    Sends a verification email to the currently logged-in user.
    Appwrite will redirect the user back to /verify/callback with userId & secret.
    """
    try:
        aw = get_client_from_session()
        callback = url_for("auth.callback", _external=True)  # Must be allowed in Appwrite -> Platforms
        aw.send_verification(callback_url=callback)
        flash("Verification email sent. Please check your inbox.", "info")
    except Exception as e:
        flash(f"Could not send verification email: {e}", "error")
    # Go back to where the user came from, or your dashboard
    return redirect(request.referrer or url_for("main.dashboard"))

@auth_bp.route("/callback", methods=["GET"])
def callback():
    """
    Completes verification after user clicks the email link.
    Requires the user to be logged in (Appwrite Account endpoints need a session).
    If not logged in, we stash the link params and send them to log in first.
    """
    user_id = request.args.get("userId")
    secret = request.args.get("secret")
    if not user_id or not secret:
        flash("Invalid verification link.", "error")
        return redirect(url_for("auth.login"))

    # If we don't currently have an Appwrite session, ask them to log in, then resume.
    if not session.get("appwrite_cookies"):
        session["pending_verification"] = {"userId": user_id, "secret": secret}
        flash("Please log in to complete email verification.", "warning")
        return redirect(url_for("auth.login"))

    # We have a session; complete verification
    try:
        aw = get_client_from_session()
        aw.complete_verification(user_id=user_id, secret=secret)
        # Refresh cached profile so templates reflect emailVerification=True
        profile = aw.get_account()
        session["user_profile"] = profile
        # Cleanup any pending state
        session.pop("pending_verification", None)
        flash("Email verified! You're all set.", "success")
        return redirect(url_for("main.dashboard"))
    except Exception as e:
        flash(f"Verification failed: {e}", "error")
        return redirect(url_for("auth.login"))