"""User settings — profile, password, email, security, API keys."""

from flask import Blueprint, flash, jsonify, redirect, render_template, request, url_for

from app.models import (
    change_user_email,
    change_user_password,
    delete_user,
    export_user_data,
    generate_api_key,
    is_magic_login_enabled,
    list_api_keys,
    revoke_api_key,
    update_user_magic_login_pref,
    update_user_profile,
)
from app.routes.auth import current_user, login_required

user_settings_bp = Blueprint("user_settings", __name__, url_prefix="/settings")


# ─── Main Settings Page ─────────────────────────────────────────────────────


@user_settings_bp.route("/")
@login_required
def settings_page():
    """Main settings page — profile, password, email, security."""
    user = current_user()
    magic_enabled = is_magic_login_enabled(user["id"])
    return render_template(
        "settings.html",
        user=user,
        magic_login_enabled=magic_enabled,
    )


# ─── Profile ────────────────────────────────────────────────────────────────


@user_settings_bp.route("/profile", methods=["POST"])
@login_required
def update_profile():
    """Update user profile (name, display name)."""
    user = current_user()

    name = request.form.get("name", "").strip()
    display_name = request.form.get("display_name", "").strip()

    result = update_user_profile(user["id"], name=name or None, display_name=display_name or None)

    if result["success"]:
        flash("Profile updated successfully.", "success")
    else:
        flash(result.get("error", "Failed to update profile."), "error")

    return redirect(url_for("user_settings.settings_page"))


# ─── Password ───────────────────────────────────────────────────────────────


@user_settings_bp.route("/password", methods=["POST"])
@login_required
def change_password():
    """Change user password."""
    user = current_user()

    current_password = request.form.get("current_password", "").strip()
    new_password = request.form.get("new_password", "").strip()
    confirm_password = request.form.get("confirm_password", "").strip()

    if not current_password or not new_password:
        flash("Current password and new password are required.", "error")
        return redirect(url_for("user_settings.settings_page"))

    if new_password != confirm_password:
        flash("New password and confirmation do not match.", "error")
        return redirect(url_for("user_settings.settings_page"))

    result = change_user_password(user["id"], current_password, new_password)

    if result["success"]:
        flash("Password changed successfully.", "success")
    else:
        flash(result.get("error", "Failed to change password."), "error")

    return redirect(url_for("user_settings.settings_page"))


# ─── Email ──────────────────────────────────────────────────────────────────


@user_settings_bp.route("/email", methods=["POST"])
@login_required
def change_email():
    """Change user email address."""
    user = current_user()

    current_password = request.form.get("current_password", "").strip()
    new_email = request.form.get("new_email", "").strip()

    if not current_password or not new_email:
        flash("Current password and new email are required.", "error")
        return redirect(url_for("user_settings.settings_page"))

    if "@" not in new_email or "." not in new_email:
        flash("Please enter a valid email address.", "error")
        return redirect(url_for("user_settings.settings_page"))

    result = change_user_email(user["id"], current_password, new_email)

    if result["success"]:
        flash(
            f"Email changed to {new_email}. A verification link has been sent to the new address.",
            "success",
        )
        # TODO: Send verification email via NotificationService
    else:
        flash(result.get("error", "Failed to change email."), "error")

    return redirect(url_for("user_settings.settings_page"))


# ─── Security ───────────────────────────────────────────────────────────────


@user_settings_bp.route("/security/magic-login", methods=["POST"])
@login_required
def toggle_magic_login():
    """Enable or disable magic login (passwordless). Handles both AJAX and form POST."""
    user = current_user()
    # Support both form POST and JSON body
    if request.is_json:
        enabled = request.json.get("enabled", False)
    else:
        # Form POST: checkbox only sends 'on' when checked, nothing when unchecked
        enabled = request.form.get("magic_login_enabled") == "on"
    update_user_magic_login_pref(user["id"], enabled)
    # Return JSON for AJAX, redirect for form POST
    if request.is_json:
        return jsonify({"status": "ok", "enabled": enabled})
    return redirect(url_for("user_settings.settings_page"))


