"""Auth blueprint: login, signup, verify."""
from flask import Blueprint, request, redirect, url_for, render_template, session, flash
from app.extensions import db, login_manager
from app.services.auth_service import signup_user, login_user, verify_email, send_email
from app.models.user import User
from app.models.notification import Notification

bp = Blueprint("auth", __name__)


@bp.route("/login", methods=["GET", "POST"])
def login():
    if "user_id" in session:
        return redirect(url_for("web.home"))
    if request.method == "POST":
        email = request.form.get("email", "").strip().lower()
        password = request.form.get("password", "")
        user, err = login_user(email, password)
        if err:
            flash(err, "danger")
            return render_template("auth/login.html", error=err)
        session["user_id"] = user.id
        session["lang"] = user.lang or session.get("lang", "en")
        session["region"] = user.region or session.get("region", "global")
        db.session.commit()
        # mark intro seen if not already
        if not user.intro_seen:
            return redirect(url_for("web.intro"))
        return redirect(url_for("web.home"))
    return render_template("auth/login.html")


@bp.route("/signup", methods=["GET", "POST"])
def signup():
    if "user_id" in session:
        return redirect(url_for("web.home"))
    error = None
    if request.method == "POST":
        email = request.form.get("email", "").strip().lower()
        password = request.form.get("password", "")
        confirm = request.form.get("confirm_password", "")
        username = request.form.get("username", "").strip()
        if not email or "@" not in email:
            error = "Invalid email"
        elif password != confirm:
            error = "Passwords do not match"
        elif len(password) < 6:
            error = "Password must be at least 6 characters"
        else:
            try:
                user, code = signup_user(email, password, username)
                # dev mode: show code in template
                sent_code = send_email(user, "Verify your email", f"Your code: {code}")
                session["pending_user_id"] = user.id
                session["pending_code"] = code
                return redirect(url_for("auth.verify", uid=user.id))
            except ValueError as e:
                error = str(e)
    return render_template("auth/signup.html", error=error)


@bp.route("/verify/<int:uid>", methods=["GET", "POST"])
def verify(uid):
    if request.method == "POST":
        code = request.form.get("code", "").strip()
        pending_id = session.get("pending_user_id")
        pending_code = session.get("pending_code")
        if int(uid) != pending_id:
            flash("Invalid user", "danger")
            return redirect(url_for("auth.login"))
        try:
            verify_email(uid, code)
            del session["pending_user_id"]
            del session["pending_code"]
            flash("Email verified! Please login.", "success")
            return redirect(url_for("auth.login"))
        except ValueError as e:
            flash(str(e), "danger")
            return render_template("auth/verify.html", uid=uid, demo_code=pending_code)
    return render_template("auth/verify.html", uid=uid, demo_code=session.get("pending_code"))


@bp.route("/resend/<int:uid>", methods=["POST"])
def resend(uid):
    pending_id = session.get("pending_user_id")
    if uid != pending_id:
        flash("Invalid request", "danger")
        return redirect(url_for("auth.login"))
    from app.models.user import User
    from app.models.verification import EmailVerification
    from app.services.auth_service import send_email
    user = db.session.get(User, uid)
    if not user or user.email_verified:
        return redirect(url_for("auth.login"))
    ev = EmailVerification.create(user.id, purpose="signup")
    session["pending_code"] = ev.code
    sent_code = send_email(user, "Verify your email", f"Your code: {ev.code}")
    db.session.commit()
    flash("A new code has been sent to your email.", "success")
    return redirect(url_for("auth.verify", uid=uid))


@bp.route("/logout")
def logout():
    session.clear()
    return redirect(url_for("public.index"))


@bp.route("/forgot", methods=["GET", "POST"])
def forgot_password():
    """Request a password reset code sent to the user's email."""
    from app.services.auth_service import request_password_reset
    error = None
    sent = False
    if request.method == "POST":
        email = request.form.get("email", "").strip().lower()
        if not email or "@" not in email:
            error = "Invalid email"
        else:
            user, code = request_password_reset(email)
            if user:
                sent = True
                if code:
                    # Dev mode: expose the code in the UI for easy testing
                    session["pwd_reset_user_id"] = user.id
                    session["pwd_reset_token"] = user.reset_token
                    session["pwd_reset_code"] = code
            else:
                # Don't reveal if email exists; still show generic success
                sent = True
    return render_template("auth/forgot.html", error=error, sent=sent,
                           demo_code=session.get("pwd_reset_code") if sent else None)


@bp.route("/reset/<token>", methods=["GET", "POST"])
def reset_password(token):
    """Reset password after verifying the token/code."""
    from app.services.auth_service import reset_password as do_reset
    error = None
    if request.method == "POST":
        new_password = request.form.get("password", "")
        confirm = request.form.get("confirm_password", "")
        if new_password != confirm:
            error = "Passwords do not match"
        elif len(new_password) < 6:
            error = "Password must be at least 6 characters"
        else:
            user_id = session.get("pwd_reset_user_id")
            user, err = do_reset(user_id, token, new_password)
            if err:
                error = err
            else:
                session.pop("pwd_reset_user_id", None)
                session.pop("pwd_reset_token", None)
                session.pop("pwd_reset_code", None)
                flash("Your password has been reset. Please login.", "success")
                return redirect(url_for("auth.login"))
    return render_template("auth/reset.html", token=token, error=error)
