import uuid
import datetime
import json
import urllib.request
import asyncio
import re
import random
from fastapi import APIRouter, Request, Depends, HTTPException, Body, BackgroundTasks
from typing import List, Optional, Dict, Any
from pydantic import BaseModel, Field

router = APIRouter(tags=["IDG Chatbox"])

# DTOs
class ChatRoomCreate(BaseModel):
    name: str
    description: Optional[str] = ""
    order: Optional[int] = 0
    enabled: Optional[bool] = True
    is_staff: Optional[bool] = False
    allowed_users: Optional[List[str]] = []

class ChatRoomUpdate(BaseModel):
    name: Optional[str] = None
    description: Optional[str] = None
    order: Optional[int] = None
    enabled: Optional[bool] = None
    is_staff: Optional[bool] = None
    allowed_users: Optional[List[str]] = None

class ChatSettingsUpdate(BaseModel):
    announcement_text: Optional[str] = None
    polls_enabled: Optional[bool] = None
    messages_retention_days: Optional[int] = None
    allowed_roles_view: Optional[List[str]] = None
    allowed_roles_post: Optional[List[str]] = None
    allowed_boards: Optional[List[str]] = None
    ai_api_key: Optional[str] = None
    widget_width: Optional[str] = None
    widget_height: Optional[str] = None
    widget_padding: Optional[str] = None
    chat_font_family: Optional[str] = None
    chat_inner_padding: Optional[str] = None
    allowed_roles_media: Optional[List[str]] = None
    allowed_roles_mention: Optional[List[str]] = None

class ChatMessageCreate(BaseModel):
    content: str

class ChatMessageReact(BaseModel):
    emoji: str

class ChatModerationAction(BaseModel):
    room_id: str
    target_username: str
    action_type: str  # "ban", "mute", "kick"
    duration: Optional[int] = None
    reason: str
    proof_url: Optional[str] = None

class ChatModerationAppeal(BaseModel):
    action_type: str
    reason: str
    moderator_username: str
    proof_url: Optional[str] = None
    appeal_text: str



# AI Background Task - INDUNGI @BOT Engine
INDUNGI_SYSTEM_PROMPT = """Ești INDUNGI @BOT, asistentul inteligent oficial și antrenat al comunității INDUNGI ROMANIA (fondată în 2010, comunitatea #1 de Counter-Strike și Gaming din România).

CUNOȘTINȚE DESPRE COMUNITATEA INDUNGI:
- Istorie: Înființată în 2010. Comunitate legendară de gaming din România, axată pe CS 1.6, CS2, servere de jocuri și competiții.
- Servere Oficiale:
  * CS 1.6: NUMAI DD2 (209.38.247.243:27015), Respawn (209.38.247.243:27016), Furien (209.38.247.243:27017), Zombie, GunGame, War3.
  * CS2: Competitive 128 Tick, Retakes, Deathmatch.
- Grade Forum & Ierarhie: Root (Super-Administrator), Administrator, Moderator, FORUM VIP, Membru, precum și grade secundare (Fondator Server, Sponsor, Donator+).
- Secțiuni Forum: Regulament General, Servere Oficiale, Asistență Tehnică, Cereri Unban, Reclamații Staff, Propuneri, Echipe & Clanuri, VIP & Shop.
- Beneficii VIP: Chatbox VIP color, avatar frames personalizate, badge-uri animate, multiplicator de puncte, acces camere speciale.
- Comenzi CS Utile:
  * CS 1.6: fps_max 101, rate 100000, cl_updaterate 101, cl_cmdrate 101, ex_interp 0.01.
  * CS2: +fps_max 0, -novid, -tickrate 128, rate 1000000, cl_interp_ratio 1.

INSTRUCȚIUNI:
1. Răspunde în limba română, prietenos, inteligent, concis (2-4 propoziții potrivite pentru chatbox), folosind gaming slang românesc când e cazul.
2. Poți răspunde la ORICE întrebare: despre forum, servere, optimizări CS, hardware, gaming, glume sau întrebări generale de cultură generală.
3. Răspunde direct și oferă soluții concrete."""

def search_youtube(query: str) -> Optional[str]:
    """Search YouTube for a query and return watch URL."""
    try:
        url = "https://www.youtube.com/results?search_query=" + urllib.parse.quote(query)
        req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"})
        with urllib.request.urlopen(req, timeout=5) as response:
            html = response.read().decode("utf-8")
            video_ids = re.findall(r"\/watch\?v=([a-zA-Z0-9_-]{11})", html)
            if video_ids:
                return f"https://www.youtube.com/watch?v={video_ids[0]}"
    except Exception as e:
        print("YouTube Search error:", e)
    return None

