from aiohttp import web
import logging
from database import db
from utils.payment import zarinpal_verify, zibal_verify
from aiogram import Bot

logger = logging.getLogger(__name__)

async def execute_pending_action(bot: Bot, user_id: int, action_type: str, action_meta: str) -> str:
    from database import db
    from utils import texts
    from keyboards import inline
    
    if action_type == 'hire':
        try:
            bid_id, project_id = map(int, action_meta.split("_"))
            bid = await db.get_bid(bid_id)
            project = await db.get_project(project_id)
            
            if bid and project:
                db_success = await db.accept_bid(bid_id, project_id, bid['freelancer_id'], user_id, bid['amount'])
                if db_success:
                    try:
                        client = await db.get_user(user_id)
                        client_name = client['full_name'] if client else "کارفرما"
                        await bot.send_message(
                            bid['freelancer_id'],
                            texts.bid_accepted_notification(project['title'], client_name, bid['amount']),
                            reply_markup=inline.freelancer_accepted_project_keyboard(project['project_id'], 'in_progress'),
                            parse_mode="HTML"
                        )
                    except Exception as e:
                        logger.error(f"Error notifying freelancer in web server: {e}")
                    
                    return f"🤝 <b>فریلنسر با موفقیت استخدام شد!</b>\nمبلغ <b>{bid['amount']:,} تومان</b> برای پروژه «{project['title']}» در صندوق امن تودیع گردید."
        except Exception as ex:
            logger.error(f"Error executing hire action: {ex}")
            
    elif action_type == 'vip':
        try:
            parts = action_meta.split("_") if action_meta else []
            level = int(parts[0]) if len(parts) > 0 else 1
            months = int(parts[1]) if len(parts) > 1 else 1
            
            p1 = int(await db.get_setting('vip_bronze_price', 50000))
            p2 = int(await db.get_setting('vip_silver_price', 100000))
            p3 = int(await db.get_setting('vip_gold_price', 200000))
            
            base_price = {1: p1, 2: p2, 3: p3}.get(level, p1)
            price_map = {1: base_price, 3: int(base_price * 2.7), 6: base_price * 5, 12: base_price * 9}
            price = price_map.get(months, base_price)
            
            names = {1: "برنزی", 2: "نقره‌ای", 3: "طلایی"}
            name = f"{names.get(level, 'ویژه')} ({months} ماهه)"
            
            s_bronze = int(await db.get_setting('connects_monthly_bronze', '50'))
            s_silver = int(await db.get_setting('connects_monthly_silver', '100'))
            s_gold = int(await db.get_setting('connects_monthly_gold', '200'))
            base_bonus = {1: s_bronze, 2: s_silver, 3: s_gold}.get(level, s_bronze)
            bonus_multiplier = {1: 1, 3: 3.5, 6: 8, 12: 20}.get(months, 1)
            bonus = int(base_bonus * bonus_multiplier)
            
            user = await db.get_user(user_id)
            if user and user['balance'] >= price:
                await db.update_balance(user_id, -price, "subscription", f"خرید اشتراک VIP {name}")
                await db.activate_vip(user_id, level=level, months=months)
                await db.update_connects(user_id, bonus, "vip_bonus", f"هدیه فعالسازی اشتراک VIP {name}")
                return f"💎 <b>اشتراک VIP {name} شما با موفقیت فعال شد!</b>\nتعداد <b>{bonus} کانکت</b> هدیه دریافت کردید."
        except Exception as ex:
            logger.error(f"Error executing VIP action: {ex}")
            
    elif action_type == 'upgrade_ft':
        try:
            project_id = int(action_meta)
            project = await db.get_project(project_id)
            if project and not project.get('is_fulltime', 0):
                price = int(await db.get_setting('fulltime_price', 20000))
                user = await db.get_user(user_id)
                if user and user['balance'] >= price:
                    await db.update_balance(user_id, -price, "service", f"هزینه ارتقا به تمام‌وقت برای پروژه {project_id}")
                    await db.update_project_fulltime(project_id, True)
                    return f"🌟 <b>پروژه شما با موفقیت به تمام‌وقت ارتقا یافت!</b>"
        except Exception as ex:
            logger.error(f"Error executing upgrade_ft action: {ex}")
            
    elif action_type == 'promo':
        try:
            project_id = int(action_meta)
            featured_project_price = await db.get_setting_int("featured_project_price", 50000)
            user = await db.get_user(user_id)
            if user and user['balance'] >= featured_project_price:
                db_success = await db.promote_project(project_id, user_id, featured_project_price)
                if db_success:
                    return "🔥 <b>پروژه شما با موفقیت ویژه شد!</b>\nاین پروژه اکنون با اولویت بالاتر به فریلنسرها نمایش داده می‌شود."
        except Exception as ex:
            logger.error(f"Error executing promo action: {ex}")
            
    return ""

