"""API blueprint for AJAX endpoints."""
from flask import Blueprint, request, jsonify, session
from app.extensions import db
from app.models.user import User, GameProfile
from app.models.game import Game, GameMode
from app.models.wallet import Wallet
from app.models.notification import Notification
from app.services.wallet_service import credit_wallet

bp = Blueprint("api", __name__)


@bp.route("/player/search")
def player_search():
    q = request.args.get("q", "").strip()
    if not q:
        return jsonify({"results": []})
    me_id = session.get("user_id")
    users = []
    if q.isdigit():
        u = User.query.filter_by(numeric_id=int(q)).first()
        if u: users.append(u)
    if len(users) == 0:
        users = User.query.filter(
            (User.username.ilike(f"%{q}%")) | (User.email.ilike(f"%{q}%"))
        ).limit(10).all()
    # never offer the searching user themselves
    users = [u for u in users if u.id != me_id]
    return jsonify({"results": [{
        "id": u.id, "username": u.username,
        "display_name": u.display_name, "email": u.email,
        "avatar": u.avatar, "numeric_id": u.numeric_id
    } for u in users]})


@bp.route("/game/modes/<int:game_id>")
def game_modes(game_id):
    modes = GameMode.query.filter_by(game_id=game_id, is_active=True).all()
    return jsonify([{"id": m.id, "name": m.name} for m in modes])


@bp.route("/charge", methods=["POST"])
def charge():
    """شارژ فقط کیف پول ورودی (deposit). کیف پول خروجی قابل شارژ نیست."""
    if "user_id" not in session:
        return jsonify({"error": "unauthorized"}), 401
    wallet_id = request.form.get("wallet_id", type=int)
    amount = request.form.get("amount", type=float)
    if not wallet_id or not amount or amount <= 0:
        return jsonify({"error": "invalid"}), 400
    w = db.session.get(Wallet, wallet_id)
    if not w or w.user_id != session["user_id"]:
        return jsonify({"error": "forbidden"}), 403
    if w.kind != "deposit":
        return jsonify({"error": "Only the entry wallet can be charged"}), 400
    credit_wallet(w.id, amount, f"Charge {amount} USDT")
    from flask import redirect, url_for
    if request.form.get("ajax"):
        return jsonify({"ok": True, "balance": w.balance})
    return redirect(url_for("web.wallet"))


# ── NOTIFICATIONS ──
@bp.route("/notifications/unread-count")
def notif_unread_count():
    if "user_id" not in session:
        return jsonify({"count": 0})
    count = Notification.query.filter_by(user_id=session["user_id"], read=False).count()
    return jsonify({"count": count})


@bp.route("/notifications")
def notif_list():
    """Recent notifications for the bell dropdown (JSON)."""
    if "user_id" not in session:
        return jsonify([])
    items = (Notification.query
             .filter_by(user_id=session["user_id"])
             .order_by(Notification.created_at.desc())
             .limit(12)
             .all())
    return jsonify([{
        "id": n.id,
        "type": n.type,
        "title": n.title,
        "body": n.body,
        "icon": n.icon,
        "read": bool(n.read),
        "created_at": n.created_at.strftime("%Y-%m-%dT%H:%M:%S") if n.created_at else None,
    } for n in items])


@bp.route("/notifications/latest")
def notif_latest():
    """Lightweight poll payload: unread count + newest unread notification.
    Used by notify.js to play the soft chime / toast when the admin
    messages the user while they are browsing."""
    if "user_id" not in session:
        return jsonify({"count": 0, "last_id": None})
    last = (Notification.query
            .filter_by(user_id=session["user_id"], read=False)
            .order_by(Notification.created_at.desc(), Notification.id.desc())
            .first())
    count = Notification.query.filter_by(user_id=session["user_id"], read=False).count()
    return jsonify({
        "count": count,
        "last_id": last.id if last else None,
        "title": last.title if last else None,
        "body": last.body if last else None,
        "icon": last.icon if last else None,
        "created_at": last.created_at.strftime("%Y-%m-%dT%H:%M:%S") if last and last.created_at else None,
    })


@bp.route("/notifications/<int:nid>/read", methods=["POST"])
def notif_read(nid):
    if "user_id" not in session:
        return jsonify({"error": "unauthorized"}), 401
    n = db.session.get(Notification, nid)
    if n and n.user_id == session["user_id"]:
        n.read = True
        db.session.commit()
    return jsonify({"ok": True})


@bp.route("/notifications/read-all", methods=["POST"])
def notif_read_all():
    if "user_id" not in session:
        return jsonify({"error": "unauthorized"}), 401
    Notification.query.filter_by(user_id=session["user_id"], read=False).update({"read": True})
    db.session.commit()
    return jsonify({"ok": True})