async def answer_with_internal_knowledge(db, content: str, sender_user: Optional[Dict[str, Any]] = None) -> (str, Optional[Dict[str, Any]]):
    """Intelligent dynamic knowledge and action engine with database and web context."""
    # Clean and strip all bot prefixes/mentions
    clean_text = content
    for prefix in ["@INDUNGI @BOT", "@INDUNGI_BOT", "@INDUNGI", "@BOT", "@AI", "!AI", "!BOT", "!HELP", "!INDUNGI", "/AI", "/BOT", "bot,", "ai,", "bot ", "ai "]:
        clean_text = re.sub(re.escape(prefix), "", clean_text, flags=re.IGNORECASE)
    
    q = clean_text.strip().lower()
    media = None

    # 1. YouTube Video Search & Embed Action
    if any(p in q for p in ["youtube", "video", "clip", "melodie", "muzica", "song", "track", "ascult"]):
        # Extract search query
        yt_query = clean_text
        for w in ["pune un video cu", "pune video cu", "cauta pe youtube", "cauta youtube", "pune melodia", "pune o melodie cu", "pune o piesa cu", "cauta un clip cu", "pune un clip cu", "muzica cu", "melodie cu"]:
            yt_query = re.sub(re.escape(w), "", yt_query, flags=re.IGNORECASE)
        yt_query = yt_query.strip() or "Counter-Strike Highlights 2026"
        
        yt_link = await asyncio.to_thread(search_youtube, yt_query)
        if yt_link:
            media = {"type": "yt", "url": yt_link}
            return f"🎬 Am găsit clipul pentru **{yt_query}**! Îl poți urmări direct aici în chat:\n{yt_link}", media
        return f"Nu am reușit să găsesc un clip pentru '{yt_query}', încearcă cu alți termeni!", None

    # 2. Tag a Member / Search User Action
    if any(p in q for p in ["da-i tag lui", "da tag lui", "tag lui", "saluta-l pe", "cheama-l pe", "cauta userul", "cauta membrul", "cine e"]):
        target_name = clean_text
        for w in ["da-i tag lui", "da tag lui", "tag lui", "saluta-l pe", "cheama-l pe", "cauta userul", "cauta membrul", "cine e"]:
            target_name = re.sub(re.escape(w), "", target_name, flags=re.IGNORECASE)
        target_name = target_name.replace("?", "").replace("!", "").strip()
        
        if target_name:
            found_user = await db.users.find_one({"username": {"$regex": f"^{re.escape(target_name)}$", "$options": "i"}})
            if not found_user:
                found_user = await db.users.find_one({"username": {"$regex": re.escape(target_name), "$options": "i"}})
                
            if found_user:
                target_uname = found_user["username"]
                role_label = found_user.get("role", "user").capitalize()
                pts = found_user.get("points", 0)
                sender_name = sender_user.get("username", "cineva") if sender_user else "un coleg"
                return f"👋 Salut @{target_uname}! Te-a strigat @{sender_name} în chat. (Profil: {role_label}, {pts} puncte)", None
            return f"Nu am găsit niciun membru cu numele '{target_name}'. Verifică dacă ai scris corect username-ul!", None

    # 3. Topic Search & Linking Action
    if any(p in q for p in ["cauta topic", "topic despre", "topicuri", "arata topicul", "ultimele topicuri", "ce topicuri avem", "recomanda-mi un topic"]):
        topic_query = clean_text
        for w in ["cauta topic despre", "cauta topic cu", "cauta topic", "topic despre", "ce topicuri avem despre", "arata topicul", "recomanda-mi un topic"]:
            topic_query = re.sub(re.escape(w), "", topic_query, flags=re.IGNORECASE)
        topic_query = topic_query.replace("?", "").strip()
        
        query_filter = {"title": {"$regex": re.escape(topic_query), "$options": "i"}} if topic_query and len(topic_query) > 2 else {}
        found_topics = await db.topics.find(query_filter).sort("created_at", -1).limit(4).to_list(4)
        
        if found_topics:
            topic_links = []
            for t in found_topics:
                author_name = t.get("author_username") or "Anonim"
                topic_links.append(f"• **[{t.get('title')}](/topics/{t.get('id')})** (deschis de @{author_name})")
            return "📌 Iată ce topicuri am găsit pe forum:\n" + "\n".join(topic_links), None
        return f"Nu am găsit niciun topic legat de '{topic_query}'. Poți deschide chiar tu unul nou în secțiunea potrivită!", None

    # 4. Despre Forum / About Forum Breakdown
    if any(p in q for p in ["ce poti sami zici despre forum", "despre forum", "ce este indungi", "ce e indungi", "povesteste-mi despre", "ce sectiuni", "ce gasim pe forum"]):
        total_users = await db.users.count_documents({})
        total_topics = await db.topics.count_documents({})
        return (
            f"🏆 **INDUNGI ROMANIA** este comunitatea #1 de Counter-Strike și Gaming din România, înființată în anul 2010!\n\n"
            f"• 👥 **Membri activi:** {total_users} utilizatori înregistrați & {total_topics} topicuri de discuție.\n"
            f"• 🎮 **Servere Oficiale:** Servere de CS 1.6 (NUMAI DD2, Respawn, Furien, Zombie) și CS2 Competitive/128-tick.\n"
            f"• ⚔️ **Echipe & Clanuri:** Sistem dedicat de clanuri cu clasamente lunare și premii.\n"
            f"• 👑 **Sistem VIP & Shop:** Beneficii vizuale unice (avatar frames, culori de chat, badge-uri animate).\n"
            f"• 🛡️ **Secțiuni Support:** Asistență tehnică, cereri unban, propuneri și discuții libere!"
        ), None

    # 5. Who am I / Sender Info Questions
    if any(p in q for p in ["cum ma numesc", "cum ma cheama", "cine sunt eu", "cine sunt", "ce nume am", "profilul meu", "ce grad am", "ce rol am", "cate puncte am"]):
        if sender_user:
            uname = sender_user.get("username", "Membru")
            role = sender_user.get("role", "user")
            role_title = "Root (Super-Administrator)" if role == "root" else ("Administrator" if role == "admin" else ("Moderator" if role == "mod" else "Membru"))
            points = sender_user.get("points", 0)
            msgs = sender_user.get("message_count", 0)
            return f"Te numești **{uname}**, ai gradul de **{role_title}**, **{points} puncte** și **{msgs} mesaje** pe forumul INDUNGI! 🏆", None
        return "Ești un membru valoros al comunității INDUNGI ROMANIA!", None

    # 6. Forum Stats / Member Count Questions
    if any(p in q for p in ["cati membri", "cati utilizatori", "cati useri", "cate conturi", "cati oameni", "statistici", "cate postari", "cate mesaje"]):
        total_users = await db.users.count_documents({})
        total_topics = await db.topics.count_documents({})
        total_posts = await db.posts.count_documents({})
        return f"📊 Comunitatea INDUNGI are în prezent **{total_users} membri înregistrați**, **{total_topics} topicuri** deschise și **{total_posts} mesaje** pe forum!", None

    # 7. Time / Date Questions
    if any(p in q for p in ["cat e ceasul", "ce ora e", "ce data e", "in ce an suntem", "ce zi e"]):
        now_ro = datetime.datetime.now(timezone.utc)
        return f"🕒 Data și ora curentă: **{now_ro.strftime('%d.%m.%Y, %H:%M UTC')}**.", None

    # 8. VIP and Perks Questions
    if any(w in q for w in ["vip", "beneficii", "pret", "cumpar", "donate", "donatie"]):
        return "👑 Statutul VIP îți oferă: avatar frames personalizate, badge-uri pe profil, culori unice în chatbox, multiplicator de puncte lunare și acces la camere VIP. Intră în tab-ul 'VIP' din meniu pentru detalii!", None

    # 9. Unban & Ban Inquiries
    if any(w in q for w in ["unban", "banat", "cerere unban", "debanare"]):
        return "🛡️ Pentru cereri de unban, mergi la secțiunea serverului pe care ai primit ban, deschide un topic nou la 'Cereri Unban' și atașează demo-ul și pozele (SS) făcute de admin.", None

    # 10. CS Settings, FPS, Configs, Optimizations
    if any(w in q for w in ["fps", "lag", "rate", "setari", "config", "optimizare", "interp", "recoil"]):
        if "cs2" in q:
            return "⚡ Setări recomandate CS2: Launch options `-novid +fps_max 0 -tickrate 128`, iar în consolă `rate 1000000` și `cl_interp_ratio 1`.", None
        return "⚡ Setări optime CS 1.6: În consolă scrie `rate 100000`, `cl_updaterate 101`, `cl_cmdrate 101`, `fps_max 101`, `ex_interp 0.01` pentru un recoil impecabil!", None

    # 11. Server IPs & List
    if any(w in q for w in ["server", "ip", "connect", "adresa", "port", "unde jucam", "dd2", "furien", "respawn"]):
        servers = await db.servers.find({}, {"_id": 0, "name": 1, "address": 1}).to_list(10)
        if servers:
            s_list = " | ".join([f"{s.get('name')}: `{s.get('address')}`" for s in servers if s.get('address')])
            return f"🎮 Servere INDUNGI disponibile: {s_list}. Te așteptăm la joc!", None
        return "🎮 Servere INDUNGI disponibile: [CS 1.6] NUMAI DD2: `209.38.247.243:27015` | Respawn: `209.38.247.243:27016` | Furien: `209.38.247.243:27017`.", None

    # 12. Staff / Founder / Owner Inquiries
    if any(w in q for w in ["fondator", "owner", "admin", "staff", "root", "moderator", "conducere"]):
        admins = await db.users.find({"role": {"$in": ["root", "admin"]}}, {"_id": 0, "username": 1, "role": 1}).to_list(10)
        admin_names = ", ".join([f"@{a['username']}" for a in admins if a.get("username")])
        return f"👑 Echipa de Administrație INDUNGI: {admin_names or '@BL1NG, @Admin'}. Pentru probleme urgente, le poți trimite un mesaj privat!", None

    # 13. Clan & Teams
    if any(w in q for w in ["clan", "echipa", "team", "clans"]):
        return "⚔️ Poți crea sau intra într-un Clan din meniul 'CLANS' din antet. Membrii clanurilor primesc tag special și concurează în clasamentul lunar!", None

    # 14. Bot Identity
    if any(w in q for w in ["cine esti", "ce esti", "despre tine", "cum functionezi"]):
        return "🤖 Sunt INDUNGI @BOT, asistentul AI oficial al comunității INDUNGI ROMANIA (fondată în 2010). Sunt antrenat să te ajut cu orice informație despre forum, servere, optimizări CS, căutare video YouTube și asistență!", None

    # 15. Jokes / Humor
    if any(w in q for w in ["gluma", "banc", "joke", "amuzant", "ras"]):
        jokes = [
            "😄 De ce nu dau fetițele rush pe lung în Dust 2? Pentru că știu că le așteaptă AWP-ul cu floarea în gură!",
            "🎯 Un terorist intră pe B și întreabă: 'De ce e liniște?' Răspuns: 'Pentru că ai luat flash de la coechipier!'",
            "💣 Ce face un gamer de CS când se căsătorește? Plantează bomba și așteaptă 45 de secunde!"
        ]
        return random.choice(jokes), None

    # 16. Math Calculations (e.g. 5+5, 100/4)
    math_match = re.match(r"^[\d\s\+\-\*\/\(\)\.\^]+$", q)
    if math_match:
        try:
            val = eval(q, {"__builtins__": None}, {})
            return f"Rezultatul calculului este: **{val}**", None
        except Exception:
            pass

    # 17. Greetings
    if not q or any(w in q for w in ["salut", "buna", "cf", "ce faci", "hello", "hi", "hei", "noroc", "servus", "ziua", "salutama"]):
        uname_tag = f"@{sender_user.get('username')}" if sender_user and sender_user.get("username") else ""
        return f"Salut {uname_tag}! Sunt INDUNGI @BOT. Cu ce te pot ajuta? (pot căuta clipuri YouTube, topicuri pe forum, informații despre servere, statistici sau membri) 😊", None

    # 18. General Helpful Assistant
    return f"Sunt aici să te ajut! Poți să-mi ceri să caut un video pe YouTube (ex: `@bot pune video cu s1mple`), să caut topicuri pe forum (ex: `@bot cauta topic despre regulament`), să dau tag unui membru sau să-ți dau informații despre servere și VIP!", None