def render_payment_result_html(is_success: bool, title: str, description: str, amount: int = None, ref_id: str = None) -> str:
    import os
    template_path = "assets/payment_result.html"
    html_content = ""
    if os.path.exists(template_path):
        try:
            with open(template_path, 'r', encoding='utf-8') as f:
                html_content = f.read()
        except Exception:
            pass
            
    if not html_content:
        # Fallback if file read fails
        html_content = "<html><body style='font-family:Tahoma; text-align:center; padding:50px;'><h1>{TITLE}</h1><p>{DESCRIPTION}</p></body></html>"
        
    status_class = "status-success" if is_success else "status-error"
    if is_success:
        status_icon = """
        <svg class="icon-svg" viewBox="0 0 24 24">
            <polyline points="20 6 9 17 4 12"></polyline>
        </svg>
        """
    else:
        status_icon = """
        <svg class="icon-svg" viewBox="0 0 24 24">
            <line x1="18" y1="6" x2="6" y2="18"></line>
            <line x1="6" y1="6" x2="18" y2="18"></line>
        </svg>
        """
        
    details_html = ""
    if amount is not None or ref_id is not None:
        details_html += '<div class="details-box">'
        if amount is not None:
            details_html += f"""
            <div class="details-row">
                <span class="details-label">مبلغ پرداخت:</span>
                <span class="details-value amount">{amount:,} تومان</span>
            </div>
            """
        if ref_id is not None:
            details_html += f"""
            <div class="details-row">
                <span class="details-label">کد رهگیری / شناسه:</span>
                <span class="details-value">{ref_id}</span>
            </div>
            """
        details_html += '</div>'
        
    # Standard bot username configuration
    bot_username = "XLancer_bot"
    
    # Replace placeholders
    html_content = html_content.replace("{TITLE}", title)
    html_content = html_content.replace("{DESCRIPTION}", description)
    html_content = html_content.replace("{STATUS_CLASS}", status_class)
    html_content = html_content.replace("{STATUS_ICON}", status_icon)
    html_content = html_content.replace("{DETAILS_HTML}", details_html)
    html_content = html_content.replace("{BOT_USERNAME}", bot_username)
    html_content = html_content.replace("{IS_SUCCESS}", "true" if is_success else "false")
    
    return html_content

