File size: 29,190 Bytes
b22819e
4340a48
b22819e
 
 
 
 
 
 
28520ff
 
 
b22819e
 
 
28520ff
 
 
b22819e
 
 
 
 
 
4340a48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b22819e
4340a48
 
 
 
 
b22819e
 
28520ff
 
 
b22819e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4340a48
b22819e
 
4340a48
b22819e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4340a48
 
 
 
b22819e
 
 
 
 
 
 
 
 
 
4340a48
 
 
b22819e
 
 
 
 
 
4340a48
 
 
 
 
 
 
 
 
 
 
 
 
b22819e
4340a48
 
b22819e
 
 
 
 
 
 
 
4340a48
 
 
 
b22819e
 
 
 
 
 
 
 
4340a48
 
 
 
b22819e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4340a48
b22819e
 
 
 
 
 
 
 
4340a48
b22819e
 
 
 
 
4340a48
 
b22819e
 
 
4340a48
 
b22819e
 
 
 
 
 
4340a48
 
b22819e
 
 
 
4340a48
 
 
 
 
 
 
 
 
 
b22819e
 
 
 
 
 
 
4340a48
 
28520ff
 
4340a48
b22819e
 
4340a48
 
 
 
28520ff
 
4340a48
 
 
 
 
b22819e
28520ff
 
4340a48
 
28520ff
 
4340a48
 
28520ff
 
4340a48
b22819e
 
 
 
 
 
 
 
 
 
 
 
 
 
4340a48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b22819e
 
 
 
 
 
 
 
 
4340a48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b22819e
4340a48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b22819e
 
 
 
 
 
 
 
 
4340a48
 
 
 
 
 
 
b22819e
 
 
 
 
4340a48
 
 
 
 
 
 
 
b22819e
 
 
 
 
 
4340a48
 
 
b22819e
4340a48
 
 
 
 
 
 
b22819e
 
 
 
 
 
 
 
 
 
 
 
28520ff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
import discord
from discord.ext import commands, tasks
from discord import app_commands
from discord.ui import Button, View, Select
import asyncio
import random
import os
from datetime import datetime

# =======================================================
#               الإعدادات الأساسية (الثوابت)
# =======================================================
TARGET_GUILD_ID = 1463693244897693779  # أيدي السيرفر المسموح
OWNER_ROLE_ID = 1492516779598155877   # أيدي رتبة المالك للتحكم