async def process_ai_message(db, room_id: str, content: str, api_key: str, sender_user: Optional[Dict[str, Any]] = None):
    # Check if we should use external AI or rich internal engine
    valid_key = api_key and len(api_key) > 8 and api_key.lower() != "admin"
    media = None
    
    if not valid_key:
        reply_content, media = await answer_with_internal_knowledge(db, content, sender_user)
    else:
        def call_ai():
            try:
                user_context = f"Utilizatorul care vorbește: {sender_user.get('username', 'Membru')} (Rol: {sender_user.get('role', 'user')})" if sender_user else ""
                full_system = f"{INDUNGI_SYSTEM_PROMPT}\n{user_context}"
                
                if api_key.startswith("sk-"):
                    req = urllib.request.Request(
                        "https://api.openai.com/v1/chat/completions",
                        headers={
                            "Authorization": f"Bearer {api_key}",
                            "Content-Type": "application/json"
                        },
                        data=json.dumps({
                            "model": "gpt-3.5-turbo",
                            "messages": [
                                {"role": "system", "content": full_system},
                                {"role": "user", "content": content}
                            ],
                            "max_tokens": 250,
                            "temperature": 0.7
                        }).encode("utf-8")
                    )
                    with urllib.request.urlopen(req, timeout=12) as response:
                        res = json.loads(response.read().decode("utf-8"))
                        return res["choices"][0]["message"]["content"]
                else:
                    req = urllib.request.Request(
                        f"https://generativelanguage.googleapis.com/v1beta/openai/chat/completions",
                        headers={
                            "Authorization": f"Bearer {api_key}",
                            "Content-Type": "application/json"
                        },
                        data=json.dumps({
                            "model": "gemini-2.0-flash",
                            "messages": [
                                {"role": "system", "content": full_system},
                                {"role": "user", "content": content}
                            ],
                            "max_tokens": 250,
                            "temperature": 0.7
                        }).encode("utf-8")
                    )
                    with urllib.request.urlopen(req, timeout=12) as response:
                        res = json.loads(response.read().decode("utf-8"))
                        return res["choices"][0]["message"]["content"]
            except Exception as e:
                print("External AI failed, using internal knowledge engine:", e)
                return None

        reply_content = await asyncio.to_thread(call_ai)
        if not reply_content:
            reply_content, media = await answer_with_internal_knowledge(db, content, sender_user)

    msg_id = str(uuid.uuid4())
    msg_doc = {
        "_id": msg_id,
        "room_id": room_id,
        "user_id": "bot_indungi",
        "avatar_url": "https://api.dicebear.com/7.x/bottts/svg?seed=IndungiBot&backgroundColor=0b0e14",
        "role": "bot",
        "is_vip": True,
        "content": reply_content,
        "media": media,
        "created_at": datetime.datetime.utcnow().isoformat()
    }
    await db.idg_chat_messages.insert_one(msg_doc)

# Helper for permissions
def check_chat_perms(user, settings, perm_type="view"):
    user_role = user.get("role", "guest") if user else "guest"
    
    # admins and roots always allowed
    if user_role in ["admin", "root"]:
        return True
        
    if perm_type == "view":
        # Public viewing is allowed for everyone
        return True
        
    # for posting, user must be logged in
    if user_role == "guest" or not user:
        raise HTTPException(status_code=401, detail="Trebuie să fii autentificat pentru a trimite mesaje în chatbox.")
        
    allowed_roles = settings.get(f"allowed_roles_{perm_type}", ["user", "vip", "mod", "admin", "root"])
    if user_role not in allowed_roles:
        raise HTTPException(status_code=403, detail=f"Grupul tău '{user_role}' nu are permisiuni de postare în chatbox.")
    return True

async def check_chat_moderation(db, user_id: str, action: str = "post"):
    now = datetime.datetime.utcnow()
    # Check for active ban
    ban = await db.idg_chat_moderation.find_one({
        "user_id": user_id,
        "type": "ban",
        "$or": [{"expires_at": None}, {"expires_at": {"$gt": now}}]
    })
    if ban:
        raise HTTPException(status_code=403, detail="Ești banat din chatbox.")
        
    if action == "post":
        # Check for active mute
        mute = await db.idg_chat_moderation.find_one({
            "user_id": user_id,
            "type": "mute",
            "$or": [{"expires_at": None}, {"expires_at": {"$gt": now}}]
        })
        if mute:
            exp_str = f" până la {mute['expires_at'].strftime('%H:%M:%S')}" if mute.get('expires_at') else " permanent"
            raise HTTPException(status_code=403, detail=f"Ești redus la tăcere (muted){exp_str}.")