# ─── API Keys ───────────────────────────────────────────────────────────────


@user_settings_bp.route("/api-keys")
@login_required
def api_keys_page():
    """API key management page."""
    user = current_user()
    keys = list_api_keys(user["id"])
    return render_template(
        "user_settings_api_keys.html",
        user=user,
        keys=keys,
    )


@user_settings_bp.route("/api-keys", methods=["POST"])
@login_required
def create_api_key():
    """Create a new API key."""
    user = current_user()

    name = request.form.get("name", "").strip()
    if not name:
        flash("API key name is required", "error")
        return redirect(url_for("user_settings.api_keys_page"))

    # Parse permission checkboxes
    permissions = {
        "read_forms": request.form.get("perm_read_forms") == "on",
        "write_forms": request.form.get("perm_write_forms") == "on",
        "read_submissions": request.form.get("perm_read_submissions") == "on",
        "delete_forms": request.form.get("perm_delete_forms") == "on",
    }

    result = generate_api_key(name, user["id"], permissions)
    flash(f"API key created: {result['full_key']}. Save it now — you won't see it again.", "success")

    # Store the full key in a flash-like mechanism for the template
    from flask import session

    session["_new_api_key"] = result["full_key"]

    return redirect(url_for("user_settings.api_keys_page"))


@user_settings_bp.route("/api-keys/clear-new-key", methods=["POST"])
@login_required
def clear_new_api_key():
    """Clear the temporarily-stored new API key from session."""
    from flask import session

    session.pop("_new_api_key", None)
    return jsonify({"status": "ok"})


@user_settings_bp.route("/api-keys/<int:key_id>/revoke", methods=["POST"])
@login_required
def revoke_api_key_route(key_id):
    """Revoke an API key."""
    user = current_user()
    success = revoke_api_key(key_id, user["id"])

    if success:
        flash("API key revoked.", "info")
    else:
        flash("API key not found or already revoked.", "error")

    return redirect(url_for("user_settings.api_keys_page"))


# ─── GDPR Data Export ───────────────────────────────────────────────────────


@user_settings_bp.route("/data-export", methods=["POST"])
@login_required
def data_export():
    """Export all user data as JSON (GDPR right to data portability)."""
    user = current_user()
    import io

    from flask import make_response

    data = export_user_data(user["id"])
    if data is None:
        flash("Failed to export data — user not found.", "error")
        return redirect(url_for("user_settings.settings_page"))

    json_bytes = json.dumps(data, indent=2, default=str).encode("utf-8")
    response = make_response(json_bytes)
    response.headers["Content-Type"] = "application/json"
    response.headers["Content-Disposition"] = 'attachment; filename="agentforms-data-export.json"'
    return response


# ─── Account Deletion ───────────────────────────────────────────────────────


@user_settings_bp.route("/account/delete", methods=["POST"])
@login_required
def delete_account():
    """Delete user account and all associated data."""
    user = current_user()

    current_password = request.form.get("current_password", "").strip()

    # Verify password before deletion (bcrypt — consistent with auth.py)
    import bcrypt

    from app.db import get_db

    if not current_password:
        flash("Current password is required to confirm deletion.", "error")
        return redirect(url_for("user_settings.settings_page"))
    conn = get_db()
    user_row = conn.execute("SELECT password_hash FROM users WHERE id = ?", (user["id"],)).fetchone()
    conn.close()

    if not user_row:
        flash("User not found. Account not deleted.", "error")
        return redirect(url_for("user_settings.settings_page"))

    if not bcrypt.checkpw(
        current_password.encode("utf-8"),
        user_row["password_hash"].encode("utf-8"),
    ):
        flash("Incorrect password. Account not deleted.", "error")
        return redirect(url_for("user_settings.settings_page"))

    # Delete the account
    result = delete_user(user["id"])

    if result["success"]:
        from flask import session as flask_session

        flask_session.clear()
        flash("Your account and all associated data have been permanently deleted.", "success")
        return redirect(url_for("auth.login"))
    else:
        flash(result.get("error", "Failed to delete account."), "error")
        return redirect(url_for("user_settings.settings_page"))