# =======================================================
#               الأذكار والتذكيرات (القائمة الكاملة)
# =======================================================
REMINDERS = [
    "🌸 سبحان الله وبحمده، سبحان الله العظيم",
    "✨ اللهم صل وسلم على نبينا محمد",
    "📿 أستغفر الله العظيم وأتوب إليه",
    "🕊️ لا حول ولا قوة إلا بالله",
    "🌿 سبحان الله، والحمد لله، ولا إله إلا الله، والله أكبر",
    "🌸 سبحان الله", "✨ الحمد لله", "📿 الله أكبر", "🕊️ لا إله إلا الله",
    "🌿 اللهم اغفر لي", "🌸 اللهم ارحمني", "✨ اللهم تب علي", "📿 اللهم ارزقني",
    "🕊️ حسبي الله ونعم الوكيل", "🌿 توكلت على الله", "🌸 رب اغفر لي ولوالدي",
    "✨ اللهم اجعلني من الصالحين", "📿 اللهم اهدني", "🕊️ اللهم ثبتني",
    "🌿 اللهم ارزقني الجنة", "🌸 اللهم أجرني من النار", "✨ يا رب", "📿 يا الله",
    "🕊️ يا حي يا قيوم برحمتك أستغيث", "🌿 اللهم إني أسألك العافية",
    "🌸 اللهم إني أسألك الهدى والتقى", "✨ اللهم إني أعوذ بك من الهم والحزن",
    "📿 اللهم إني أعوذ بك من العجز والكسل", "🕊️ اللهم إني أعوذ بك من الجبن والبخل",
    "🌿 اللهم إني أعوذ بك من غلبة الدين وقهر الرجال", "🌸 اللهم اجعل القرآن ربيع قلبي",
    "✨ اللهم نور قلبي", "📿 اللهم طهر قلبي", "🕊️ اللهم أصلح حالي",
    "🌿 اللهم اجعلني من الذاكرين", "🌸 اللهم اجعلني من الشاكرين",
    "✨ اللهم اجعلني من الصابرين", "📿 اللهم اجعلني من التوابين",
    "🕊️ اللهم اجعلني من المتقين", "🌿 اللهم اجعلني من المحسنين",
    "🌸 اللهم ارزقني الإخلاص", "✨ اللهم ارزقني الصدق", "📿 اللهم ارزقني حسن الخاتمة",
    "🕊️ اللهم اجعل قبري روضة من رياض الجنة", "🌿 اللهم اجعلني من أهل الجنة",
    "🌸 اللهم ارزقني الفردوس الأعلى", "✨ اللهم لا تحرمني من رحمتك",
    "📿 اللهم لا تكلني إلى نفسي", "🕊️ اللهم ارحم موتانا", "🌿 اللهم اشف مرضانا",
    "🌸 اللهم فرج همومنا", "✨ اللهم اقض ديوننا", "📿 اللهم وسع رزقنا",
    "🕊️ اللهم بارك لنا", "🌿 اللهم احفظنا", "🌸 اللهم انصرنا",
    "✨ اللهم اجعلنا من عبادك الصالحين", "📿 اللهم ارزقنا رضاك",
    "🕊️ اللهم اجعلنا من أهل الذكر", "🌿 اللهم ارزقنا حبك", "🌸 اللهم ارزقنا حب نبيك",
    "✨ اللهم اجعلنا من المتوكلين", "📿 اللهم ارزقنا الصبر", "🕊️ اللهم ارزقنا اليقين",
    "🌿 اللهم اجعلنا من الذاكرين الله كثيرا", "🌸 اللهم اجعلنا من القانتين",
    "✨ اللهم ارزقنا حسن الظن بك", "📿 اللهم اجعلنا من المقبولين",
    "🕊️ اللهم ارزقنا لذة النظر إلى وجهك", "🌿 اللهم اجعلنا من الفائزين",
    "🌸 اللهم اجعلنا من أهل الفردوس", "✨ اللهم اجعلنا من عتقائك من النار",
    "📿 اللهم اجعلنا من المستغفرين", "🕊️ اللهم اجعلنا من الراجعين إليك",
    "🌿 اللهم اجعلنا من المنيبين", "🌸 اللهم ارزقنا التوبة النصوح",
    "✨ اللهم تقبل منا", "📿 اللهم اغفر لنا", "🕊️ اللهم ارحمنا", "🌿 اللهم تب علينا",
    "🌸 اللهم اهدنا", "✨ اللهم احفظنا من كل سوء", "📿 اللهم اجعلنا من الصالحين",
    "🕊️ اللهم ارزقنا الجنة بغير حساب", "🌿 اللهم اجعلنا من أهل القرآن",
    "🌸 اللهم اجعل القرآن شفيعاً لنا", "✨ اللهم اجعل القرآن حجة لنا",
    "📿 اللهم اجعلنا من الذين يستمعون القول فيتبعون أحسنه",
    "🕊️ اللهم اجعلنا من أولي الألباب", "🌿 اللهم ارزقنا العلم النافع",
    "🌸 اللهم ارزقنا العمل الصالح", "✨ اللهم ارزقنا الإيمان الكامل",
    "📿 اللهم اجعلنا من أهل التقوى", "🕊️ اللهم اجعلنا من الصادقين",
    "🌿 اللهم اجعلنا من المخلصين", "🌸 اللهم اجعلنا من عبادك المقربين",
    "✨ اللهم اجعلنا من الذاكرين الشاكرين", "📿 اللهم اجعلنا من الصابرين المحتسبين"
]