def get_room_query_id(room_id: str):
    if len(room_id) == 24:
        try:
            from bson import ObjectId
            return ObjectId(room_id)
        except Exception:
            pass
    return room_id

# PUBLIC ENDPOINTS

@router.get("/idg/chat/fix")
async def force_fix(request: Request):
    await require_admin(request)
    db = request.app.state.db
    await db.idg_apps.update_one({'key': 'chatbox'}, {'$set': {'status': 'enabled', 'name': 'Chatbox (Rooms)'}}, upsert=True)
    if not await db.idg_chat_rooms.find_one({}):
        import uuid
        import datetime
        await db.idg_chat_rooms.insert_one({
            "id": uuid.uuid4().hex,
            "name": "General Chat",
            "description": "Lobby",
            "order": 0,
            "enabled": True,
            "is_staff": False,
            "created_at": datetime.datetime.utcnow().isoformat()
        })
    return {"status": "fixed"}

@router.get("/idg/chat/debug_auth")
async def debug_auth(request: Request):
    await require_admin(request)
    auth = request.headers.get("Authorization")
    if not auth:
        return {"error": "No Authorization header"}
    if not auth.startswith("Bearer "):
        return {"error": "Not a Bearer token"}
    token = auth.split(" ")[1]
    db = request.app.state.db
    try:
        import jwt
        import os
        payload = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
        user = await db.users.find_one({"$or": [{"id": payload["sub"]}, {"_id": payload["sub"]}]})
        if not user:
            return {"error": "User not found in DB", "payload": payload}
        return {"status": "ok", "user": {"id": user.get("id"), "role": user.get("role")}}
    except Exception as e:
        import traceback
        return {"error": str(e), "traceback": traceback.format_exc()}

@router.get("/idg/chat/debug_settings")
async def debug_settings(request: Request):
    await require_admin(request)
    db = request.app.state.db
    settings = await db.idg_chat_settings.find_one({}, {"_id": 0})
    app_doc = await db.idg_apps.find_one({"key": "chatbox"}, {"_id": 0})
    rooms = await db.idg_chat_rooms.find({}).to_list(10)
    return {"settings": settings, "app": app_doc, "rooms": [r.get("name") for r in rooms]}

@router.get("/idg/chat/rooms")
async def get_public_rooms(request: Request, board_id: str = "all"):
    db = request.app.state.db
    
    user = None
    auth = request.headers.get("Authorization")
    if auth and auth.startswith("Bearer "):
        token = auth.split(" ")[1]
        try:
            import jwt
            import os
            payload = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
            user = await db.users.find_one({"$or": [{"id": payload["sub"]}, {"_id": payload["sub"]}]})
        except Exception:
            pass

    settings = await db.idg_chat_settings.find_one({}) or {}
    rooms = await db.idg_chat_rooms.find({"enabled": True}).sort("order", 1).to_list(100)
    
    if not rooms:
        default_room = {
            "id": "6a7a240f10967fb304f48226",
            "_id": "6a7a240f10967fb304f48226",
            "name": "General Chat",
            "description": "Lobby Principal",
            "order": 0,
            "enabled": True,
            "is_staff": False,
            "created_at": datetime.datetime.utcnow().isoformat()
        }
        await db.idg_chat_rooms.insert_one(default_room)
        rooms = [default_room]

    filtered_rooms = []
    user_role = user.get("role") if user else None
    user_id = user.get("id") or user.get("_id") if user else None
    
    for r in rooms:
        r_id = r.get("id") or str(r.get("_id", ""))
        r["id"] = r_id
        if "_id" in r:
            del r["_id"]
        if r.get("is_staff"):
            if user_role in ["admin", "root", "mod"] or (user_id and user_id in r.get("allowed_users", [])):
                filtered_rooms.append(r)
        else:
            filtered_rooms.append(r)
            
    if "_id" in settings:
        del settings["_id"]
    settings.pop("ai_api_key", None)
        
    return {
        "rooms": filtered_rooms,
        "settings": settings
    }

@router.get("/idg/chat/rooms/{room_id}/state")
async def get_room_state(room_id: str, request: Request, last_msg_id: Optional[str] = None):
    db = request.app.state.db
    
    now = datetime.datetime.utcnow()
    user = None
    ban = None
    auth = request.headers.get("Authorization")
    if auth and auth.startswith("Bearer "):
        token = auth.split(" ")[1]
        try:
            import jwt
            import os
            payload = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
            user_data = await db.users.find_one({"$or": [{"id": payload["sub"]}, {"_id": payload["sub"]}]})
            if user_data:
                user = {
                    "id": user_data.get("id") or str(user_data.get("_id")),
                    "username": user_data.get("username", "Unknown"),
                    "avatar": user_data.get("avatar_url") or user_data.get("avatar"),
                    "avatar_url": user_data.get("avatar_url") or user_data.get("avatar"),
                    "role": user_data.get("role", "user"),
                    "is_vip": user_data.get("is_vip", False),
                    "vip_tier": user_data.get("vip_tier", "none"),
                    "loadout": user_data.get("loadout", {})
                }
                ban = await db.idg_chat_moderation.find_one({
                    "user_id": user["id"],
                    "type": "ban",
                    "$or": [{"expires_at": None}, {"expires_at": {"$gt": now}}]
                })
        except Exception:
            pass

    settings = await db.idg_chat_settings.find_one({}) or {}
    room = await db.idg_chat_rooms.find_one({"$or": [{"_id": room_id}, {"id": room_id}]})
    if not room:
        room = await db.idg_chat_rooms.find_one({})
        
    if not room:
        raise HTTPException(status_code=404, detail="Room not found")
        
    if room.get("is_staff"):
        user_role = user.get("role") if user else None
        user_id = user.get("id") if user else None
        if user_role not in ["admin", "root", "mod"] and (not user_id or user_id not in room.get("allowed_users", [])):
            raise HTTPException(status_code=403, detail="Nu ai acces în această cameră privată.")
            
    if ban:
        raise HTTPException(status_code=403, detail="Ești banat din chatbox.")
        
    actual_room_id = room.get("id") or str(room.get("_id"))
    
    if user:
        await db.idg_chat_online.update_one(
            {"user_id": user["id"], "room_id": actual_room_id},
            {"$set": {
                "username": user["username"],
                "avatar_url": user.get("avatar_url"),
                "role": user["role"],
                "is_vip": user["is_vip"],
                "last_seen_at": now
            }},
            upsert=True
        )
    
    idle_threshold = now - datetime.timedelta(minutes=2)
    
    possible_room_ids = list(set([room_id, actual_room_id, str(room.get("_id", ""))]))
    query = {"room_id": {"$in": possible_room_ids}}
    if last_msg_id:
        last_msg = await db.idg_chat_messages.find_one({"$or": [{"_id": last_msg_id}, {"id": last_msg_id}]})
        if last_msg:
            query["created_at"] = {"$gt": last_msg.get("created_at")}
            
    active_users = await db.idg_chat_online.find({"room_id": {"$in": possible_room_ids}}).sort("last_seen_at", -1).to_list(100)
    messages = await db.idg_chat_messages.find(query).sort("created_at", -1).limit(60).to_list(60)
    await db.idg_chat_online.delete_many({"last_seen_at": {"$lt": idle_threshold}})
    
    for au in active_users:
        au.pop("_id", None)
        au["last_seen_at"] = au["last_seen_at"].isoformat() if hasattr(au.get("last_seen_at"), "isoformat") else str(au.get("last_seen_at"))
    
    messages.reverse()
    
    # Hydrate user details into messages
    user_ids = set()
    for m in messages:
        if m.get("user_id"):
            user_ids.add(str(m["user_id"]))
    for au in active_users:
        if au.get("user_id"):
            user_ids.add(str(au["user_id"]))
            
    users_data = {}
    if user_ids:
        id_list = list(user_ids)
        db_users = await db.users.find({"$or": [{"id": {"$in": id_list}}, {"_id": {"$in": id_list}}]}).to_list(len(id_list) * 2)
        for u in db_users:
            u_info = {
                "username": u.get("username"),
                "avatar_url": u.get("avatar_url") or u.get("avatar"),
                "role": u.get("role", "user"),
                "is_vip": u.get("is_vip", False),
                "vip_tier": u.get("vip_tier", "none"),
                "loadout": u.get("loadout", {})
            }
            if u.get("id"):
                users_data[str(u["id"])] = u_info
            if u.get("_id"):
                users_data[str(u["_id"])] = u_info
                
    for au in active_users:
        u_id = str(au.get("user_id", ""))
        if u_id in users_data:
            ud = users_data[u_id]
            au["username"] = ud["username"]
            au["avatar_url"] = ud["avatar_url"]
            au["role"] = ud["role"]
            au["is_vip"] = ud["is_vip"]
            au["vip_tier"] = ud["vip_tier"]
            au["loadout"] = ud["loadout"]
            
    for m in messages:
        m_id = m.get("id") or str(m.pop("_id", ""))
        m["id"] = m_id
        if "_id" in m:
            del m["_id"]
        if isinstance(m.get("created_at"), datetime.datetime):
            m["created_at"] = m["created_at"].isoformat()
        u_id = str(m.get("user_id", ""))
        if u_id in users_data:
            ud = users_data[u_id]
            m["username"] = ud["username"]
            m["avatar_url"] = ud["avatar_url"]
            m["role"] = ud["role"]
            m["is_vip"] = ud["is_vip"]
            m["vip_tier"] = ud["vip_tier"]
            m["loadout"] = ud["loadout"]
            
    return {
        "messages": messages,
        "online_users": active_users
    }

