import asyncio
import json
import os
from aiogram import Bot, Dispatcher, types, F
from aiogram.filters import CommandStart, Command
from aiogram.types import (
    InlineKeyboardMarkup, InlineKeyboardButton,
    ReplyKeyboardMarkup, KeyboardButton,
    ReplyKeyboardRemove
)
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup

BOT_TOKEN = "8162491685:AAHbJtaG6cfE1rxcsFXgerNvmXiRqlclRt4"
SERVER_URL = "https://web.elnadaonline.com"
ADMIN_ID = 6201056867

USERS_FILE = "users.json"

# ─── حالات الانتظار (FSM) ──────────────────────────────────────────
class ContactAdmin(StatesGroup):
    waiting_for_message = State()

class AdminReply(StatesGroup):
    waiting_for_reply = State()
    target_user_id = State()

# إضافة حالة الإشعار الجماعي
class BroadcastMessage(StatesGroup):
    waiting_for_broadcast = State()
# ───────────────────────────────────────────────────────────────────

def load_users():
    if os.path.exists(USERS_FILE):
        with open(USERS_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    return {}

def save_users(users):
    with open(USERS_FILE, "w", encoding="utf-8") as f:
        json.dump(users, f, ensure_ascii=False, indent=2)

def is_approved(chat_id: int) -> bool:
    users = load_users()
    return str(chat_id) in users and users[str(chat_id)]["status"] == "approved"

bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()

main_keyboard = ReplyKeyboardMarkup(
    keyboard=[
        [KeyboardButton(text="🎬 ارسال فيديو"), KeyboardButton(text="ℹ️ من نحن")],
        [KeyboardButton(text="📞 تواصل معنا"), KeyboardButton(text="❓ المساعدة")]
    ],
    resize_keyboard=True
)

phone_keyboard = ReplyKeyboardMarkup(
    keyboard=[
        [KeyboardButton(text="📱 مشاركة رقمي", request_contact=True)]
    ],
    resize_keyboard=True,
    one_time_keyboard=True
)

NOT_APPROVED_MSG = "⛔ ليس لديك صلاحية. أرسل /start لطلب الوصول."

# ─── /start ──────────────────────────────────────────────────────────
@dp.message(CommandStart())
async def start(message: types.Message):
    chat_id = message.chat.id
    users = load_users()
    key = str(chat_id)

    if is_approved(chat_id):
        await message.answer(
            f"👋 أهلاً {message.from_user.first_name}!\n\n"
            "🎬 أنا بوت مشاركة الفيديوهات\n\n"
            "📌 كيف أعمل?\n"
            "1️⃣ أرسل لي رابط أي فيديو\n"
            "2️⃣ سأعطيك رابطاً خاصاً\n"
            "3️⃣ أرسل الرابط لمن تريد\n\n"
            "اختر من القائمة أدناه 👇",
            reply_markup=main_keyboard
        )
        return

    if key in users and users[key]["status"] == "pending":
        await message.answer(
            "⏳ طلبك قيد المراجعة، انتظر موافقة الأدمن.",
            reply_markup=ReplyKeyboardRemove()
        )
        return

    if key in users and users[key]["status"] == "rejected":
        users[key]["status"] = "waiting_phone"
        save_users(users)
        await message.answer(
            f"👋 أهلاً {message.from_user.first_name}!\n\n"
            "📱 لإتمام التسجيل، اضغط الزر أدناه لمشاركة رقم هاتفك:",
            reply_markup=phone_keyboard
        )
        return

    if key in users and users[key]["status"] == "waiting_phone":
        await message.answer(
            "📱 اضغط الزر أدناه لمشاركة رقم هاتفك لإتمام التسجيل:",
            reply_markup=phone_keyboard
        )
        return

    users[key] = {
        "name": message.from_user.full_name,
        "username": message.from_user.username or "",
        "phone": "",
        "status": "waiting_phone"
    }
    save_users(users)

    await message.answer(
        f"👋 أهلاً {message.from_user.first_name}!\n\n"
        "📱 لإتمام التسجيل، اضغط الزر أدناه لمشاركة رقم هاتفك:",
            reply_markup=phone_keyboard
    )

# ─── استقبال رقم الهاتف ──────────────────────────────────────────────
@dp.message(F.contact)
async def handle_contact(message: types.Message):
    chat_id = message.chat.id
    users = load_users()
    key = str(chat_id)

    if message.contact.user_id != chat_id:
        await message.answer("❌ يرجى مشاركة رقمك الشخصي فقط.")
        return

    phone = message.contact.phone_number

    if key not in users:
        users[key] = {
            "name": message.from_user.full_name,
            "username": message.from_user.username or "",
            "status": "waiting_phone"
        }

    users[key]["phone"] = phone
    users[key]["status"] = "pending"
    save_users(users)

    approve_kb = InlineKeyboardMarkup(inline_keyboard=[
        [
            InlineKeyboardButton(text="✅ موافقة", callback_data=f"approve_{chat_id}"),
            InlineKeyboardButton(text="❌ رفض", callback_data=f"reject_{chat_id}")
        ]
    ])
    await bot.send_message(
        ADMIN_ID,
        f"🔔 *طلب وصول جديد*\n\n"
        f"👤 الاسم: {message.from_user.full_name}\n"
        f"🆔 ID: `{chat_id}`\n"
        f"📛 يوزر: @{message.from_user.username or 'لا يوجد'}\n"
        f"📱 الرقم: `{phone}`",
        parse_mode="Markdown",
        reply_markup=approve_kb
    )

    await message.answer(
        "✅ تم استلام رقمك!\n\n📨 طلبك أُرسل للأدمن، انتظر الموافقة.",
        reply_markup=ReplyKeyboardRemove()
    )

# ─── /users ──────────────────────────────────────────────────────────
@dp.message(Command("users"))
async def list_users(message: types.Message):
    if message.chat.id != ADMIN_ID:
        return
    users = load_users()
    if not users:
        await message.answer("لا يوجد مستخدمون.")
        return

    text = "👥 *قائمة المستخدمين:*\n\n"
    buttons = []
    for uid, info in users.items():
        status_icon = "✅" if info["status"] == "approved" else ("⏳" if info["status"] == "pending" else "❌")
        phone = info.get("phone", "غير محدد")
        text += f"{status_icon} {info['name']} | 📱 {phone} | `{uid}`\n"
        if info["status"] == "approved":
            buttons.append([InlineKeyboardButton(text=f"🗑 حذف {info['name']}", callback_data=f"remove_{uid}")])

    kb = InlineKeyboardMarkup(inline_keyboard=buttons) if buttons else None
    await message.answer(text, parse_mode="Markdown", reply_markup=kb)

# ─── /broadcast (الإشعار الجماعي) ───────────────────────────────────
@dp.message(Command("broadcast"))
async def start_broadcast(message: types.Message, state: FSMContext):
    # التأكد من أن المرسل هو الأدمن
    if message.chat.id != ADMIN_ID:
        return
    
    await message.answer(
        "📢 *نظام الإشعارات الجماعية*\n\n"
        "أرسل الآن الرسالة التي تريد تعميمها على جميع المستخدمين المعتمدين.\n"
        "*(لإلغاء العملية أرسل كلمة `الغاء`)*",
        parse_mode="Markdown"
    )
    await state.set_state(BroadcastMessage.waiting_for_broadcast)

@dp.message(BroadcastMessage.waiting_for_broadcast)
async def process_broadcast(message: types.Message, state: FSMContext):
    if message.chat.id != ADMIN_ID:
        return
        
    if message.text == 'الغاء':
        await state.clear()
        await message.answer("✅ تم إلغاء الإرسال الجماعي.")
        return
        
    users = load_users()
    success_count = 0
    fail_count = 0
    
    await message.answer("⏳ جاري إرسال الإشعار للجميع، الرجاء الانتظار...")
    
    for user_id, info in users.items():
        # إرسال الرسالة فقط للمستخدمين المعتمدين
        if info.get("status") == "approved":
            try:
                await bot.send_message(
                    chat_id=int(user_id), 
                    text=f"📢 *إشعار إداري:*\n\n{message.text}", 
                    parse_mode="Markdown"
                )
                success_count += 1
                await asyncio.sleep(0.05) 
            except Exception as e:
                fail_count += 1
                
    await state.clear()
    await message.answer(
        f"✅ *اكتمل الإرسال الجماعي!*\n\n"
        f"🟢 نجاح: {success_count} مستخدم\n"
        f"🔴 فشل: {fail_count} مستخدم (ربما قاموا بحظر البوت)",
        parse_mode="Markdown"
    )
# ───────────────────────────────────────────────────────────────────

# ─── Callbacks للإدارة ──────────────────────────────────────────────
@dp.callback_query(F.data.startswith("approve_"))
async def approve_user(call: types.CallbackQuery):
    if call.from_user.id != ADMIN_ID:
        return
    uid = call.data.split("_")[1]
    users = load_users()
    if uid in users:
        users[uid]["status"] = "approved"
        save_users(users)
        await call.message.edit_text(
            f"✅ تمت الموافقة على {users[uid]['name']}\n📱 {users[uid].get('phone','')}"
        )
        await bot.send_message(
            int(uid),
            "✅ *تمت الموافقة على طلبك!*\n\nاختر من القائمة 👇",
            parse_mode="Markdown",
            reply_markup=main_keyboard
        )
    await call.answer()

@dp.callback_query(F.data.startswith("reject_"))
async def reject_user(call: types.CallbackQuery):
    if call.from_user.id != ADMIN_ID:
        return
    uid = call.data.split("_")[1]
    users = load_users()
    if uid in users:
        users[uid]["status"] = "rejected"
        save_users(users)
        await call.message.edit_text(f"❌ تم رفض {users[uid]['name']} | 📱 {users[uid].get('phone','')}")
        await bot.send_message(int(uid), "❌ تم رفض طلبك.\n\nيمكنك إرسال /start للمحاولة مرة أخرى.")
    await call.answer()

@dp.callback_query(F.data.startswith("remove_"))
async def remove_user(call: types.CallbackQuery):
    if call.from_user.id != ADMIN_ID:
        return
    uid = call.data.split("_")[1]
    users = load_users()
    if uid in users:
        name = users[uid]["name"]
        del users[uid]
        save_users(users)
        await call.message.edit_text(f"🗑 تم حذف {name}")
        await bot.send_message(int(uid), "⛔ تم إلغاء وصولك للبوت.\n\nيمكنك إرسال /start لطلب الوصول مجدداً.")
    await call.answer()

# ─── الأزرار الرئيسية ─────────────────────────────────────────────────
@dp.message(F.text == "🎬 ارسال فيديو")
async def send_video_instructions(message: types.Message):
    if not is_approved(message.chat.id):
        await message.answer(NOT_APPROVED_MSG)
        return
    await message.answer(
        "🎬 *إرسال فيديو*\n\nببساطة أرسل لي رابط الفيديو مباشرة\n\n"
        "مثال:\n`https://www.youtube.com/watch?v=xxxxx`\n\n"
        "✅ يدعم: يوتيوب، انستجرام، تيك توك وغيرها",
        parse_mode="Markdown",
        reply_markup=main_keyboard
    )

@dp.message(F.text == "ℹ️ من نحن")
async def about(message: types.Message):
    if not is_approved(message.chat.id):
        await message.answer(NOT_APPROVED_MSG)
        return
    keyboard = InlineKeyboardMarkup(inline_keyboard=[
        [InlineKeyboardButton(text="🌐 زيارة موقعنا", url="https://almutahida-ms.com")]
    ])
    await message.answer(
        "ℹ️ *من نحن*\n\nنحن فريق متخصص في تطوير بوتات تيليجرام\n"
        "وتقديم حلول تقنية مبتكرة\n\n"
        "🎯 هدفنا تقديم أفضل تجربة مستخدم\n"
        "💡 نعمل على تطوير مستمر لخدماتنا",
        parse_mode="Markdown",
        reply_markup=keyboard
    )

# ─── نظام التواصل الاحترافي (للمستخدم والإدارة) ─────────────────────────

@dp.message(F.text == "📞 تواصل معنا")
async def contact(message: types.Message, state: FSMContext):
    if not is_approved(message.chat.id):
        await message.answer(NOT_APPROVED_MSG)
        return
    
    await message.answer(
        "✍️ اكتب رسالتك الآن وسأقوم بإرسالها للإدارة فوراً\n*(لإلغاء العملية أرسل كلمة `الغاء`)*:",
        parse_mode="Markdown",
        reply_markup=ReplyKeyboardRemove()
    )
    await state.set_state(ContactAdmin.waiting_for_message)

@dp.message(ContactAdmin.waiting_for_message)
async def forward_to_admin(message: types.Message, state: FSMContext):
    if not message.text:
        await message.answer("⚠️ الرجاء إرسال رسالة نصية فقط، أو أرسل `الغاء`.", parse_mode="Markdown")
        return
        
    if message.text == 'الغاء':
        await state.clear()
        await message.answer("✅ تم إلغاء الإرسال.", reply_markup=main_keyboard)
        return
    
    admin_text = f"📩 *رسالة جديدة من:* {message.from_user.full_name}\n\n*الرسالة:*\n{message.text}"
    
    reply_kb = InlineKeyboardMarkup(inline_keyboard=[
        [InlineKeyboardButton(text="✍️ الرد على المستخدم", callback_data=f"replyuser_{message.chat.id}")]
    ])
    
    try:
        await bot.send_message(ADMIN_ID, admin_text, reply_markup=reply_kb, parse_mode="Markdown")
        await message.answer("✅ تم إرسال رسالتك للإدارة، سيتم الرد عليك في أقرب وقت.", reply_markup=main_keyboard)
    except Exception as e:
        await message.answer("❌ حدث خطأ أثناء الإرسال.", reply_markup=main_keyboard)
    
    await state.clear()

@dp.callback_query(F.data.startswith("replyuser_"))
async def start_admin_reply(call: types.CallbackQuery, state: FSMContext):
    if call.from_user.id != ADMIN_ID:
        return
    
    user_id = call.data.split("_")[1]
    
    await state.set_state(AdminReply.waiting_for_reply)
    await state.update_data(target_user_id=user_id)
    
    await call.message.reply("📝 *اكتب ردك الآن ليتم إرساله للمستخدم:*\n*(لإلغاء الرد أرسل `الغاء`)*", parse_mode="Markdown")
    await call.answer()

@dp.message(AdminReply.waiting_for_reply, F.chat.id == ADMIN_ID)
async def send_admin_reply(message: types.Message, state: FSMContext):
    if message.text == 'الغاء':
        await state.clear()
        await message.answer("✅ تم إلغاء الرد.")
        return
        
    data = await state.get_data()
    user_id = data.get("target_user_id")
    
    try:
        await bot.send_message(user_id, f"👨‍💻 *رد من الإدارة:*\n\n{message.text}", parse_mode="Markdown")
        await message.answer("✅ تم إرسال الرد للمستخدم بنجاح.")
    except Exception as e:
        await message.answer(f"❌ حدث خطأ أثناء الإرسال (ربما قام المستخدم بحظر البوت).\nالسبب: {e}")
        
    await state.clear()

# ───────────────────────────────────────────────────────────────────

@dp.message(F.text == "❓ المساعدة")
async def help_msg(message: types.Message):
    if not is_approved(message.chat.id):
        await message.answer(NOT_APPROVED_MSG)
        return
    await message.answer(
        "❓ *المساعدة*\n\n"
        "🔹 *كيف أرسل فيديو?*\nفقط أرسل رابط الفيديو مباشرة في المحادثة\n\n"
        "🔹 *ما هي الروابط المدعومة?*\nيوتيوب، انستجرام، تيك توك، فيسبوك وغيرها\n\n"
        "🔹 *ماذا يحدث بعد إرسال الرابط?*\nستحصل على رابط خاص ترسله لمن تريد\n\n"
        "🔹 *هل هناك مشكلة?*\nتواصل معنا عبر قسم 📞 تواصل معنا",
        parse_mode="Markdown",
        reply_markup=main_keyboard
    )

@dp.message(F.text.startswith("http"))
async def handle_link(message: types.Message):
    if not is_approved(message.chat.id):
        await message.answer(NOT_APPROVED_MSG)
        return
    original_url = message.text
    sender_chat_id = message.chat.id
    watch_link = f"{SERVER_URL}/watch?ref={sender_chat_id}&url={original_url}"
    keyboard = InlineKeyboardMarkup(inline_keyboard=[
        [InlineKeyboardButton(text="📤 نسخ الرابط", url=watch_link)]
    ])
    await message.answer(
        "✅ *تم إنشاء الرابط بنجاح!*\n\n"
        f"🔗 الرابط الخاص:\n`{watch_link}`\n\n"
        "📱 أرسل هذا الرابط للشخص المراد",
        parse_mode="Markdown",
        reply_markup=keyboard
    )

@dp.message()
async def unknown(message: types.Message):
    if not is_approved(message.chat.id):
        await message.answer(NOT_APPROVED_MSG)
        return
    await message.answer(
        "❗ لم أفهم رسالتك\n\nأرسل رابط فيديو مباشرة أو اختر من القائمة 👇",
        reply_markup=main_keyboard
    )

async def main():
    await dp.start_polling(bot)

if __name__ == "__main__":
    asyncio.run(main())