# =======================================================
#               قائمة 30 قارئ (بدون اختصار)
# =======================================================
RECITERS = [
    {"name": "إذاعة تلاوات منوعة", "desc": "بث مباشر لتلاوات مختارة", "url": "https://qurango.net/radio/tarateel"},
    {"name": "عبدالباسط عبدالصمد", "desc": "تلاوة مجودة بصوت خاشع", "url": "https://qurango.net/radio/abdulbasit_abdulsamad_mjawwad"},
    {"name": "مشاري العفاسي", "desc": "تلاوة هادئة ومريحة", "url": "https://qurango.net/radio/mishary_alafasi"},
    {"name": "ياسر الدوسري", "desc": "تلاوات مميزة من الحرم", "url": "https://qurango.net/radio/yasser_aldosari"},
    {"name": "ماهر المعيقلي", "desc": "تلاوة عذبة وشهيرة", "url": "https://qurango.net/radio/maher_al_muaiqly"},
    {"name": "أحمد بن علي العجمي", "desc": "تلاوة خاشعة", "url": "https://qurango.net/radio/ahmad_alajmy"},
    {"name": "سعد الغامدي", "desc": "تلاوة مريحة للقلب", "url": "https://qurango.net/radio/saad_alghamidi"},
    {"name": "سعود الشريم", "desc": "من تلاوات الحرم المكي", "url": "https://qurango.net/radio/saud_alshuraim"},
    {"name": "عبدالرحمن السديس", "desc": "تلاوة الحرم المكي الشريف", "url": "https://qurango.net/radio/abdulrahman_alsudaes"},
    {"name": "محمود خليل الحصري", "desc": "تلاوة مرتلة دقيقة", "url": "https://qurango.net/radio/mahmoud_khalil_alhussary"},
    {"name": "علي عبدالله جابر", "desc": "تلاوة مميزة", "url": "https://qurango.net/radio/ali_jaber"},
    {"name": "محمد أيوب", "desc": "تلاوة حجازية", "url": "https://qurango.net/radio/mohammed_ayyub"},
    {"name": "محمد صديق المنشاوي", "desc": "تلاوة خاشعة جداً", "url": "https://qurango.net/radio/mohammed_siddiq_alminshawi"},
    {"name": "أبوبكر الشاطري", "desc": "تلاوة هادئة", "url": "https://qurango.net/radio/abubakr_alshatri"},
    {"name": "عبدالله بصفر", "desc": "تلاوة عذبة", "url": "https://qurango.net/radio/abdullah_basfer"},
    {"name": "عبدالمحسن القاسم", "desc": "إمام المسجد النبوي", "url": "https://qurango.net/radio/abdulmohsin_alqasim"},
    {"name": "عبدالودود حنيف", "desc": "تلاوة رائعة", "url": "https://qurango.net/radio/abdulwadood_haneef"},
    {"name": "علي عبدالرحمن الحذيفي", "desc": "من تلاوات المسجد النبوي", "url": "https://qurango.net/radio/ali_alhuthaifi"},
    {"name": "فارس عباد", "desc": "تلاوة مؤثرة", "url": "https://qurango.net/radio/fares_abbad"},
    {"name": "محمد جبريل", "desc": "تلاوة مشهورة", "url": "https://qurango.net/radio/mohammed_jibreel"},
    {"name": "محمد الطبلاوي", "desc": "من كبار القراء", "url": "https://qurango.net/radio/mohammad_altablaway"},
    {"name": "محمود علي البنا", "desc": "تلاوة كلاسيكية", "url": "https://qurango.net/radio/mahmoud_ali__albanna"},
    {"name": "مصطفى إسماعيل", "desc": "تلاوة مجودة", "url": "https://qurango.net/radio/mustafa_ismail"},
    {"name": "هاني الرفاعي", "desc": "تلاوة بكائية", "url": "https://qurango.net/radio/hani_arrifai"},
    {"name": "يحيى حوا", "desc": "تلاوة هادئة", "url": "https://qurango.net/radio/yahya_hawwa"},
    {"name": "خالد القحطاني", "desc": "تلاوة خاشعة", "url": "https://qurango.net/radio/khalid_alqahtani"},
    {"name": "صلاح البدير", "desc": "إمام المسجد النبوي", "url": "https://qurango.net/radio/salah_albudair"},
    {"name": "صلاح بو خاطر", "desc": "تلاوة ندية", "url": "https://qurango.net/radio/salah_bukhatir"},
    {"name": "عبدالرشيد صوفي", "desc": "تلاوة مميزة بروايات", "url": "https://qurango.net/radio/abdulrasheed_soufi"},
    {"name": "عبدالله عواد الجهني", "desc": "إمام الحرم المكي", "url": "https://qurango.net/radio/abdullah_aljuhani"}
]