@router.post("/idg/chat/rooms/{room_id}/messages")
async def post_message(room_id: str, payload: ChatMessageCreate, request: Request, background_tasks: BackgroundTasks):
    db = request.app.state.db
    user = None
    auth = request.headers.get("Authorization")
    if auth and auth.startswith("Bearer "):
        token = auth.split(" ")[1]
        try:
            import jwt
            import os
            payload_jwt = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
            user = await db.users.find_one({"$or": [{"id": payload_jwt["sub"]}, {"_id": payload_jwt["sub"]}]})
        except Exception:
            pass
            
    if not user:
        raise HTTPException(status_code=401, detail="Trebuie să fii autentificat pentru a trimite mesaje în chat.")

    settings = await db.idg_chat_settings.find_one({}) or {}
    check_chat_perms(user, settings, "post")
    
    user_id = user.get("id") or str(user.get("_id"))
    await check_chat_moderation(db, user_id, "post")
    
    # Check Staff Chat access
    room = await db.idg_chat_rooms.find_one({"$or": [{"_id": room_id}, {"id": room_id}]})
    if not room:
        room = await db.idg_chat_rooms.find_one({})
    if not room:
        raise HTTPException(status_code=404, detail="Room not found")
        
    actual_room_id = room.get("id") or str(room.get("_id"))
    if room.get("is_staff"):
        user_role = user.get("role") if user else None
        if user_role not in ["admin", "root", "mod"] and user_id not in room.get("allowed_users", []):
            raise HTTPException(status_code=403, detail="Nu ai acces în această cameră privată.")
            
    # Check media posting permissions
    is_media = payload.content.startswith(("/yt", "/tk", "/ig", "/img", "/image")) or any(ext in payload.content.lower() for ext in [".jpg", ".png", ".gif", ".webp"])
    if is_media:
        allowed_media = settings.get("allowed_roles_media", ["user", "vip", "mod", "admin", "root"])
        if user.get("role", "user") not in allowed_media and user.get("role") not in ["admin", "root"]:
            raise HTTPException(status_code=403, detail="Nu ai permisiunea de a posta fișiere media în chat.")
            
    # Check group mentions permissions
    import re
    mentions = re.findall(r"@(\w+)", payload.content)
    if mentions:
        all_groups = await db.idg_groups.find({}, {"name": 1, "slug": 1}).to_list(100)
        group_slugs = {g["slug"].lower() for g in all_groups}
        group_names = {g["name"].lower() for g in all_groups}
        
        has_role_mention = False
        for m_name in mentions:
            m_lower = m_name.lower()
            if m_lower in group_slugs or m_lower in group_names:
                has_role_mention = True
                break
                
        if has_role_mention:
            allowed_mention = settings.get("allowed_roles_mention", ["user", "vip", "mod", "admin", "root"])
            if user.get("role", "user") not in allowed_mention and user.get("role") not in ["admin", "root"]:
                raise HTTPException(status_code=403, detail="Nu ai permisiunea de a menționa roluri în chat.")

    # Process Admin commands
    if payload.content.startswith(("/clear", "/ban", "/mute", "/kick")):
        user_role = user.get("role", "user")
        if user_role not in ["admin", "root", "mod"]:
            raise HTTPException(status_code=403, detail="Nu ai permisiuni pentru comenzi administrative.")
            
        parts = payload.content.split(" ")
        cmd = parts[0].lower()
        
        if cmd == "/clear":
            await db.idg_chat_messages.delete_many({"room_id": room_id})
            sys_doc = {
                "_id": str(uuid.uuid4()),
                "room_id": room_id,
                "user_id": "system",
                "username": "System",
                "avatar_url": "https://api.dicebear.com/7.x/bottts/svg?seed=System",
                "role": "system",
                "content": f"Chat-ul a fost curățat de către {user.get('username')}.",
                "created_at": datetime.datetime.utcnow()
            }
            await db.idg_chat_messages.insert_one(sys_doc)
            sys_doc["id"] = sys_doc.pop("_id")
            sys_doc["created_at"] = sys_doc["created_at"].isoformat()
            return sys_doc
            
        elif cmd in ["/ban", "/kick", "/mute"]:
            if len(parts) < 2:
                raise HTTPException(status_code=400, detail="Sintaxă incorectă. Exemplu: /mute username [minute]")
            target_username = parts[1]
            
            target_user = await db.users.find_one({"username_lower": target_username.lower()})
            if not target_user:
                raise HTTPException(status_code=404, detail=f"Utilizatorul '{target_username}' nu a fost găsit.")
                
            target_id = target_user.get("id") or target_user.get("_id")
            
            if cmd == "/ban":
                await db.idg_chat_moderation.update_one(
                    {"user_id": target_id, "type": "ban"},
                    {"$set": {
                        "user_id": target_id,
                        "type": "ban",
                        "expires_at": None,
                        "created_at": datetime.datetime.utcnow(),
                        "moderator_id": user.get("id")
                    }},
                    upsert=True
                )
                content = f"Utilizatorul {target_user.get('username')} a primit BAN din chatbox de la {user.get('username')}."
                
            elif cmd == "/mute":
                duration = None
                if len(parts) >= 3:
                    try:
                        duration = int(parts[2])
                    except ValueError:
                        pass
                
                expires_at = datetime.datetime.utcnow() + datetime.timedelta(minutes=duration) if duration else None
                await db.idg_chat_moderation.update_one(
                    {"user_id": target_id, "type": "mute"},
                    {"$set": {
                        "user_id": target_id,
                        "type": "mute",
                        "expires_at": expires_at,
                        "created_at": datetime.datetime.utcnow(),
                        "moderator_id": user.get("id")
                    }},
                    upsert=True
                )
                dur_str = f" timp de {duration} minute" if duration else " permanent"
                content = f"Utilizatorul {target_user.get('username')} a primit MUTE in chatbox de la {user.get('username')}{dur_str}."
                
            elif cmd == "/kick":
                await db.idg_chat_online.delete_many({"user_id": target_id})
                content = f"Utilizatorul {target_user.get('username')} a primit KICK din chatbox de la {user.get('username')}."
                
            sys_doc = {
                "_id": str(uuid.uuid4()),
                "room_id": room_id,
                "user_id": "system",
                "username": "System",
                "avatar_url": "https://api.dicebear.com/7.x/bottts/svg?seed=System",
                "role": "system",
                "content": content,
                "created_at": datetime.datetime.utcnow()
            }
            await db.idg_chat_messages.insert_one(sys_doc)
            sys_doc["id"] = sys_doc.pop("_id")
            sys_doc["created_at"] = sys_doc["created_at"].isoformat()
            return sys_doc

    # Process Media Embed command
    media = None
    if payload.content.startswith(("/yt", "/tk", "/ig", "/img", "/image")):
        parts = payload.content.split(" ")
        cmd = parts[0].lower()
        if len(parts) >= 2:
            media = {"type": cmd[1:], "url": parts[1]}
        
    msg_id = str(uuid.uuid4())
    msg_doc = {
        "_id": msg_id,
        "id": msg_id,
        "room_id": actual_room_id,
        "user_id": user_id,
        "username": user.get("username"),
        "avatar_url": user.get("avatar_url") or user.get("avatar"),
        "role": user.get("role", "user"),
        "is_vip": user.get("is_vip", False),
        "vip_tier": user.get("vip_tier", "none"),
        "loadout": user.get("loadout", {}),
        "content": payload.content,
        "media": media,
        "created_at": datetime.datetime.utcnow()
    }
    
    await db.idg_chat_messages.insert_one(msg_doc)
    msg_doc["id"] = str(msg_doc.pop("_id"))
    msg_doc["created_at"] = msg_doc["created_at"].isoformat()

    # Trigger AI if mentioned or asked
    clean_upper = payload.content.upper()
    triggers = ["@AI", "@BOT", "@INDUNGI", "@INDUNGI_BOT", "!AI", "!BOT", "!HELP", "!INDUNGI", "/AI", "/BOT"]
    is_triggered = any(t in clean_upper for t in triggers) or payload.content.strip().lower().startswith(("bot ", "bot, ", "ai ", "ai, ", "!ai ", "!bot ", "ajutor "))
    if is_triggered:
        ai_key = settings.get("ai_api_key") or os.environ.get("GEMINI_API_KEY") or os.environ.get("OPENAI_API_KEY") or ""
        background_tasks.add_task(process_ai_message, db, room_id, payload.content, ai_key, user)

    return msg_doc