@bp.route("/team/invite", methods=["POST"])
def team_invite():
    if "user_id" not in session:
        return jsonify({"error": "unauthorized"}), 401
    from app.models.team import Team, TeamMember, TeamInvite
    data = request.get_json() or {}
    team_id = data.get("team_id")
    # accept both player_id (client) and user_id (legacy)
    user_id = data.get("user_id") or data.get("player_id")
    team = db.session.get(Team, team_id)
    if not team:
        return jsonify({"error": "not found"}), 404
    if team.owner_id != session["user_id"]:
        return jsonify({"error": "not owner"}), 403
    target = db.session.get(User, user_id)
    if not target:
        return jsonify({"error": "user not found"}), 404
    if target.id == team.owner_id:
        return jsonify({"error": "already in team"}), 409
    already_member = TeamMember.query.filter_by(team_id=team.id, user_id=target.id).first()
    if already_member:
        return jsonify({"error": "already in team"}), 409
    existing = TeamInvite.query.filter_by(team_id=team_id, to_user_id=user_id, status="pending").first()
    if existing:
        return jsonify({"error": "already invited"}), 409
    inv = TeamInvite(team_id=team_id, from_user_id=session["user_id"], to_user_id=user_id)
    db.session.add(inv)
    invitee = db.session.get(User, user_id)
    inviter = db.session.get(User, session["user_id"])
    notif = Notification(
        user_id=user_id,
        type="team_invite",
        title=f"Team Invitation from {inviter.display_name if inviter else 'A player'}",
        body=f"You received a team invitation for {team.name} ({team.game.name if team.game else 'Team'})."
    )
    db.session.add(notif)
    db.session.commit()
    return jsonify({"ok": True})


@bp.route("/team/member/<int:mid>", methods=["DELETE"])
def remove_member(mid):
    if "user_id" not in session:
        return jsonify({"error": "unauthorized"}), 401
    from app.models.team import TeamMember
    m = db.session.get(TeamMember, mid)
    if not m or m.team.owner_id != session["user_id"]:
        return jsonify({"error": "forbidden"}), 403
    db.session.delete(m)
    db.session.commit()
    return jsonify({"ok": True})


@bp.route("/team/member/<int:mid>/role", methods=["POST"])
def change_role(mid):
    if "user_id" not in session:
        return jsonify({"error": "unauthorized"}), 401
    from app.models.team import TeamMember
    data = request.get_json()
    role = data.get("role")
    m = db.session.get(TeamMember, mid)
    if not m or m.team.owner_id != session["user_id"] or role not in ("member", "manager"):
        return jsonify({"error": "forbidden"}), 403
    m.role = role
    db.session.commit()
    return jsonify({"ok": True})


@bp.route("/team/rename", methods=["POST"])
def team_rename():
    """Team leader (owner) renames their team."""
    if "user_id" not in session:
        return jsonify({"error": "unauthorized"}), 401
    from app.models.team import Team
    data = request.get_json() or {}
    team = db.session.get(Team, data.get("team_id"))
    if not team:
        return jsonify({"error": "not found"}), 404
    if team.owner_id != session["user_id"]:
        return jsonify({"error": "only the team leader can rename the team"}), 403
    name = (data.get("name") or "").strip()
    if len(name) < 3:
        return jsonify({"error": "Team name must be at least 3 characters"}), 400
    if len(name) > 40:
        return jsonify({"error": "Team name must be at most 40 characters"}), 400
    team.name = name
    db.session.commit()
    return jsonify({"ok": True, "name": team.name})


@bp.route("/team/leave", methods=["POST"])
def team_leave():
    """A joined member leaves the team they are in (for the current game context).
    The owner cannot leave their own team."""
    if "user_id" not in session:
        return jsonify({"error": "unauthorized"}), 401
    from app.models.team import Team, TeamMember
    data = request.get_json(silent=True) or {}
    team_id = data.get("team_id")
    if team_id:
        team = db.session.get(Team, team_id)
    else:
        # fallback: infer the user's active joined (non-owned) team
        m0 = (TeamMember.query.join(Team, TeamMember.team_id == Team.id)
              .filter(TeamMember.user_id == session["user_id"],
                      TeamMember.status == "active",
                      Team.owner_id != session["user_id"]).first())
        team = m0.team if m0 else None
    if not team:
        return jsonify({"error": "not found"}), 404
    if team.owner_id == session["user_id"]:
        return jsonify({"error": "the team leader cannot leave their own team"}), 400
    m = TeamMember.query.filter_by(team_id=team.id, user_id=session["user_id"]).first()
    if not m:
        return jsonify({"error": "you are not a member of this team"}), 404
    db.session.delete(m)
    db.session.commit()
    return jsonify({"ok": True})