# --- متغيرات التحكم بالبث ---
current_reciter_index = 0
current_volume = 1.0  

# إعدادات أكثر أماناً لتجنب حظر IP من السيرفرات الصوتية
FFMPEG_OPTIONS = {
    'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
    'options': '-vn -sn -dn -bufsize 500k -max_muxing_queue_size 1024'
}

# =======================================================
#               تجهيز واجهة الأزرار (Control Panel)
# =======================================================
class ReciterSelect(Select):
    def __init__(self):
        options = []
        for i, r in enumerate(RECITERS[:25]):
            options.append(discord.SelectOption(label=r['name'], description=r['desc'][:50], value=str(i)))
        super().__init__(placeholder="اختر القارئ من القائمة السريعة...", min_values=1, max_values=1, options=options, custom_id="select_reciter")

    async def callback(self, interaction: discord.Interaction):
        role = interaction.guild.get_role(OWNER_ROLE_ID)
        if role not in interaction.user.roles:
            return await interaction.response.send_message("❌ لا تملك صلاحية.", ephemeral=True)
        
        global current_reciter_index
        current_reciter_index = int(self.values[0])
        vc = interaction.guild.voice_client
        if vc: await play_current_reciter(vc)
        
        try:
            await interaction.response.send_message(f"🎙️ تم التغيير إلى: {RECITERS[current_reciter_index]['name']}", ephemeral=True)
            await log_event(interaction.guild, f"🎙️ **{interaction.user.name}** قام بتغيير القارئ إلى: {RECITERS[current_reciter_index]['name']}")
        except: pass

class ControlPanelView(View):
    def __init__(self):
        super().__init__(timeout=None)
        self.add_item(ReciterSelect())

    async def check_owner(self, interaction: discord.Interaction):
        role = interaction.guild.get_role(OWNER_ROLE_ID)
        if role and role in interaction.user.roles:
            return True
        try:
            await interaction.response.send_message("❌ عذراً، لا تملك الصلاحية (رتبة المالك المطلوبة).", ephemeral=True)
        except: pass
        return False

    @discord.ui.button(label="⏸️ / ▶️ إيقاف وتشغيل", style=discord.ButtonStyle.primary, custom_id="btn_toggle")
    async def toggle_btn(self, interaction: discord.Interaction, button: Button):
        if not await self.check_owner(interaction): return
        vc = interaction.guild.voice_client
        try:
            if vc:
                if vc.is_paused():
                    vc.resume()
                    await interaction.response.send_message("▶️ تم استئناف البث.", ephemeral=True)
                    await log_event(interaction.guild, f"▶️ **{interaction.user.name}** قام باستئناف البث.")
                elif vc.is_playing():
                    vc.pause()
                    await interaction.response.send_message("⏸️ تم إيقاف البث مؤقتاً.", ephemeral=True)
                    await log_event(interaction.guild, f"⏸️ **{interaction.user.name}** قام بإيقاف البث يدوياً.")
                else:
                    await play_current_reciter(vc)
                    await interaction.response.send_message("▶️ تم تشغيل البث.", ephemeral=True)
            else:
                await interaction.response.send_message("❌ البوت غير متصل.", ephemeral=True)
        except: pass

    @discord.ui.button(label="⏭️ التالي", style=discord.ButtonStyle.secondary, custom_id="btn_next")
    async def next_btn(self, interaction: discord.Interaction, button: Button):
        if not await self.check_owner(interaction): return
        global current_reciter_index
        current_reciter_index = (current_reciter_index + 1) % len(RECITERS)
        vc = interaction.guild.voice_client
        if vc: await play_current_reciter(vc)
        try:
            await interaction.response.send_message(f"⏭️ تم الانتقال إلى: {RECITERS[current_reciter_index]['name']}", ephemeral=True)
            await log_event(interaction.guild, f"⏭️ **{interaction.user.name}** انتقل للقارئ: {RECITERS[current_reciter_index]['name']}")
        except: pass

    @discord.ui.button(label="⏮️ السابق", style=discord.ButtonStyle.secondary, custom_id="btn_prev")
    async def prev_btn(self, interaction: discord.Interaction, button: Button):
        if not await self.check_owner(interaction): return
        global current_reciter_index
        current_reciter_index = (current_reciter_index - 1) % len(RECITERS)
        vc = interaction.guild.voice_client
        if vc: await play_current_reciter(vc)
        try:
            await interaction.response.send_message(f"⏮️ تم الرجوع إلى: {RECITERS[current_reciter_index]['name']}", ephemeral=True)
            await log_event(interaction.guild, f"⏮️ **{interaction.user.name}** رجع للقارئ: {RECITERS[current_reciter_index]['name']}")
        except: pass