@router.patch("/idg/chat/rooms/{room_id}/messages/{msg_id}")
async def edit_message(room_id: str, msg_id: str, payload: ChatMessageCreate, request: Request):
    db = request.app.state.db
    auth = request.headers.get("Authorization")
    if not auth or not auth.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Unauthorized")
    token = auth.split(" ")[1]
    try:
        import jwt
        import os
        payload_jwt = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
        user = await db.users.find_one({"id": payload_jwt["sub"]})
    except Exception:
        raise HTTPException(status_code=401, detail="Unauthorized")
        
    if not user:
        raise HTTPException(status_code=401, detail="Unauthorized")
        
    msg = await db.idg_chat_messages.find_one({"_id": msg_id, "room_id": room_id})
    if not msg:
        raise HTTPException(status_code=404, detail="Message not found")
        
    user_id = user.get("id") or user.get("_id")
    if msg.get("user_id") != user_id and user.get("role") not in ["admin", "root"]:
        raise HTTPException(status_code=403, detail="You can only edit your own messages.")
        
    await db.idg_chat_messages.update_one(
        {"_id": msg_id},
        {"$set": {
            "content": payload.content,
            "edited_at": datetime.datetime.utcnow().isoformat()
        }}
    )
    return {"status": "ok"}

@router.post("/idg/chat/rooms/{room_id}/messages/{msg_id}/react")
async def react_message(room_id: str, msg_id: str, payload: ChatMessageReact, request: Request):
    db = request.app.state.db
    auth = request.headers.get("Authorization")
    if not auth or not auth.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Unauthorized")
    token = auth.split(" ")[1]
    try:
        import jwt
        import os
        payload_jwt = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
        user = await db.users.find_one({"id": payload_jwt["sub"]})
    except Exception:
        raise HTTPException(status_code=401, detail="Unauthorized")
        
    if not user:
        raise HTTPException(status_code=401, detail="Unauthorized")
        
    msg = await db.idg_chat_messages.find_one({"_id": msg_id, "room_id": room_id})
    if not msg:
        raise HTTPException(status_code=404, detail="Message not found")
        
    user_id = user.get("id") or user.get("_id")
    reactions = msg.get("reactions") or {}
    
    emoji = payload.emoji
    if emoji in reactions:
        if user_id in reactions[emoji]:
            reactions[emoji].remove(user_id)
            if not reactions[emoji]:
                del reactions[emoji]
        else:
            reactions[emoji].append(user_id)
    else:
        reactions[emoji] = [user_id]
        
    await db.idg_chat_messages.update_one(
        {"_id": msg_id},
        {"$set": {"reactions": reactions}}
    )
    return {"status": "ok", "reactions": reactions}



# ADMIN ENDPOINTS

async def require_admin(request: Request):
    db = request.app.state.db
    auth = request.headers.get("Authorization")
    if not auth or not auth.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Unauthorized")
    token = auth.split(" ")[1]
    try:
        import jwt
        import os
        payload = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
        user = await db.users.find_one({"id": payload["sub"]})
        if not user or user.get("role") not in ["admin", "root"]:
            raise HTTPException(status_code=403, detail="Forbidden")
        return user
    except Exception:
        raise HTTPException(status_code=403, detail="Forbidden")