async def zarinpal_verify_handler(request):
    try:
        bot = request.app['bot']
        params = request.rel_url.query
        user_id_str = params.get('user_id')
        amount_str = params.get('amount')
        authority = params.get('Authority')
        status = params.get('Status')
        
        if not (user_id_str and amount_str and authority):
            html = render_payment_result_html(
                is_success=False,
                title="مشکل در تایید پرداخت",
                description="پارامترهای بازگشتی از درگاه معتبر نیستند."
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
            
        try:
            user_id = int(user_id_str)
            amount = int(amount_str)
        except ValueError:
            html = render_payment_result_html(
                is_success=False,
                title="پارامترهای نامعتبر",
                description="فرمت اطلاعات شناسه کاربر یا مبلغ اشتباه است."
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
            
        payment = await db.get_online_payment(authority)
        if not payment:
            html = render_payment_result_html(
                is_success=False,
                title="تراکنش یافت نشد",
                description="تراکنش مربوط به این شناسه در سیستم وجود ندارد."
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
            
        if payment['status'] == 'completed':
            html = render_payment_result_html(
                is_success=True,
                title="پرداخت قبلاً تایید شده است",
                description="این تراکنش قبلاً تأیید و حساب شما شارژ شده است. می‌توانید به ربات بازگردید.",
                amount=amount,
                ref_id=payment.get('ref_id') or authority
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
            
        if status != 'OK':
            await db.update_online_payment_status(authority, 'failed')
            html = render_payment_result_html(
                is_success=False,
                title="پرداخت ناموفق",
                description="تراکنش توسط کاربر لغو شد یا ناموفق بود.",
                amount=amount
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
            
        merchant = await db.get_setting('zarinpal_merchant', 'zarinpal')
        sandbox = (await db.get_setting('zarinpal_sandbox', '1')) == '1'
        
        success, ref_id = await zarinpal_verify(merchant, amount, authority, sandbox)
        
        if success:
            await db.update_online_payment_status(authority, 'completed')
            await db.update_balance(user_id, amount, "deposit", f"شارژ آنلاین (ZarinPal) - کد رهگیری {ref_id}")
            
            action_type = params.get('action_type', '')
            action_meta = params.get('action_meta', '')
            
            action_text = ""
            if action_type:
                action_text = await execute_pending_action(bot, user_id, action_type, action_meta)
                
            try:
                from keyboards import reply
                client = await db.get_user(user_id)
                is_admin = user_id in __import__('config').ADMIN_IDS
                role = client['role'] if client else 'client'
                kb = reply.client_main_menu(is_admin=is_admin) if role == 'client' else reply.freelancer_main_menu(is_admin=is_admin)
 
                if action_text:
                    msg = (
                        f"🎉 <b>پرداخت و اقدام مالی با موفقیت انجام شد!</b>\n\n"
                        f"💰 مبلغ <b>{amount:,} تومان</b> به کیف پول شما افزوده شد.\n"
                        f"🧾 کد رهگیری: <code>{ref_id}</code>\n\n"
                        f"{action_text}"
                    )
                else:
                    msg = (
                        f"🎉 <b>شارژ آنلاین با موفقیت انجام شد!</b>\n\n"
                        f"💰 مبلغ <b>{amount:,} تومان</b> به حساب شما افزوده شد.\n"
                        f"🧾 کد رهگیری: <code>{ref_id}</code>"
                    )
                
                await bot.send_message(user_id, msg, reply_markup=kb, parse_mode="HTML")
            except Exception as e:
                logger.error(f"Error notifying user of verification: {e}")
                
            html = render_payment_result_html(
                is_success=True,
                title="پرداخت با موفقیت انجام شد!",
                description="حساب کاربری شما با موفقیت شارژ گردید. می‌توانید این صفحه را ببندید و به تلگرام بازگردید.",
                amount=amount,
                ref_id=ref_id
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
        else:
            html = render_payment_result_html(
                is_success=False,
                title="تایید پرداخت ناموفق بود",
                description=f"خطا در تأیید تراکنش: {ref_id}",
                amount=amount
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
    except Exception as e:
        logger.error(f"Zarinpal verify handler exception: {e}")
        html = render_payment_result_html(
            is_success=False,
            title="خطای سرور",
            description=f"مشکلی در پردازش تاییدیه رخ داد: {e}"
        )
        return web.Response(text=html, content_type="text/html; charset=utf-8")

async def zibal_verify_handler(request):
    try:
        bot = request.app['bot']
        params = request.rel_url.query
        user_id_str = params.get('user_id')
        amount_str = params.get('amount')
        track_id = params.get('trackId')
        success_status = params.get('success')
        
        if not (user_id_str and amount_str and track_id):
            html = render_payment_result_html(
                is_success=False,
                title="مشکل در تایید پرداخت",
                description="پارامترهای بازگشتی از درگاه معتبر نیستند."
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
            
        try:
            user_id = int(user_id_str)
            amount = int(amount_str)
        except ValueError:
            html = render_payment_result_html(
                is_success=False,
                title="پارامترهای نامعتبر",
                description="فرمت اطلاعات شناسه کاربر یا مبلغ اشتباه است."
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
            
        payment = await db.get_online_payment(track_id)
        if not payment:
            html = render_payment_result_html(
                is_success=False,
                title="تراکنش یافت نشد",
                description="تراکنش مربوط به این شناسه در سیستم وجود ندارد."
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
            
        if payment['status'] == 'completed':
            html = render_payment_result_html(
                is_success=True,
                title="پرداخت قبلاً تایید شده است",
                description="این تراکنش قبلاً تأیید و حساب شما شارژ شده است. می‌توانید به ربات بازگردید.",
                amount=amount,
                ref_id=payment.get('ref_id') or track_id
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
            
        if success_status != '1':
            await db.update_online_payment_status(track_id, 'failed')
            html = render_payment_result_html(
                is_success=False,
                title="پرداخت ناموفق",
                description="تراکنش توسط کاربر لغو شد یا ناموفق بود.",
                amount=amount
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
            
        merchant = await db.get_setting('zibal_merchant', 'zibal')
        success, ref_id = await zibal_verify(merchant, track_id)
        
        if success:
            await db.update_online_payment_status(track_id, 'completed')
            await db.update_balance(user_id, amount, "deposit", f"شارژ آنلاین (Zibal) - کد رهگیری {ref_id}")
            
            action_type = params.get('action_type', '')
            action_meta = params.get('action_meta', '')
            
            action_text = ""
            if action_type:
                action_text = await execute_pending_action(bot, user_id, action_type, action_meta)
                
            try:
                from keyboards import reply
                client = await db.get_user(user_id)
                is_admin = user_id in __import__('config').ADMIN_IDS
                role = client['role'] if client else 'client'
                kb = reply.client_main_menu(is_admin=is_admin) if role == 'client' else reply.freelancer_main_menu(is_admin=is_admin)
 
                if action_text:
                    msg = (
                        f"🎉 <b>پرداخت و اقدام مالی با موفقیت انجام شد!</b>\n\n"
                        f"💰 مبلغ <b>{amount:,} تومان</b> به کیف پول شما افزوده شد.\n"
                        f"🧾 کد رهگیری: <code>{ref_id}</code>\n\n"
                        f"{action_text}"
                    )
                else:
                    msg = (
                        f"🎉 <b>شارژ آنلاین با موفقیت انجام شد!</b>\n\n"
                        f"💰 مبلغ <b>{amount:,} تومان</b> به حساب شما افزوده شد.\n"
                        f"🧾 کد رهگیری: <code>{ref_id}</code>"
                    )
                
                await bot.send_message(user_id, msg, reply_markup=kb, parse_mode="HTML")
            except Exception as e:
                logger.error(f"Error notifying user of verification: {e}")
                
            html = render_payment_result_html(
                is_success=True,
                title="پرداخت با موفقیت انجام شد!",
                description="حساب کاربری شما با موفقیت شارژ گردید. می‌توانید این صفحه را ببندید و به تلگرام بازگردید.",
                amount=amount,
                ref_id=ref_id
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
        else:
            html = render_payment_result_html(
                is_success=False,
                title="تایید پرداخت ناموفق بود",
                description=f"خطا در تأیید تراکنش: {ref_id}",
                amount=amount
            )
            return web.Response(text=html, content_type="text/html; charset=utf-8")
    except Exception as e:
        logger.error(f"Zibal verify handler exception: {e}")
        html = render_payment_result_html(
            is_success=False,
            title="خطای سرور",
            description=f"مشکلی در پردازش تاییدیه رخ داد: {e}"
        )
        return web.Response(text=html, content_type="text/html; charset=utf-8")


async def dispute_chat_handler(request):
    try:
        project_id_str = request.query.get('project_id')
        token = request.query.get('token')
        
        if not project_id_str or not token:
            from aiohttp import web
            return web.Response(text="مشخصات نامعتبر", status=400)
            
        project_id = int(project_id_str)
        import hashlib
        expected_token = hashlib.sha256(f"Xlancer_Secret_{project_id}".encode()).hexdigest()
        if token != expected_token:
            from aiohttp import web
            return web.Response(text="توکن نامعتبر یا منقضی شده است", status=403)
            
        from database import db
        messages = await db.get_dispute_messages(project_id)
        if not messages:
            from aiohttp import web
            return web.Response(text="هیچ پیامی برای این پروژه یافت نشد.", content_type="text/html; charset=utf-8", status=200)
            
        project = await db.get_project(project_id)
        client_id = project['client_id']
        freelancer_id = project['chosen_freelancer_id']
        
        html = """
        <!DOCTYPE html>
        <html lang="fa" dir="rtl">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>لاگ داوری پروژه #""" + str(project_id) + """</title>
            <style>
                body { font-family: Tahoma, Arial, sans-serif; background-color: #e5ddd5; margin: 0; padding: 0; }
                .header { background-color: #075e54; color: white; padding: 15px; text-align: center; position: sticky; top: 0; z-index: 100;}
                .search-box { padding: 10px; background: #f6f6f6; text-align: center; position: sticky; top: 50px; z-index: 99;}
                .search-input { width: 80%; padding: 8px; border-radius: 20px; border: 1px solid #ccc; outline: none; }
                .chat-container { max-width: 800px; margin: 0 auto; padding: 20px; display: flex; flex-direction: column; gap: 10px; }
                .message { max-width: 70%; padding: 10px 15px; border-radius: 10px; position: relative; box-shadow: 0 1px 1px rgba(0,0,0,0.1); word-wrap: break-word;}
                .msg-client { background-color: #dcf8c6; align-self: flex-start; border-top-right-radius: 0;}
                .msg-freelancer { background-color: #ffffff; align-self: flex-end; border-top-left-radius: 0;}
                .msg-admin { background-color: #fff3c4; align-self: center; text-align: center;}
                .msg-sender { font-size: 0.8em; font-weight: bold; color: #075e54; margin-bottom: 5px;}
                .msg-time { font-size: 0.7em; color: #999; text-align: left; margin-top: 5px;}
            </style>
        </head>
        <body>
            <div class="header">
                <h2>⚖️ چت داوری پروژه #""" + str(project_id) + """</h2>
            </div>
            <div class="search-box">
                <input type="text" class="search-input" id="searchInput" placeholder="🔍 جستجو در پیام‌ها..." onkeyup="searchMessages()">
            </div>
            <div class="chat-container" id="chatContainer">
        """
        
        for msg in messages:
            sender_id = msg['sender_id']
            text = msg['message_text'] or ""
            time = msg['created_at']
            
            if sender_id == client_id:
                msg_class = "msg-client"
                sender_name = "کارفرما"
            elif sender_id == freelancer_id:
                msg_class = "msg-freelancer"
                sender_name = "فریلنسر"
            else:
                msg_class = "msg-admin"
                sender_name = "ادمین / داور"
                
            html += f"""
                <div class="message {msg_class}">
                    <div class="msg-sender">{sender_name}</div>
                    <div class="msg-text">{text.replace(chr(10), '<br>')}</div>
                    <div class="msg-time">{time}</div>
                </div>
            """
            
        html += """
            </div>
            <script>
                function searchMessages() {
                    let input = document.getElementById('searchInput').value.toLowerCase();
                    let messages = document.getElementsByClassName('message');
                    for (let i = 0; i < messages.length; i++) {
                        let text = messages[i].getElementsByClassName('msg-text')[0].innerText.toLowerCase();
                        if (text.includes(input)) {
                            messages[i].style.display = "";
                        } else {
                            messages[i].style.display = "none";
                        }
                    }
                }
                window.scrollTo(0, document.body.scrollHeight);
            </script>
        </body>
        </html>
        """
        from aiohttp import web
        return web.Response(text=html, content_type="text/html; charset=utf-8")
    except Exception as e:
        logger.error(f"Dispute WebApp error: {e}")
        from aiohttp import web
        return web.Response(text="خطای سرور", status=500)

async def zarinpal_pay_deposit_handler(request):
    try:
        user_id_str = request.query.get('user_id')
        amount_str = request.query.get('amount')
        
        if not user_id_str or not amount_str:
            from aiohttp import web
            return web.Response(text="مشخصات نامعتبر", status=400)
            
        user_id = int(user_id_str)
        amount = int(amount_str)
        
        from database import db
        from utils.payment import zarinpal_request
        
        merchant = await db.get_setting('zarinpal_merchant', 'zarinpal')
        sandbox = (await db.get_setting('zarinpal_sandbox', '1')) == '1'
        
        import config
        bot_domain = await db.get_setting('bot_domain', 'http://127.0.0.1:8000')
        callback_url = f"{bot_domain}/payment/verify/zarinpal?user_id={user_id}&amount={amount}"
        
        authority = await zarinpal_request(merchant, amount, "شارژ کیف پول", callback_url, sandbox)
        
        if authority:
            await db.create_online_payment(user_id, amount, authority, 'zarinpal')
            pay_url = f"https://sandbox.zarinpal.com/pg/StartPay/{authority}" if sandbox else f"https://zarinpal.com/pg/StartPay/{authority}"
            from aiohttp import web
            raise web.HTTPFound(pay_url)
        else:
            from aiohttp import web
            return web.Response(text="خطا در اتصال به درگاه پرداخت", content_type="text/html; charset=utf-8")
            
    except Exception as e:
        if type(e).__name__ == "HTTPFound":
            raise
        logger.error(f"Zarinpal deposit request error: {e}")
        from aiohttp import web
        return web.Response(text="خطای سرور", status=500)


import json
import hashlib
from aiohttp import WSMsgType

# Store active websockets {project_id: [ws1, ws2, ...]}
active_websockets = {}

async def webapp_chat_handler(request):
    try:
        project_id = request.query.get('project_id')
        user_id = request.query.get('user_id')
        token = request.query.get('token')
        
        if not project_id or not user_id or not token:
            return web.Response(text="پارامترهای نامعتبر", status=400)
            
        expected_token = hashlib.sha256(f"Xlancer_Secret_{project_id}_{user_id}".encode()).hexdigest()
        if token != expected_token:
            return web.Response(text="عدم دسترسی", status=403)
            
        with open('assets/chat.html', 'r', encoding='utf-8') as f:
            html = f.read()
            
        html = html.replace('{PROJECT_ID}', project_id)
        html = html.replace('{USER_ID}', user_id)
        html = html.replace('{TOKEN}', token)
        
        return web.Response(text=html, content_type='text/html; charset=utf-8')
    except Exception as e:
        logger.error(f"WebApp Chat HTML error: {e}")
        return web.Response(text="خطای سرور", status=500)

async def webapp_ws_chat_handler(request):
    project_id = request.query.get('project_id')
    user_id = request.query.get('user_id')
    token = request.query.get('token')
    
    if not project_id or not user_id or not token:
        return web.Response(status=400)
        
    expected_token = hashlib.sha256(f"Xlancer_Secret_{project_id}_{user_id}".encode()).hexdigest()
    if token != expected_token:
        return web.Response(status=403)
        
    project_id = int(project_id)
    user_id = int(user_id)
    bot = request.app['bot']
    
    ws = web.WebSocketResponse()
    await ws.prepare(request)
    
    if project_id not in active_websockets:
        active_websockets[project_id] = []
    active_websockets[project_id].append(ws)
    
    try:
        # Send history
        from database import db
        messages = await db.get_project_messages(project_id)
        await ws.send_json({
            'type': 'history',
            'messages': messages
        })
        
        # Project info for notifications
        project = await db.get_project(project_id)
        
        async for msg in ws:
            if msg.type == WSMsgType.TEXT:
                data = json.loads(msg.data)
                if data.get('type') == 'send_message':
                    content = data.get('content', '')
                    reply_to_id = data.get('reply_to_id')
                    if content:
                        receiver_id = project['client_id'] if user_id == project['chosen_freelancer_id'] else project['chosen_freelancer_id']
                        if not receiver_id:
                            receiver_id = 0
                            
                        msg_id = await db.save_chat_message(
                            project_id=project_id,
                            sender_id=user_id,
                            receiver_id=receiver_id,
                            message_type='text',
                            content=content,
                            reply_to_id=reply_to_id
                        )
                        
                        # Broadcast to all connected websockets for this project
                        new_msg = {
                            'message_id': msg_id,
                            'project_id': project_id,
                            'sender_id': user_id,
                            'receiver_id': receiver_id,
                            'message_type': 'text',
                            'content': content,
                            'reply_to_id': reply_to_id,
                            'created_at': __import__('datetime').datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                        }
                        
                        for client_ws in active_websockets.get(project_id, []):
                            if not client_ws.closed:
                                await client_ws.send_json({
                                    'type': 'message',
                                    'message': new_msg
                                })
                                
                        # Send Telegram notification if receiver is not connected
                        # (A simple heuristic: if there's only 1 WS connected, the other guy is offline)
                        if len(active_websockets.get(project_id, [])) < 2 and receiver_id > 0:
                            try:
                                from aiogram.utils.keyboard import InlineKeyboardBuilder
                                from aiogram.types import WebAppInfo
                                expected_recv_token = hashlib.sha256(f"Xlancer_Secret_{project_id}_{receiver_id}".encode()).hexdigest()
                                bot_domain = await db.get_setting('bot_domain', 'http://127.0.0.1:8000')
                                kb = InlineKeyboardBuilder()
                                kb.button(text="ورود به چت‌روم پروژه 💬", web_app=WebAppInfo(url=f"{bot_domain}/chat?project_id={project_id}&user_id={receiver_id}&token={expected_recv_token}"))
                                await bot.send_message(
                                    receiver_id,
                                    f"📩 <b>پیام جدید در پروژه #{project_id}</b>\n\nجهت پاسخگویی وارد چت‌روم شوید.",
                                    reply_markup=kb.as_markup(),
                                    parse_mode="HTML"
                                )
                            except:
                                pass
                                
            elif msg.type == WSMsgType.ERROR:
                logger.error(f'ws connection closed with exception {ws.exception()}')
    finally:
        if ws in active_websockets.get(project_id, []):
            active_websockets[project_id].remove(ws)
            
    return ws

async def report_message_handler(request):
    try:
        data = await request.json()
        message_id = data.get('message_id')
        project_id = data.get('project_id')
        reporter_id = data.get('reporter_id')
        token = data.get('token')
        
        expected_token = hashlib.sha256(f"Xlancer_Secret_{project_id}_{reporter_id}".encode()).hexdigest()
        if token != expected_token:
            from aiohttp import web
            return web.json_response({'success': False, 'error': 'Forbidden'})
            
        bot = request.app['bot']
        import config
        from utils.broadcaster import safe_broadcast
        import asyncio
        
        report_text = (
            f"⚠️ <b>گزارش تخلف در چت</b>\n\n"
            f"پروژه: <b>#{project_id}</b>\n"
            f"آیدی پیام: <b>{message_id}</b>\n"
            f"گزارش‌دهنده: <b>{reporter_id}</b>\n\n"
            f"لطفاً با ورود به چت داوری این پروژه، موضوع را بررسی کنید."
        )
        
        async def do_broadcast():
            recipients = await db.get_admin_recipients('disputes')
            await safe_broadcast(
                bot=bot,
                user_ids=recipients,
                text=report_text,
                parse_mode="HTML"
            )
        asyncio.create_task(do_broadcast())
        from aiohttp import web
        return web.json_response({'success': True})
    except Exception as e:
        logger.error(f"Report handler error: {e}")
        from aiohttp import web
        return web.json_response({'success': False, 'error': 'Server error'})


async def start_web_server(bot: Bot):
    app = web.Application()
    app['bot'] = bot
    app.router.add_get('/payment/verify/zarinpal', zarinpal_verify_handler)
    app.router.add_get('/dispute_chat', dispute_chat_handler)
    app.router.add_get('/chat', webapp_chat_handler)
    app.router.add_get('/ws/chat', webapp_ws_chat_handler)
    app.router.add_post('/api/report_message', report_message_handler)

    app.router.add_get('/pay/deposit', zarinpal_pay_deposit_handler)
    app.router.add_get('/payment/verify/zibal', zibal_verify_handler)
    
    # Register static directory route to serve welcome_banner.png and other assets
    app.router.add_static('/assets', 'assets')
    
    runner = web.AppRunner(app)
    await runner.setup()
    site = web.TCPSite(runner, '0.0.0.0', 8000)
    try:
        await site.start()
        logger.info("✨ Light Payment Verification Server is running on port 8000...")
    except Exception as e:
        logger.error(f"Failed to start payment verification web server: {e}")