class QuranBot(commands.Bot):
    def __init__(self):
        intents = discord.Intents.default()
        intents.message_content = True
        intents.voice_states = True
        intents.guilds = True
        super().__init__(command_prefix="!", intents=intents)

    async def setup_hook(self):
        self.add_view(ControlPanelView())
        await self.tree.sync()
        print("✅ تم مزامنة الأوامر والأزرار بنجاح.")

bot = QuranBot()

# =======================================================
#               دوال مساعدة وحماية من الحظر
# =======================================================

async def log_event(guild: discord.Guild, message: str):
    log_channel = discord.utils.get(guild.text_channels, name="📜-سجلات-البوت")
    time_now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    if log_channel:
        try:
            await log_channel.send(f"`[{time_now}]` {message}")
        except: pass # منع توقف البوت إذا رفض ديسكورد إرسال الرسالة بسبب Rate Limit
    print(f"[{time_now}] {message}")

def is_owner_and_in_control():
    async def predicate(interaction: discord.Interaction):
        if not interaction.guild:
            try: await interaction.response.send_message("❌ هذا الأمر مخصص للاستخدام داخل السيرفر فقط.", ephemeral=True)
            except: pass
            return False
        
        if interaction.channel.name != "🛠️ غرفة التحكم (للمالك)":
            try: await interaction.response.send_message("❌ عذراً، لا يمكنك استخدام الأوامر إلا داخل 🛠️ غرفة التحكم.", ephemeral=True)
            except: pass
            return False

        role = interaction.guild.get_role(OWNER_ROLE_ID)
        if role and role in interaction.user.roles:
            return True
            
        try: await interaction.response.send_message("❌ عذراً، لا تملك الصلاحية (رتبة المالك المطلوبة).", ephemeral=True)
        except: pass
        return False
    return app_commands.check(predicate)

async def play_current_reciter(vc: discord.VoiceClient):
    try:
        if vc.is_playing() or vc.is_paused():
            vc.stop()
            await asyncio.sleep(1) # تأخير بسيط لحماية الـ API من ضغط الطلبات
            
        reciter = RECITERS[current_reciter_index]
        audio_source = discord.FFmpegPCMAudio(reciter["url"], **FFMPEG_OPTIONS)
        vc.play(discord.PCMVolumeTransformer(audio_source, volume=current_volume))
    except Exception as e:
        print(f"⚠️ خطأ أثناء التشغيل (تم تجاوزه): {e}")

# =======================================================
#               هندسة القنوات والأحداث
# =======================================================

@bot.event
async def on_ready():
    # حالة مستقرة وآمنة تظهر للمستخدمين
    await bot.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.listening, name="القرآن الكريم 24/7 🎧"))
    print(f"🤖 البوت {bot.user} متصل بشبكة ديسكورد بنجاح وهو الآن (Online).")
    
    # فحص هادئ للسيرفرات
    for guild in bot.guilds:
        if guild.id != TARGET_GUILD_ID:
            print(f"👢 جاري مغادرة سيرفر غريب بهدوء: {guild.name}")
            await asyncio.sleep(2) # تأخير لمنع الطرد المتعدد السريع
            try: await guild.leave()
            except: pass
        else:
            await check_and_create_channels(guild)
            await log_event(guild, "🚀 **تم إقلاع النظام والبوت متصل الآن.**")
            
    # تشغيل نبض القلب (فحص كل 5 دقائق)
    if not heartbeat_task.is_running():
        heartbeat_task.start()

@bot.event
async def on_guild_join(guild):
    print(f"📥 البوت دخل سيرفر جديد: {guild.name}")
    await asyncio.sleep(2) # حماية API ديسكورد
    
    if guild.id != TARGET_GUILD_ID:
        try: await guild.leave()
        except: pass
    else:
        await check_and_create_channels(guild)
        await log_event(guild, "🚀 **تم إضافة البوت للسيرفر الصحيح وبدء التشغيل!**")

