from flask import Blueprint, request, jsonify, current_app
from datetime import datetime, timezone
import os
from itsdangerous import URLSafeTimedSerializer, SignatureExpired, BadSignature

from models.state import user_sessions, user_ips, banned_ips, banned_usernames

auth_bp = Blueprint("auth", __name__)


def generate_user_key(username):
    serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"])
    return serializer.dumps({"u": username})


def verify_user_key(username, token, max_age=30*24*60*60):  # 30 days
    serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"])
    try:
        data = serializer.loads(token, max_age=max_age)
        return data.get("u") == username
    except (SignatureExpired, BadSignature):
        return False


@auth_bp.route("/register", methods=["POST"])
def register():
    data = request.get_json()
    username = data.get("username")
    user_ip = request.remote_addr

    if not username:
        return jsonify({"error": "No username provided"}), 400
    if username in user_ips:  # Check global user_ips to see if name is taken
        return jsonify({"error": "Username taken"}), 409
    if user_ip in banned_ips:
        return jsonify({"error": "IP banned"}), 403
    if username in banned_usernames:
        return jsonify({"error": "Username banned"}), 403

    user_key = generate_user_key(username)
    user_sessions[username] = {
        "key": user_key,
        "last_active": datetime.now(timezone.utc).isoformat(),
    }
    user_ips[username] = user_ip
    
    from models.database import db_set_user_ip
    db_set_user_ip(username, user_ip)

    return jsonify({"username": username, "key": user_key})


@auth_bp.route("/validate", methods=["POST"])
def validate():
    data = request.get_json()
    username = data.get("username")
    key = data.get("key")

    if not username or not key:
        return jsonify({"error": "Invalid credentials"}), 403

    if verify_user_key(username, key):
        # Restore active user session in-memory if lost on restart
        user_sessions[username] = {
            "key": key,
            "last_active": datetime.now(timezone.utc).isoformat(),
        }
        return jsonify({"status": "valid"})
        
    return jsonify({"error": "Invalid credentials"}), 403


@auth_bp.route("/logout", methods=["POST"])
def logout():
    data = request.get_json()
    username = data.get("username")
    key = data.get("key")

    if not username or not key:
        return jsonify({"error": "Missing credentials"}), 400

    if verify_user_key(username, key):
        # Remove from active sessions
        user_sessions.pop(username, None)
        # Remove from user_ips in memory and SQLite to free up the username immediately
        user_ips.pop(username, None)
        from models.database import db_delete_user_ip
        db_delete_user_ip(username)

        # Remove from all rooms
        from models.state import room_users
        for room in room_users:
            room_users[room].pop(username, None)

        return jsonify({"status": "logged_out"})

    return jsonify({"error": "Invalid credentials"}), 403


