"""Admin blueprint — full match & user management."""
from flask import Blueprint, request, redirect, url_for, render_template, session, abort, jsonify, flash
from datetime import datetime, timedelta
from functools import wraps
from app.extensions import db
from app.models.user import User, Role
from app.models.game import Game, GameMode
from app.models.match import Match
from app.models.wallet import Wallet, Transaction
from app.models.notification import Notification
from app.models.social import SocialMedia
from app.models.verification import SiteConfig

bp = Blueprint("admin", __name__)


def require_admin(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if "user_id" not in session:
            return redirect(url_for("auth.login"))
        user = db.session.get(User, session["user_id"])
        if not user or not user.is_admin:
            abort(403)
        return f(*args, **kwargs)
    return decorated


def require_operator(f):
    """Allow admins and tournament managers."""
    @wraps(f)
    def decorated(*args, **kwargs):
        if "user_id" not in session:
            return redirect(url_for("auth.login"))
        user = db.session.get(User, session["user_id"])
        if not user or not user.is_operator:
            abort(403)
        return f(*args, **kwargs)
    return decorated


# ─── DASHBOARD ───────────────────────────────────────────────────────
@bp.route("/")
@require_admin
def dashboard():
    from app.models.support import SupportMessage
    users_count = User.query.count()
    games_count = Game.query.count()
    matches_count = Match.query.count()
    txs_today = Transaction.query.filter(
        Transaction.created_at >= datetime.utcnow() - timedelta(days=1)
    ).count()
    users = User.query.order_by(User.created_at.desc()).limit(15).all()
    matches = Match.query.order_by(Match.starts_at.desc()).limit(10).all()
    recent_txs = Transaction.query.order_by(Transaction.created_at.desc()).limit(10).all()
    support_messages = SupportMessage.query.order_by(SupportMessage.created_at.desc()).limit(10).all()
    return render_template("admin/dashboard.html",
                           users_count=users_count, games_count=games_count,
                           matches_count=matches_count, txs_today=txs_today,
                           users=users, matches=matches, transactions=recent_txs,
                           support_messages=support_messages)


# ─── MATCHES MANAGEMENT ──────────────────────────────────────────────
@bp.route("/matches")
@require_operator
def matches_list():
    q = Match.query.order_by(Match.starts_at.desc())
    game_id = request.args.get("game_id", type=int)
    status = request.args.get("status")
    if game_id:
        q = q.filter_by(game_id=game_id)
    if status:
        q = q.filter_by(status=status)
    matches = q.all()
    games = Game.query.all()
    return render_template("admin/matches.html", matches=matches, games=games, is_tm=session.get("is_tournament_manager", False))


@bp.route("/matches/create", methods=["GET", "POST"])
@require_operator
def match_create():
    from app.models.match import MatchSlotParticipant
    games = Game.query.filter_by(is_active=True).all()
    modes = []
    if request.method == "POST":
        game_id = int(request.form.get("game_id"))
        modes = GameMode.query.filter_by(game_id=game_id, is_active=True).all()
        if "save" in request.form:
            import json
            from datetime import datetime as dt
            starts_at = dt.fromisoformat(request.form.get("starts_at"))
            # Build slot layout config
            slot_layout_raw = request.form.get("slot_layout_json", "{}")
            try:
                slot_layout = json.loads(slot_layout_raw) if slot_layout_raw else {}
            except Exception:
                slot_layout = {}
            m = Match(
                game_id=game_id,
                mode_id=int(request.form.get("mode_id")),
                region=request.form.get("region", "global"),
                title=request.form.get("title").strip(),
                starts_at=starts_at,
                ends_at=dt.fromisoformat(request.form.get("ends_at")) if request.form.get("ends_at") else None,
                entry_fee=int(request.form.get("entry_fee") or 0),
                prize_pool=int(request.form.get("prize_pool") or 0),
                capacity=int(request.form.get("capacity") or 50),
                team_mode=bool(request.form.get("team_mode")),
                reg_open_until_start=request.form.get("reg_open_until_start") == "1",
                status="upcoming",
                slot_layout=json.dumps(slot_layout),
                rules=(request.form.get("rules") or "").strip() or None,
            )
            db.session.add(m)
            db.session.commit()
            flash(f"Match '{m.title}' created!", "success")
            return redirect(url_for("admin.matches_list"))
        return render_template("admin/match_form.html", games=games, modes=modes, match=None,
                               sl={"layout_type":"solo","total_slots":10,"players_per_slot":1}, mode_squad_size=0)
    return render_template("admin/match_form.html", games=games, modes=modes, match=None,
                           sl={"layout_type":"solo","total_slots":10,"players_per_slot":1}, mode_squad_size=0)


@bp.route("/matches/<int:mid>/edit", methods=["GET", "POST"])
@require_operator
def match_edit(mid):
    from app.models.match import MatchSlotParticipant
    m = db.session.get(Match, mid)
    if not m:
        abort(404)
    games = Game.query.filter_by(is_active=True).all()
    modes = GameMode.query.filter_by(game_id=m.game_id, is_active=True).all()
    if request.method == "POST":
        import json
        m.title = request.form.get("title", "").strip()
        m.mode_id = int(request.form.get("mode_id"))
        m.starts_at = datetime.fromisoformat(request.form.get("starts_at"))
        if request.form.get("ends_at"):
            m.ends_at = datetime.fromisoformat(request.form.get("ends_at"))
        m.entry_fee = int(request.form.get("entry_fee") or 0)
        m.prize_pool = int(request.form.get("prize_pool") or 0)
        m.capacity = int(request.form.get("capacity") or 50)
        m.team_mode = bool(request.form.get("team_mode"))
        m.reg_open_until_start = request.form.get("reg_open_until_start") == "1"
        m.status = request.form.get("status", "upcoming")
        m.rules = (request.form.get("rules") or "").strip() or None
        if request.form.get("region"):
            m.region = request.form.get("region")
        # Slot layout
        slot_raw = request.form.get("slot_layout_json", "{}")
        try:
            m.slot_layout = json.dumps(json.loads(slot_raw))
        except Exception:
            pass
        db.session.commit()
        flash("Match updated!", "success")
        return redirect(url_for("admin.matches_list"))
    import json
    try:
        sl = json.loads(m.slot_layout) if m.slot_layout else {}
    except Exception:
        sl = {}
    msq = m.mode.squad_size if m.mode else 1
    return render_template("admin/match_form.html", games=games, modes=modes, match=m,
                           sl=sl, mode_squad_size=msq)


@bp.route("/matches/<int:mid>/cancel")
@require_admin
def match_cancel(mid):
    m = db.session.get(Match, mid)
    if not m:
        abort(404)
    m.status = "cancelled"
    db.session.commit()
    flash(f"Match '{m.title}' cancelled.", "warning")
    return redirect(url_for("admin.matches_list"))


@bp.route("/matches/<int:mid>/publish-credentials", methods=["POST"])
@require_operator
def match_publish(mid):
    m = db.session.get(Match, mid)
    if not m:
        abort(404)
    m.room_code = request.form.get("room_code", "").strip()[:50]
    m.room_password = request.form.get("room_password", "").strip()[:50]
    m.credentials_published = bool(m.room_code or m.room_password)
    db.session.commit()
    flash("Credentials published!", "success")
    return redirect(url_for("admin.match_edit", mid=mid))


@bp.route("/matches/<int:mid>/delete")
@require_admin
def match_delete(mid):
    m = db.session.get(Match, mid)
    if not m:
        abort(404)
    db.session.delete(m)
    db.session.commit()
    flash("Match deleted.", "danger")
    return redirect(url_for("admin.matches_list"))


# ─── PRIZE DISTRIBUTION ──────────────────────────────────────────────
@bp.route("/matches/<int:mid>/award", methods=["GET", "POST"])
@require_admin
def match_award(mid):
    from app.models.match import MatchParticipant
    m = db.session.get(Match, mid) or abort(404)
    # include "lost" so re-awarding a match does not drop losers' participation points
    participants = m.participants.filter(MatchParticipant.status.in_(["registered", "confirmed", "won", "lost"])).all()
    if request.method == "POST":
        # ── Ordered winner slots with per-rank prizes ─────────────────
        # slot_1..slot_6 = participant id (1st, 2nd, 3rd ...), prize_1..6 = amount
        winner_ids, prize_by_participant = [], {}
        for i in range(1, 7):
            pid = request.form.get(f"slot_{i}", type=int)
            if not pid:
                continue
            if pid in winner_ids:
                flash("Each player can occupy only one rank.", "error")
                return redirect(url_for("admin.match_award", mid=mid))
            amt = request.form.get(f"prize_{i}", type=float) or 0.0
            winner_ids.append(pid)
            prize_by_participant[pid] = round(max(amt, 0.0), 2)
        # Legacy fallback: equal split via checkboxes
        if not winner_ids:
            winner_ids = request.form.getlist("winners", type=int)
            total_prize = int(request.form.get("total_prize") or m.prize_pool or 0)
            if winner_ids and total_prize > 0:
                share = round(total_prize / len(winner_ids), 2)
                prize_by_participant = {pid: share for pid in winner_ids}
        if not winner_ids:
            flash("Select at least one winner.", "error")
            return redirect(url_for("admin.match_award", mid=mid))
        total_prize = sum(prize_by_participant.values())
        if total_prize <= 0:
            flash("Invalid prize amount.", "error")
            return redirect(url_for("admin.match_award", mid=mid))
        from app.models.wallet import Wallet
        from app.services.leaderboard_service import award_match_points, POINTS_WIN, POINTS_PARTICIPATION
        for p in participants:
            if p.id in winner_ids:
                p.status = "won"
                p.paid = True
            else:
                p.status = "lost"
        # ── Re-award safety: reverse previous prize payments for this match ──
        # (announcing winners twice adjusts the result, it never double-pays)
        prev_prize_txs = Transaction.query.filter_by(kind="prize").filter(
            Transaction.reason == f"Prize - {m.title}").all()
        for t in prev_prize_txs:
            pw_old = db.session.get(Wallet, t.wallet_id) if t.wallet_id else None
            if pw_old:
                pw_old.balance = (pw_old.balance or 0) - float(t.amount or 0)
                pw_old.last_updated = datetime.utcnow()
            db.session.delete(t)
        if prev_prize_txs:
            Notification.query.filter(
                Notification.type == "prize",
                Notification.body.like(f"%{m.title}%")
            ).delete(synchronize_session=False)
            db.session.flush()
        # واریز جایزه به کیف پول خروجی (payout) — قابل استفاده در مسابقات نیست
        import uuid
        for pid in winner_ids:
            p = db.session.get(MatchParticipant, pid)
            if not p:
                continue
            pw = Wallet.query.filter_by(user_id=p.user_id, kind="payout").first()
            if not pw:
                pw = Wallet(user_id=p.user_id, kind="payout", balance=0, currency="USDT")
                db.session.add(pw)
                db.session.flush()
            amount = float(prize_by_participant.get(pid, 0.0))
            if amount <= 0:
                continue
            pw.balance = (pw.balance or 0) + amount
            pw.last_updated = datetime.utcnow()
            db.session.add(Transaction(
                ref=f"PRZ{uuid.uuid4().hex[:12].upper()}",
                user_id=p.user_id, wallet_id=pw.id, amount=amount,
                kind="prize", reason=f"Prize - {m.title}", status="completed",
                created_by=session["user_id"],
            ))
            db.session.add(Notification(
                user_id=p.user_id, type="prize",
                title="🏆 Prize Received",
                body=f"You won {amount} USDT from {m.title}! (+{POINTS_WIN} points) Added to your Withdrawal Wallet."
            ))
        # (re-award: drop stale participation notifications BEFORE adding fresh ones)
        Notification.query.filter(
            Notification.type == "points",
            Notification.body.like(f"%{m.title}%"),
            Notification.user_id.in_([p.user_id for p in participants if p.id not in winner_ids])
        ).delete(synchronize_session=False)
        db.session.flush()
        # Losers still earn participation points
        for p in participants:
            if p.id in winner_ids:
                continue
            db.session.add(Notification(
                user_id=p.user_id, type="points",
                title="🎯 Points Earned",
                body=f"You earned +{POINTS_PARTICIPATION} points for playing {m.title}. Keep climbing the leaderboard!"
            ))
        # ── Point ledger for weekly / monthly / global leaderboards ──
        award_match_points(m, participants, winner_ids, prize_by_participant)
        m.status = "finished"
        import json as _json
        m.winner_participant_ids = _json.dumps(winner_ids)
        db.session.commit()
        flash(f"Winners announced! {total_prize:g} USDT paid by rank ({len(winner_ids)} placement(s)). Points added to leaderboards.", "success")
        return redirect(url_for("admin.matches_list"))
    # ── GET: prefill previous award state (ordered ranks + per-rank prizes) ──
    import json as _json
    try:
        prev_wids = [int(x) for x in _json.loads(m.winner_participant_ids or "[]")]
    except Exception:
        prev_wids = []
    part_by_id = {p.id: p for p in participants}
    prize_by_pid = {}
    from app.models.leaderboard import PointEvent
    for ev in PointEvent.query.filter_by(match_id=m.id).all():
        if ev.prize and ev.prize > 0:
            prize_by_pid[ev.user_id] = float(ev.prize)
    # map participant_id -> rank prize (prize_by_pid is keyed by user_id)
    pid_prize = {}
    for pid, p in part_by_id.items():
        if p.user_id in prize_by_pid:
            pid_prize[pid] = prize_by_pid[p.user_id]
    prev_slot = {i + 1: pid for i, pid in enumerate(prev_wids)}
    prev_prizes = {i + 1: pid_prize.get(pid, 0) for i, pid in enumerate(prev_wids)}
    return render_template("admin/award.html", match=m, participants=participants,
                           winner_ids=prev_wids, part_by_id=part_by_id,
                           prize_by_pid=pid_prize, prev_slot=prev_slot,
                           prev_prizes=prev_prizes)


# ─── USERS ───────────────────────────────────────────────────────────
@bp.route("/users")
@require_admin
def users_list():
    q = User.query
    search = request.args.get("q", "").strip()
    if search:
        q = q.filter(db.or_(User.email.contains(search), User.username.contains(search),
                             User.numeric_id.like(f"%{search}%")))
    users = q.order_by(User.created_at.desc()).all()
    roles = Role.query.all()
    return render_template("admin/users.html", users=users, roles=roles)


@bp.route("/users/<int:uid>/toggle-active")
@require_admin
def user_toggle(uid):
    u = db.session.get(User, uid)
    if not u:
        abort(404)
    u.is_active_flag = not u.is_active_flag
    db.session.commit()
    return redirect(url_for("admin.users_list"))


@bp.route("/users/<int:uid>/role", methods=["GET", "POST"])
@require_admin
def user_set_role(uid):
    u = db.session.get(User, uid)
    roles = Role.query.all()
    if request.method == "POST":
        role_id = int(request.form.get("role_id"))
        u.role_id = role_id
        db.session.commit()
        return redirect(url_for("admin.users_list"))
    return render_template("admin/user_role.html", user=u, roles=roles)


# ─── GAMES ───────────────────────────────────────────────────────────
@bp.route("/games")
@require_admin
def games_list():
    games = Game.query.order_by(Game.sort_order).all()
    return render_template("admin/games.html", games=games)


@bp.route("/games/create", methods=["GET", "POST"])
@require_admin
def game_create():
    if request.method == "POST":
        g = Game(
            slug=request.form.get("slug", "").strip(),
            name=request.form.get("name", "").strip(),
            icon=request.form.get("icon", "🎮").strip()[:10],
            image=request.form.get("image", "").strip(),
            sort_order=int(request.form.get("sort_order", 0)),
        )
        db.session.add(g)
        db.session.commit()
        flash("Game created!", "success")
        return redirect(url_for("admin.games_list"))
    return render_template("admin/game_form.html", game=None)


@bp.route("/games/<int:gid>/edit", methods=["GET", "POST"])
@require_admin
def game_edit(gid):
    g = db.session.get(Game, gid)
    if not g:
        abort(404)
    if request.method == "POST":
        g.name = request.form.get("name", "").strip()
        g.icon = request.form.get("icon", "🎮").strip()[:10]
        g.image = request.form.get("image", "").strip()
        g.sort_order = int(request.form.get("sort_order", 0))
        g.is_active = "is_active" in request.form
        db.session.commit()
        flash("Game updated!", "success")
        return redirect(url_for("admin.games_list"))
    return render_template("admin/game_form.html", game=g)


@bp.route("/games/<int:gid>/delete")
@require_admin
def game_delete(gid):
    g = db.session.get(Game, gid)
    if not g:
        abort(404)
    db.session.delete(g)
    db.session.commit()
    flash("Game deleted.", "danger")
    return redirect(url_for("admin.games_list"))


@bp.route("/games/<int:gid>/toggle")
@require_admin
def game_toggle(gid):
    g = db.session.get(Game, gid)
    if g:
        g.is_active = not g.is_active
        db.session.commit()
    return redirect(url_for("admin.games_list"))


# ─── GAME MODES ─────────────────────────────────────────────────────────
@bp.route("/games/<int:gid>/modes")
@require_admin
def modes_list(gid):
    game = db.session.get(Game, gid) or abort(404)
    modes = GameMode.query.filter_by(game_id=gid).order_by(GameMode.id).all()
    return render_template("admin/modes.html", game=game, modes=modes)


@bp.route("/games/<int:gid>/modes/create", methods=["GET", "POST"])
@require_admin
def mode_create(gid):
    game = db.session.get(Game, gid) or abort(404)
    if request.method == "POST":
        slug = request.form.get("slug", "").strip()
        name = request.form.get("name", "").strip()
        if not slug or not name:
            flash("Name and slug are required.", "error")
            return redirect(url_for("admin.modes_list", gid=gid))
        sq = int(request.form.get("squad_size", 1))
        mx = int(request.form.get("max_squad_size") or 0) or None
        m = GameMode(
            game_id=gid, slug=slug, name=name,
            description=request.form.get("description", "").strip(),
            squad_size=sq, max_squad_size=mx,
            icon=request.form.get("icon", "⚔️").strip()[:10],
            is_active=True,
        )
        db.session.add(m)
        db.session.commit()
        flash(f"Mode '{m.name}' created!", "success")
        return redirect(url_for("admin.modes_list", gid=gid))
    return render_template("admin/mode_form.html", game=game, mode=None)


@bp.route("/games/<int:gid>/modes/<int:mid>/edit", methods=["GET", "POST"])
@require_admin
def mode_edit(gid, mid):
    game = db.session.get(Game, gid) or abort(404)
    m = db.session.get(GameMode, mid) or abort(404)
    if m.game_id != gid:
        abort(404)
    if request.method == "POST":
        m.name = request.form.get("name", "").strip()
        m.slug = request.form.get("slug", "").strip()
        m.description = request.form.get("description", "").strip()
        m.squad_size = int(request.form.get("squad_size", 1))
        mx = int(request.form.get("max_squad_size") or 0) or None
        m.max_squad_size = mx
        m.icon = request.form.get("icon", "⚔️").strip()[:10]
        m.is_active = "is_active" in request.form
        db.session.commit()
        flash(f"Mode '{m.name}' updated!", "success")
        return redirect(url_for("admin.modes_list", gid=gid))
    return render_template("admin/mode_form.html", game=game, mode=m)


@bp.route("/games/<int:gid>/modes/<int:mid>/delete")
@require_admin
def mode_delete(gid, mid):
    m = db.session.get(GameMode, mid)
    if not m or m.game_id != gid:
        abort(404)
    db.session.delete(m)
    db.session.commit()
    flash("Mode deleted.", "danger")
    return redirect(url_for("admin.modes_list", gid=gid))


# ─── TEAMS ───────────────────────────────────────────────────────────
@bp.route("/teams")
@require_admin
def teams_list():
    from app.models.team import Team
    teams = Team.query.order_by(Team.created_at.desc()).all()
    return render_template("admin/teams.html", teams=teams)


@bp.route("/teams/<int:tid>")
@require_admin
def team_detail(tid):
    from app.models.team import Team
    t = db.session.get(Team, tid) or abort(404)
    return render_template("admin/team_detail.html", team=t)


@bp.route("/teams/<int:tid>/remove/<int:mem_id>")
@require_admin
def team_remove_member(tid, mem_id):
    from app.models.team import Team, TeamMember
    tm = db.session.get(TeamMember, mem_id)
    if not tm or tm.team_id != tid:
        abort(404)
    if tm.role == "owner":
        flash("Cannot remove the team owner.", "error")
        return redirect(url_for("admin.team_detail", tid=tid))
    db.session.delete(tm)
    db.session.commit()
    flash("Member removed from team.", "success")
    return redirect(url_for("admin.team_detail", tid=tid))


@bp.route("/teams/<int:tid>/disband")
@require_admin
def team_disband(tid):
    from app.models.team import Team
    t = db.session.get(Team, tid)
    if not t:
        abort(404)
    db.session.delete(t)
    db.session.commit()
    flash("Team disbanded.", "danger")
    return redirect(url_for("admin.teams_list"))


# ─── (Duplicate wallets_list removed — see line 648) ─────────────────


@bp.route("/wallets/<int:wid>/credit", methods=["POST"])
@require_admin
def wallet_credit(wid):
    w = db.session.get(Wallet, wid)
    if not w:
        abort(404)
    amt = int(request.form.get("amount", 0))
    reason = request.form.get("reason", "Admin credit")
    if amt <= 0:
        flash("Invalid amount", "error")
        return redirect(url_for("admin.wallets_list"))
    w.balance += amt
    w.last_updated = datetime.utcnow()
    tx = Transaction(
        user_id=w.user_id, wallet_id=w.id, amount=amt,
        kind="admin_credit", reason=reason, status="completed",
        created_by=session["user_id"],
    )
    db.session.add(tx)
    db.session.commit()
    flash(f"Credited {amt} to {w.user.display_name}", "success")
    return redirect(url_for("admin.wallets_list"))


@bp.route("/wallets/<int:wid>/debit", methods=["POST"])
@require_admin
def wallet_debit(wid):
    w = db.session.get(Wallet, wid)
    if not w:
        abort(404)
    amt = int(request.form.get("amount", 0))
    reason = request.form.get("reason", "Admin debit")
    if amt <= 0:
        flash("Invalid amount", "error")
        return redirect(url_for("admin.wallets_list"))
    if w.balance < amt:
        flash(f"Insufficient balance. Current: {w.balance}", "warning")
        return redirect(url_for("admin.wallets_list"))
    w.balance -= amt
    w.last_updated = datetime.utcnow()
    tx = Transaction(
        user_id=w.user_id, wallet_id=w.id, amount=-amt,
        kind="admin_debit", reason=reason, status="completed",
        created_by=session["user_id"],
    )
    db.session.add(tx)
    db.session.commit()
    flash(f"Debited {amt} from {w.user.display_name}", "success")
    return redirect(url_for("admin.wallets_list"))


# ── SUPPORT ─────────────────────────────────────────────────────────
@bp.route("/support")
@require_admin
def support_list():
    from app.models.support import SupportMessage
    q = SupportMessage.query.filter_by(parent_id=None)
    status = request.args.get("status")
    if status:
        q = q.filter_by(status=status)
    search = (request.args.get("q") or "").strip()
    if search:
        like = f"%{search}%"
        q = q.join(User, SupportMessage.user_id == User.id).filter(
            (User.display_name.ilike(like)) |
            (User.username.ilike(like)) |
            (User.email.ilike(like)) |
            (User.numeric_id.cast(db.String).like(like))
        )
    # newest first (top -> bottom)
    msgs = q.order_by(SupportMessage.created_at.desc()).all()
    unread_count = q.filter_by(status="open").count()
    return render_template("admin/support.html", messages=msgs,
                           search=search, status=status)


@bp.route("/support/<int:mid>")
@require_admin
def support_detail(mid):
    from app.models.support import SupportMessage
    msg = db.session.get(SupportMessage, mid) or abort(404)
    if msg.parent_id:  # opened a reply directly -> go to root
        return redirect(url_for("admin.support_detail", mid=msg.parent_id))
    replies = SupportMessage.query.filter_by(parent_id=msg.id).order_by(SupportMessage.created_at).all()
    return render_template("admin/support_detail.html", msg=msg, replies=replies)


@bp.route("/support/<int:mid>/claim", methods=["POST", "GET"])
@require_admin
def support_claim(mid):
    """Admin accepts to answer -> claimed + straight to the chat page."""
    from app.models.support import SupportMessage
    from app.models.notification import Notification
    msg = db.session.get(SupportMessage, mid) or abort(404)
    if msg.claimed_by_admin_id is None:
        msg.claimed_by_admin_id = session["user_id"]
        msg.status = "claimed"
        db.session.add(Notification(
            user_id=msg.user_id, type="support_claim",
            title="🛡️ ادمین پیام شما را گرفت",
            body=f"{db.session.get(User, session['user_id']).display_name} در گفتگوی پشتیبانی پاسخ می‌دهد."
        ))
        db.session.commit()
    return redirect(url_for("admin.support_detail", mid=mid))


@bp.route("/support/<int:mid>/reply", methods=["POST"])
@require_admin
def support_reply(mid):
    from app.models.support import SupportMessage
    from app.models.notification import Notification
    parent = db.session.get(SupportMessage, mid) or abort(404)
    body = request.form.get("message", "").strip()
    if not body:
        flash("Empty reply", "error")
        return redirect(url_for("admin.support_detail", mid=mid))
    reply = SupportMessage(user_id=parent.user_id, admin_id=session["user_id"],
                           subject=parent.subject, message=body,
                           is_admin_reply=True, parent_id=parent.id,
                           status="claimed")
    db.session.add(reply)
    # first admin to answer claims the thread
    if parent.claimed_by_admin_id is None:
        parent.claimed_by_admin_id = session["user_id"]
    if parent.status in ("open", None):
        parent.status = "claimed"
    # notify the user
    db.session.add(Notification(
        user_id=parent.user_id, type="support_reply",
        title="🛡️ Support replied to your message",
        body=body[:120]
    ))
    db.session.commit()
    if request.form.get("ajax"):
        return {"ok": True, "id": reply.id}
    flash("Reply sent!", "success")
    return redirect(url_for("admin.support_detail", mid=mid))


@bp.route("/support/<int:mid>/close")
@require_admin
def support_close(mid):
    from app.models.support import SupportMessage
    m = db.session.get(SupportMessage, mid) or abort(404)
    m.status = "closed"
    db.session.commit()
    flash("Ticket closed", "warning")
    return redirect(url_for("admin.support_list"))


# ─── TRANSACTIONS ────────────────────────────────────────────────────
@bp.route("/transactions")
@require_admin
def transactions_list():
    txs = Transaction.query.order_by(Transaction.created_at.desc()).limit(100).all()
    return render_template("admin/transactions.html", transactions=txs)


# ─── WALLETS MANAGEMENT ──────────────────────────────────────────────
@bp.route("/wallets")
@require_admin
def wallets_list():
    """View all wallets (deposit + payout) with search"""
    q = request.args.get("q", "").strip()
    users = User.query
    if q:
        like = f"%{q}%"
        users = users.filter(db.or_(User.username.ilike(like), User.email.ilike(like),
                                    User.numeric_id.cast(db.String).like(like)))
    users = users.order_by(User.created_at.desc()).all()
    wallets_data = []
    for u in users:
        dw = Wallet.query.filter_by(user_id=u.id, kind="deposit").first()
        pw = Wallet.query.filter_by(user_id=u.id, kind="payout").first()
        wallets_data.append({'user': u, 'deposit': dw, 'payout': pw})
    return render_template("admin/wallets.html", wallets_data=wallets_data, search_q=q)


@bp.route("/wallets/set-balance", methods=["POST"])
@require_admin
def wallets_set_balance():
    """Set deposit or payout balance directly for a user (admin)."""
    from datetime import datetime
    from app.models.notification import Notification
    user_id = request.form.get("user_id", type=int)
    kind = request.form.get("kind", "deposit")  # deposit / payout
    amount = float(request.form.get("amount") or 0)
    user = db.session.get(User, user_id)
    if not user:
        return {"ok": False, "error": "User not found"}, 404
    wallet = Wallet.query.filter_by(user_id=user_id, kind=kind).first()
    if not wallet:
        wallet = Wallet(user_id=user_id, kind=kind, balance=0)
        db.session.add(wallet)
        db.session.flush()
    wallet.balance = amount
    wallet.last_updated = datetime.utcnow()
    db.session.add(Transaction(
        ref="ADJ" + str(user_id) + kind[:1].upper(),
        user_id=user_id, wallet_id=wallet.id, amount=amount,
        kind="adjustment", reason=f"Admin balance set ({kind})", status="completed",
        created_by=session.get("user_id"),
    ))
    db.session.add(Notification(
        user_id=user_id, type="wallet", title="Wallet Adjusted",
        body=f"Your {kind} balance was set to {amount} USDT by an administrator."
    ))
    db.session.commit()
    return {"ok": True, "balance": wallet.balance}, 200


# ─── SOCIAL MEDIA MANAGEMENT ─────────────────────────────────────────
@bp.route("/social")
@require_admin
def social_list():
    """لیست شبکه‌های اجتماعی"""
    socials = SocialMedia.query.order_by(SocialMedia.display_order).all()
    return render_template("admin/social.html", socials=socials)


@bp.route("/social/create", methods=["POST"])
@require_admin
def social_create():
    """افزودن شبکه اجتماعی جدید"""
    name = request.form.get("name", "").strip()
    url = request.form.get("url", "").strip()
    icon = request.form.get("icon", "").strip()
    if not name or not url:
        flash("Name and URL are required", "danger")
        return redirect(url_for("admin.social_list"))
    
    max_order = db.session.query(db.func.max(SocialMedia.display_order)).scalar() or 0
    social = SocialMedia(
        name=name,
        url=url,
        icon=icon or "🔗",
        display_order=max_order + 1,
        is_active=True
    )
    db.session.add(social)
    db.session.commit()
    flash(f"Social media '{name}' added successfully", "success")
    return redirect(url_for("admin.social_list"))


@bp.route("/social/<int:sid>/edit", methods=["POST"])
@require_admin
def social_edit(sid):
    """ویرایش شبکه اجتماعی"""
    social = db.session.get(SocialMedia, sid) or abort(404)
    social.name = request.form.get("name", social.name).strip()
    social.url = request.form.get("url", social.url).strip()
    social.icon = request.form.get("icon", social.icon).strip()
    social.is_active = request.form.get("is_active") == "1"
    db.session.commit()
    flash(f"Social media '{social.name}' updated", "success")
    return redirect(url_for("admin.social_list"))


@bp.route("/social/<int:sid>/delete", methods=["POST"])
@require_admin
def social_delete(sid):
    """حذف شبکه اجتماعی"""
    social = db.session.get(SocialMedia, sid) or abort(404)
    db.session.delete(social)
    db.session.commit()
    flash(f"Social media '{social.name}' deleted", "warning")
    return redirect(url_for("admin.social_list"))


# ─── SITE CONFIG ─────────────────────────────────────────────────────
@bp.route("/settings", methods=["GET", "POST"])
@require_admin
def site_settings():
    """تنظیمات سایت (نام، لوگو، تصاویر)"""
    config = SiteConfig.query.first()
    if not config:
        config = SiteConfig(site_name="FIGHTSKILL")
        db.session.add(config)
        db.session.commit()
    
    if request.method == "POST":
        config.site_name = request.form.get("site_name", "FIGHTSKILL").strip()
        config.footer_text = request.form.get("footer_text", "").strip()
        
        # آپلود لوگو
        if "site_logo" in request.files:
            logo_file = request.files["site_logo"]
            if logo_file and logo_file.filename:
                import os
                from werkzeug.utils import secure_filename
                filename = secure_filename(logo_file.filename)
                upload_path = os.path.join("app", "static", "uploads", filename)
                logo_file.save(upload_path)
                config.site_logo = f"/static/uploads/{filename}"
        
        # آپلود تصویر هیرو
        if "hero_image" in request.files:
            hero_file = request.files["hero_image"]
            if hero_file and hero_file.filename:
                import os
                from werkzeug.utils import secure_filename
                filename = secure_filename(hero_file.filename)
                upload_path = os.path.join("app", "static", "uploads", filename)
                hero_file.save(upload_path)
                config.hero_image = f"/static/uploads/{filename}"
        
        # آپلود تصویر درباره ما
        if "about_image" in request.files:
            about_file = request.files["about_image"]
            if about_file and about_file.filename:
                import os
                from werkzeug.utils import secure_filename
                filename = secure_filename(about_file.filename)
                upload_path = os.path.join("app", "static", "uploads", filename)
                about_file.save(upload_path)
                config.about_image = f"/static/uploads/{filename}"
        
        db.session.commit()
        flash("Site settings updated successfully", "success")
        return redirect(url_for("admin.site_settings"))
    
    return render_template("admin/settings.html", config=config)


# ─── MESSAGES (admin → user notifications) ───────────────────────────
MSG_ICONS = ["📢", "🎁", "⚡", "🏆", "💰", "👥", "🎮", "⚠️", "💬", "🔔", "🛡️", "🎯"]

@bp.route("/messages")
@require_admin
def messages_page():
    """Admin messaging center: send a personal notification to any user
    (or broadcast to everyone) — shows up instantly in the user's bell."""
    from sqlalchemy import or_, func
    uid = request.args.get("uid", type=int)
    preselected = None
    if uid:
        preselected = db.session.get(User, uid)

    q = (Notification.query
         .filter(Notification.type.in_(["admin_message", "admin_broadcast"]))
         .order_by(Notification.created_at.desc()))

    search = request.args.get("q", "").strip()
    if search:
        q = q.join(User, Notification.user_id == User.id).filter(
            or_(User.username.ilike(f"%{search}%"),
                User.email.ilike(f"%{search}%"),
                Notification.title.ilike(f"%{search}%")))

    sent = q.limit(40).all()
    total_count = (Notification.query
                   .filter(Notification.type.in_(["admin_message", "admin_broadcast"]))
                   .count())
    today_count = (Notification.query
                   .filter(Notification.type.in_(["admin_message", "admin_broadcast"]),
                           Notification.created_at >= datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0))
                   .count())
    user_count = User.query.filter(User.is_active_flag.is_(True)).count()

    return render_template("admin/messages.html",
                           sent=sent, preselected=preselected,
                           icons=MSG_ICONS, search=search,
                           total_count=total_count,
                           today_count=today_count,
                           user_count=user_count,
                           all_users=User.query.filter(User.is_active_flag.is_(True)).order_by(User.username).all())