@router.get("/idg/admin/chat/rooms")
async def admin_get_rooms(request: Request):
    await require_admin(request)
    db = request.app.state.db
    rooms = await db.idg_chat_rooms.find().sort("order", 1).to_list(100)
    for r in rooms:
        r["id"] = str(r.pop("_id"))
    return rooms

@router.post("/idg/admin/chat/rooms")
async def admin_create_room(payload: ChatRoomCreate, request: Request):
    await require_admin(request)
    db = request.app.state.db
    room_id = str(uuid.uuid4())
    doc = payload.dict()
    doc["_id"] = room_id
    await db.idg_chat_rooms.insert_one(doc)
    doc["id"] = str(doc.pop("_id"))
    return doc

@router.patch("/idg/admin/chat/rooms/{room_id}")
async def admin_update_room(room_id: str, payload: ChatRoomUpdate, request: Request):
    await require_admin(request)
    db = request.app.state.db
    update_data = {k: v for k, v in payload.dict().items() if v is not None}
    if not update_data:
        return {"status": "ok"}
    await db.idg_chat_rooms.update_one({"_id": get_room_query_id(room_id)}, {"$set": update_data})
    return {"status": "ok"}

@router.delete("/idg/admin/chat/rooms/{room_id}")
async def admin_delete_room(room_id: str, request: Request):
    await require_admin(request)
    db = request.app.state.db
    await db.idg_chat_rooms.delete_one({"_id": get_room_query_id(room_id)})
    db.idg_chat_messages.delete_many({"room_id": room_id})
    db.idg_chat_online.delete_many({"room_id": room_id})
    return {"status": "ok"}

@router.get("/idg/admin/chat/settings")
async def admin_get_settings(request: Request):
    await require_admin(request)
    db = request.app.state.db
    settings = await db.idg_chat_settings.find_one({}) or {}
    if "_id" in settings:
        del settings["_id"]
    return settings

@router.patch("/idg/admin/chat/settings")
async def admin_update_settings(payload: ChatSettingsUpdate, request: Request):
    await require_admin(request)
    db = request.app.state.db
    update_data = {k: v for k, v in payload.dict().items() if v is not None}
    if update_data:
        await db.idg_chat_settings.update_one({}, {"$set": update_data}, upsert=True)
    return {"status": "ok"}

@router.get("/idg/chat/roles")
async def get_chat_roles(request: Request):
    db = request.app.state.db
    groups = await db.idg_groups.find({}, {"_id": 0, "name": 1, "slug": 1, "color": 1}).to_list(100)
    return groups

class ChatAnnouncementUpdate(BaseModel):
    announcement_text: str

@router.post("/idg/chat/settings/announcement")
async def update_chat_announcement(payload: ChatAnnouncementUpdate, request: Request):
    db = request.app.state.db
    auth = request.headers.get("Authorization")
    if not auth or not auth.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Unauthorized")
    token = auth.split(" ")[1]
    try:
        import jwt
        import os
        payload_jwt = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
        user = await db.users.find_one({"id": payload_jwt["sub"]})
    except Exception:
        raise HTTPException(status_code=401, detail="Unauthorized")
        
    if not user or user.get("role") not in ["admin", "root"]:
        raise HTTPException(status_code=403, detail="Forbidden")
        
    await db.idg_chat_settings.update_one({}, {"$set": {"announcement_text": payload.announcement_text}}, upsert=True)
    return {"status": "ok", "announcement_text": payload.announcement_text}

@router.get("/idg/chat/rooms/{room_id}/members")
async def get_room_members(room_id: str, request: Request):
    db = request.app.state.db
    auth = request.headers.get("Authorization")
    if not auth or not auth.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Unauthorized")
    token = auth.split(" ")[1]
    try:
        import jwt
        import os
        payload_jwt = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
        user = await db.users.find_one({"id": payload_jwt["sub"]})
    except Exception:
        raise HTTPException(status_code=401, detail="Unauthorized")
        
    if not user or user.get("role") not in ["admin", "root", "mod"]:
        raise HTTPException(status_code=403, detail="Forbidden")
        
    room = await db.idg_chat_rooms.find_one({"_id": get_room_query_id(room_id)})
    if not room:
        raise HTTPException(status_code=404, detail="Room not found")
        
    allowed_ids = room.get("allowed_users") or []
    if not allowed_ids:
        return []
        
    members = await db.users.find(
        {"id": {"$in": allowed_ids}},
        {"_id": 0, "id": 1, "username": 1, "avatar_url": 1, "role": 1}
    ).to_list(100)
    return members

@router.post("/idg/chat/rooms/{room_id}/members")
async def add_room_member(room_id: str, payload: Dict[str, str], request: Request):
    db = request.app.state.db
    auth = request.headers.get("Authorization")
    if not auth or not auth.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Unauthorized")
    token = auth.split(" ")[1]
    try:
        import jwt
        import os
        payload_jwt = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
        user = await db.users.find_one({"id": payload_jwt["sub"]})
    except Exception:
        raise HTTPException(status_code=401, detail="Unauthorized")
        
    if not user or user.get("role") not in ["admin", "root", "mod"]:
        raise HTTPException(status_code=403, detail="Forbidden")
        
    user_id = payload.get("user_id")
    if not user_id:
        raise HTTPException(status_code=400, detail="Missing user_id")
        
    await db.idg_chat_rooms.update_one({"_id": get_room_query_id(room_id)}, {"$addToSet": {"allowed_users": user_id}})
    return {"status": "ok"}

@router.delete("/idg/chat/rooms/{room_id}/members/{user_id}")
async def remove_room_member(room_id: str, user_id: str, request: Request):
    db = request.app.state.db
    auth = request.headers.get("Authorization")
    if not auth or not auth.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Unauthorized")
    token = auth.split(" ")[1]
    try:
        import jwt
        import os
        payload_jwt = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
        user = await db.users.find_one({"id": payload_jwt["sub"]})
    except Exception:
        raise HTTPException(status_code=401, detail="Unauthorized")
        
    if not user or user.get("role") not in ["admin", "root", "mod"]:
        raise HTTPException(status_code=403, detail="Forbidden")
        
    await db.idg_chat_rooms.update_one({"_id": get_room_query_id(room_id)}, {"$pull": {"allowed_users": user_id}})
    return {"status": "ok"}