async def check_and_create_channels(guild):
    category_name = "إذاعة القرآن الكريم"
    broadcast_vc_name = "🎧 استماع القرآن (بث عام)"
    control_vc_name = "🛠️ غرفة التحكم (للمالك)"
    log_channel_name = "📜-سجلات-البوت"

    category = discord.utils.get(guild.categories, name=category_name)
    broadcast_vc = discord.utils.get(guild.voice_channels, name=broadcast_vc_name)
    control_vc = discord.utils.get(guild.voice_channels, name=control_vc_name)
    log_tc = discord.utils.get(guild.text_channels, name=log_channel_name)

    owner_role = guild.get_role(OWNER_ROLE_ID)

    try:
        if not category:
            category = await guild.create_category(category_name)
            await asyncio.sleep(1)

        if not log_tc:
            overwrites_log = {
                guild.default_role: discord.PermissionOverwrite(view_channel=False),
                bot.user: discord.PermissionOverwrite(view_channel=True, send_messages=True, read_message_history=True)
            }
            if owner_role: overwrites_log[owner_role] = discord.PermissionOverwrite(view_channel=True, read_message_history=True)
            log_tc = await guild.create_text_channel(log_channel_name, category=category, overwrites=overwrites_log)
            await asyncio.sleep(1)

        if not broadcast_vc:
            overwrites_broadcast = {
                guild.default_role: discord.PermissionOverwrite(
                    view_channel=True, connect=True, read_message_history=True,
                    speak=False, send_messages=False, add_reactions=False, stream=False
                ),
                bot.user: discord.PermissionOverwrite(connect=True, speak=True, send_messages=True, administrator=True)
            }
            broadcast_vc = await guild.create_voice_channel(broadcast_vc_name, category=category, overwrites=overwrites_broadcast)
            await asyncio.sleep(1)

        if not control_vc:
            overwrites_control = {
                guild.default_role: discord.PermissionOverwrite(view_channel=False, connect=False),
                bot.user: discord.PermissionOverwrite(view_channel=True, connect=True, send_messages=True)
            }
            if owner_role: overwrites_control[owner_role] = discord.PermissionOverwrite(view_channel=True, connect=True, send_messages=True)
            control_vc = await guild.create_voice_channel(control_vc_name, category=category, overwrites=overwrites_control, user_limit=99)
            
            embed = discord.Embed(
                title="🎛️ لوحة تحكم الإذاعة الذكية", 
                description="استخدم الأزرار أدناه للتحكم السريع في البث، أو اختر القارئ من القائمة المنسدلة.\n\n*ملاحظة: يمكنك أيضاً استخدام الأوامر مثل `/volume` هنا فقط.*", 
                color=discord.Color.dark_theme()
            )
            embed.set_footer(text="SaaS Pro Dashboard")
            await control_vc.send(embed=embed, view=ControlPanelView())

        # اتصال البوت
        if not guild.voice_client:
            vc = await broadcast_vc.connect()
            await asyncio.sleep(2) # استقرار الاتصال
            await play_current_reciter(vc)
            
            human_members = sum(1 for m in broadcast_vc.members if not m.bot)
            if human_members == 0:
                vc.pause() 
                await log_event(guild, "⏸️ القناة فارغة، تم وضع البث في وضع الاستعداد (لتجنب ضغط الشبكة).")
            else:
                await log_event(guild, "▶️ تم البدء بالبث لوجود مستمعين في القناة.")

    except Exception as e:
        print(f"⚠️ تحذير أثناء إنشاء القنوات (قد يكون بسبب ضغط الطلبات): {e}")