@bp.route("/messages/send", methods=["POST"])
@require_admin
def messages_send():
    """Create notification(s) from the admin messaging form."""
    from sqlalchemy import or_
    title = (request.form.get("title") or "").strip()
    body = (request.form.get("body") or "").strip()
    icon = request.form.get("icon", "📢").strip() or "📢"
    broadcast = request.form.get("broadcast") == "on"
    target = (request.form.get("target") or "").strip()

    if not title:
        flash("عنوان پیام الزامی است", "error")
        return redirect(url_for("admin.messages_page"))

    if broadcast:
        users = User.query.filter(User.is_active_flag.is_(True)).all()
        for u in users:
            db.session.add(Notification(
                user_id=u.id, type="admin_broadcast", icon=icon,
                title=title[:150], body=body[:2000],
                data=f'{{"from":"admin","admin_id":{session.get("user_id")}}}'))
        db.session.commit()
        flash(f"📣 پیام همگانی برای {len(users)} کاربر فعال ارسال شد!", "success")
        return redirect(url_for("admin.messages_page"))

    if not target:
        flash("کاربر مقصد را انتخاب کنید یا حالت همگانی را فعال کنید", "error")
        return redirect(url_for("admin.messages_page"))

    user = None
    if target.isdigit():
        user = db.session.get(User, int(target))
    if not user:
        user = User.query.filter(
            or_(User.username.ilike(target),
                User.email.ilike(target))).first()
    if not user:
        flash(f"کاربر «{target}» پیدا نشد", "error")
        return redirect(url_for("admin.messages_page"))

    db.session.add(Notification(
        user_id=user.id, type="admin_message", icon=icon,
        title=title[:150], body=body[:2000],
        data=f'{{"from":"admin","admin_id":{session.get("user_id")}}}'))
    db.session.commit()
    flash(f"✉️ پیام برای {user.display_name or user.username} ارسال شد و نوتیفیکیشن او فعال شد!", "success")
    return redirect(url_for("admin.messages_page"))