@router.post("/idg/chat/moderation/action")
async def perform_moderation_action(payload: ChatModerationAction, request: Request):
    db = request.app.state.db
    auth = request.headers.get("Authorization")
    if not auth or not auth.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Unauthorized")
    token = auth.split(" ")[1]
    try:
        import jwt
        import os
        payload_jwt = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
        user = await db.users.find_one({"id": payload_jwt["sub"]})
    except Exception:
        raise HTTPException(status_code=401, detail="Unauthorized")
        
    if not user or user.get("role") not in ["admin", "root", "mod"]:
        raise HTTPException(status_code=403, detail="Forbidden")
        
    target_username = payload.target_username
    if target_username.startswith("@"):
        target_username = target_username[1:]
        
    target_user = await db.users.find_one({
        "$or": [
            {"username_lower": target_username.lower()},
            {"username": target_username}
        ]
    })
    if not target_user:
        raise HTTPException(status_code=404, detail=f"Utilizatorul '{target_username}' nu a fost găsit.")
        
    target_id = target_user.get("id") or target_user.get("_id")
    action_type = payload.action_type.lower()
    if action_type not in ["ban", "mute", "kick"]:
        raise HTTPException(status_code=400, detail="Tip acțiune invalid. Valori permise: ban, mute, kick.")
        
    now = datetime.datetime.utcnow()
    dur_str = ""
    
    if action_type == "ban":
        expires_at = now + datetime.timedelta(minutes=payload.duration) if payload.duration else None
        await db.idg_chat_moderation.update_one(
            {"user_id": target_id, "type": "ban"},
            {"$set": {
                "user_id": target_id,
                "type": "ban",
                "expires_at": expires_at,
                "created_at": now,
                "moderator_id": user.get("id")
            }},
            upsert=True
        )
        if payload.duration:
            dur_str = f" timp de {payload.duration} minute"
        else:
            dur_str = " permanent"
            
    elif action_type == "mute":
        expires_at = now + datetime.timedelta(minutes=payload.duration) if payload.duration else None
        await db.idg_chat_moderation.update_one(
            {"user_id": target_id, "type": "mute"},
            {"$set": {
                "user_id": target_id,
                "type": "mute",
                "expires_at": expires_at,
                "created_at": now,
                "moderator_id": user.get("id")
            }},
            upsert=True
        )
        if payload.duration:
            dur_str = f" timp de {payload.duration} minute"
        else:
            dur_str = " permanent"
            
    elif action_type == "kick":
        await db.idg_chat_online.delete_many({"user_id": target_id})
        
    content = f"Utilizatorul {target_user.get('username')} a primit {action_type.upper()} în chatbox de la {user.get('username')}{dur_str}. Motiv: {payload.reason}."
    if payload.proof_url:
        content += f" Dovezi: {payload.proof_url}"
        
    media = None
    if payload.proof_url:
        ext = payload.proof_url.rsplit(".", 1)[-1].lower()
        media_type = "video" if ext in ["mp4", "webm"] else "image"
        media = {"type": media_type, "url": payload.proof_url}
        
    sys_doc = {
        "_id": str(uuid.uuid4()),
        "room_id": payload.room_id,
        "user_id": "system",
        "username": "System",
        "avatar_url": "https://api.dicebear.com/7.x/bottts/svg?seed=System",
        "role": "system",
        "content": content,
        "media": media,
        "created_at": now
    }
    await db.idg_chat_messages.insert_one(sys_doc)
    sys_doc["id"] = sys_doc.pop("_id")
    sys_doc["created_at"] = sys_doc["created_at"].isoformat()
    
    # Notify user in notifications
    import urllib.parse
    reason_quoted = urllib.parse.quote(payload.reason)
    mod_quoted = urllib.parse.quote(user.get("username"))
    proof_quoted = urllib.parse.quote(payload.proof_url or "")
    
    notif_id = uuid.uuid4().hex
    notif_doc = {
        "id": notif_id,
        "user_id": target_id,
        "type": "sanction",
        "title": "Ai fost sancționat în chatbox!",
        "body": f"Sancțiune: {action_type} | Motiv: {payload.reason} (Apasă pentru detalii/contestație)",
        "link": f"/chatbox?appeal=1&action={action_type}&reason={reason_quoted}&mod={mod_quoted}&proof={proof_quoted}",
        "read": False,
        "created_at": datetime.datetime.utcnow().isoformat() + "Z"
    }
    await db.notifications.insert_one(notif_doc)
    
    return {"status": "ok", "message": sys_doc}

@router.post("/idg/chat/moderation/appeal")
async def submit_moderation_appeal(payload: ChatModerationAppeal, request: Request):
    db = request.app.state.db
    auth = request.headers.get("Authorization")
    if not auth or not auth.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Unauthorized")
    token = auth.split(" ")[1]
    try:
        import jwt
        import os
        payload_jwt = jwt.decode(token, os.environ['JWT_SECRET'], algorithms=["HS256"])
        user = await db.users.find_one({"id": payload_jwt["sub"]})
    except Exception:
        raise HTTPException(status_code=401, detail="Unauthorized")
        
    if not user:
        raise HTTPException(status_code=401, detail="Unauthorized")
        
    admins = await db.users.find({"role": {"$in": ["admin", "root"]}}).to_list(1000)
    if not admins:
        raise HTTPException(status_code=500, detail="Nu există niciun administrator înregistrat.")
        
    proof_str = payload.proof_url if payload.proof_url else "Fără dovezi atașate."
    appeal_content = (
        f"[Contestație Sancțiune Chatbox]\n"
        f"• Tip Sancțiune: {payload.action_type}\n"
        f"• Dată de: {payload.moderator_username}\n"
        f"• Motiv: {payload.reason}\n"
        f"• Dovezi: {proof_str}\n\n"
        f"Mesaj contestație:\n"
        f"{payload.appeal_text}"
    )
    
    timestamp = datetime.datetime.utcnow().isoformat() + "Z"
    
    async def get_or_create_dm_thread(user_a: str, user_b: str):
        key = "::".join(sorted([user_a, user_b]))
        thread = await db.dm_threads.find_one({"key": key})
        if thread:
            return thread
        thread = {
            "id": uuid.uuid4().hex,
            "key": key,
            "participants": sorted([user_a, user_b]),
            "last_message_at": timestamp,
            "last_message_preview": "",
            "last_sender_id": "",
            "created_at": timestamp,
            "unread": {user_a: 0, user_b: 0},
        }
        await db.dm_threads.insert_one(thread)
        return thread

    for admin in admins:
        admin_id = admin["id"]
        if admin_id == user["id"]:
            continue
            
        thread = await get_or_create_dm_thread(user["id"], admin_id)
        msg_id = uuid.uuid4().hex
        msg = {
            "id": msg_id,
            "thread_id": thread["id"],
            "sender_id": user["id"],
            "sender_username": user["username"],
            "recipient_id": admin_id,
            "content": appeal_content,
            "created_at": timestamp,
            "read": False,
        }
        await db.dms.insert_one(msg)
        
        unread = thread.get("unread", {})
        unread[admin_id] = unread.get(admin_id, 0) + 1
        await db.dm_threads.update_one(
            {"id": thread["id"]},
            {"$set": {
                "last_message_at": timestamp,
                "last_message_preview": appeal_content[:120],
                "last_sender_id": user["id"],
                "unread": unread
            }}
        )
        
        notif_id = uuid.uuid4().hex
        await db.notifications.insert_one({
            "id": notif_id,
            "user_id": admin_id,
            "type": "dm",
            "title": f"Contestație chat de la {user['username']}",
            "body": appeal_content[:120],
            "link": f"/messages/{thread['id']}",
            "read": False,
            "created_at": timestamp,
        })
        
    return {"status": "ok"}