@bot.event
async def on_voice_state_update(member, before, after):
    if member.bot: return
    guild = member.guild
    if guild.id != TARGET_GUILD_ID: return
    bot_vc = guild.voice_client
    if not bot_vc: return

    try:
        # حالة دخول عضو
        if after.channel and after.channel.id == bot_vc.channel.id:
            if bot_vc.is_paused():
                bot_vc.resume() 
                await log_event(guild, f"▶️ استئناف البث التلقائي لدخول مستمع.")
                
            embed = discord.Embed(
                title="أهلاً بك في مجلس الذكر 🕊️",
                description=random.choice(REMINDERS),
                color=discord.Color.gold()
            )
            embed.set_footer(text=f"القارئ الحالي: {RECITERS[current_reciter_index]['name']}")
            try:
                await after.channel.send(content=f"مرحباً بك {member.mention}", embed=embed, delete_after=60)
            except: pass

        # حالة خروج عضو
        elif before.channel and before.channel.id == bot_vc.channel.id:
            human_members = sum(1 for m in before.channel.members if not m.bot)
            if human_members == 0 and bot_vc.is_playing():
                bot_vc.pause()
    except: pass # منع أي خطأ مفاجئ من إيقاف البوت

# =======================================================
#               مهمة الفحص الهادئ (Heartbeat)
# =======================================================
@tasks.loop(minutes=5)
async def heartbeat_task():
    """هذه الدالة تفحص البوت كل 5 دقائق لضمان عدم فصله من ديسكورد"""
    try:
        guild = bot.get_guild(TARGET_GUILD_ID)
        if guild and guild.voice_client:
            human_members = sum(1 for m in guild.voice_client.channel.members if not m.bot)
            # إذا كان هناك ناس والصوت متوقف بالخطأ، نقوم بتشغيله
            if human_members > 0 and not guild.voice_client.is_playing() and not guild.voice_client.is_paused():
                await play_current_reciter(guild.voice_client)
                await log_event(guild, "🔄 تم إعادة إنعاش البث التلقائي بواسطة نظام الحماية (Heartbeat).")
    except: pass

# =======================================================
#               أوامر السلاش (محصورة في غرفة التحكم)
# =======================================================

@bot.tree.command(name="play_radio", description="▶️ تشغيل بث القرآن إجبارياً")
@is_owner_and_in_control()
async def play_radio(interaction: discord.Interaction):
    vc = interaction.guild.voice_client
    try:
        if not vc: return await interaction.response.send_message("❌ البوت غير متصل.", ephemeral=True)
        if vc.is_paused(): vc.resume()
        else: await play_current_reciter(vc)
        await interaction.response.send_message(f"▶️ تم التشغيل: **{RECITERS[current_reciter_index]['name']}**", ephemeral=True)
        await log_event(interaction.guild, f"▶️ تم التشغيل عبر أمر /play_radio")
    except: pass

@bot.tree.command(name="stop_radio", description="⏹️ إيقاف البث مؤقتاً")
@is_owner_and_in_control()
async def stop_radio(interaction: discord.Interaction):
    vc = interaction.guild.voice_client
    try:
        if vc and vc.is_playing():
            vc.pause()
            await interaction.response.send_message("⏹️ تم الإيقاف.", ephemeral=True)
            await log_event(interaction.guild, f"⏹️ تم الإيقاف عبر أمر /stop_radio")
        else:
            await interaction.response.send_message("⚠️ متوقف بالفعل.", ephemeral=True)
    except: pass

@bot.tree.command(name="volume", description="🔊 التحكم بدرجة الصوت (من 1 إلى 100)")
@app_commands.describe(level="درجة الصوت من 1 إلى 100")
@is_owner_and_in_control()
async def set_volume(interaction: discord.Interaction, level: int):
    global current_volume
    try:
        if level < 1 or level > 100:
            return await interaction.response.send_message("❌ يرجى إدخال رقم بين 1 و 100.", ephemeral=True)
        
        current_volume = level / 100.0
        vc = interaction.guild.voice_client
        if vc and vc.source: vc.source.volume = current_volume
            
        await interaction.response.send_message(f"🔊 تم تغيير درجة الصوت إلى: **{level}%**", ephemeral=True)
        await log_event(interaction.guild, f"🔊 تم تغيير درجة الصوت إلى {level}%")
    except: pass

# =======================================================
#               التشغيل والـ Keep Alive
# =======================================================
try:
    from keep_alive import keep_alive
    keep_alive()
except Exception: pass

if __name__ == "__main__":
    TOKEN = os.environ.get("DISCORD_TOKEN")
    if TOKEN: bot.run(TOKEN)
    else: print("❌ التوكن مفقود! يرجى التأكد من وضعه في المتغيرات البيئية (Secrets).")