        import React, { useState, useRef, useEffect, useMemo, useCallback, useLayoutEffect } from 'react';
        import { createRoot } from 'react-dom/client';
        import { Play, Pause, Upload, Settings, Layers, Video, Music, Wand2, Clock, Scissors, Sparkles, BookOpen, Trophy, CheckCircle2, AlertCircle, Cpu, Loader2, ListMusic, Palette, Search, X, Check, Edit3, Save, Download, Image as ImageIcon, Type, AlignVerticalJustifyCenter, Move, Lock, Code2, Film, FileAudio, Heart, RefreshCcw, FileJson, UploadCloud, AlertTriangle, ShieldAlert, BadgeCheck, Grid, FolderOpen, MonitorPlay, Volume2, Volume1, VolumeX, Headphones, Dna, MapPin, ChevronRight, ChevronLeft, HelpCircle, LayoutTemplate, Monitor, Copy, Trash2, GripVertical, MoreVertical, ChevronUp, ChevronDown, PanelTopClose, PanelBottomOpen, ArrowRight, Hash, Layout, LayoutGrid, RotateCcw, RotateCw, Maximize, ZoomIn, MoveHorizontal, MoveVertical } from 'lucide-react';
        import Cropper from 'react-easy-crop';

        // لا تُعطَّل وظائف المتصفح أو أدوات الوصول عالميًا. حماية الأسرار
        // والعمليات الحساسة تقع على الخادم، لا عبر حجب الاختصارات أو النسخ.

        /* ═══════════════════════════════════════════════════════════════════
           مصيدة أدوات المطوّر — أُزيلت في المرحلة 5
           ═══════════════════════════════════════════════════════════════════
           كانت: `debugger;` كل 4 ثوان، وإن تجاوز الفارق 160ms تُمسح
           `document.body.innerHTML` وتُستبدل بشاشة خطأ.

           أُزيلت لثلاثة أسباب، أوّلها وحده كافٍ:

           1) **المسح غير قابل للرجوع.** إفراغ `body` يهدم جذر React وكل
              حالة العمل معه. لا يكفي إغلاق الأدوات ولا `setInterval` آخر:
              المستخدم أمام شاشة ميتة، وأي مقطع لم يُصدَّر ضاع. عقوبةُ
              خطأٍ في الكشف هنا أثقل من الشيء الذي يُفترض أنه يحميه.

           2) **الكشف يخطئ على الأجهزة التي وعدنا بدعمها.** القياس هو الفارق
              بين `performance.now()` قبل `debugger` وبعده — أي أنه يقيس
              *أي* تجميدٍ للخيط في تلك اللحظة، لا وجود الأدوات. ووقفة GC
              أو خنقٌ حراري على جهاز أندرويد 6-7 تبلغ 160ms بلا عناء.
              والأسوأ: عند تصغير التطبيق (الانتقال إلى تطبيق آخر) قد يُجمِّد
              Chrome الـrenderer بين السطرين، فيعود المستخدم من مكالمةٍ
              أثناء تصدير طويل ليجد تطبيقه مهدومًا. وهذا ليس افتراضًا
              نظريًّا: هو أكثر سلوكٍ متوقَّع على الهاتف.

           3) **لا تُضيف أمانًا.** الكود يُخدَم نصًّا عامًّا لكل زائر؛ من أراد
              قراءته يقرأه من "عرض المصدر" أو من الشبكة بلا أدوات مطوّر.
              الحماية الحقيقية محلّها الخادم (انظر ملاحظة التوكن أدناه).

           بقي `window._devtoolsCheckPaused` بلا تعريف بقصد: مواضع نداءه
           الثلاثة في كود التصدير محروسة بـ`if (window._devtoolsCheckPaused)`،
           فتصير بلا أثر تلقائيًّا. (حُذفت هي أيضًا في المرحلة نفسها.)

           أُزيل مفتاح Google من العميل. التحليل التلقائي يمر الآن عبر
           `quran-analysis.php` الذي يفرض حدود الملف والنطاق والتحقق من النص.
           ═══════════════════════════════════════════════════════════════════ */
        const CANVAS_WIDTH = 1080, CANVAS_HEIGHT = 1920;
        const QURAN_ANALYSIS_ENDPOINT = './quran-analysis.php';
        const FONTS = [{ name: 'UthmanicHafs', label: 'عثماني حفص', css: "'Uthmanic Hafs', serif" }, { name: 'Tajawal', label: 'تجوّل', css: "'Tajawal', sans-serif" }, { name: 'Cairo', label: 'كايرو', css: "'Cairo', sans-serif" }, { name: 'Amiri', label: 'أميري', css: "'Amiri', serif" }];
        const DEFAULT_AYAH_STYLE = { x: CANVAS_WIDTH / 2, y: CANVAS_HEIGHT / 2, size: 71, color: '#ffffff', shadowColor: '#000000', shadowOpacity: 0.5, font: FONTS[0].css, fontWeight: 'normal', animation: 'fade' };
        const DEFAULT_WATERMARK = { text: "@wadl6", x: CANVAS_WIDTH / 2, y: CANVAS_HEIGHT - 200, size: 30, color: '#ffffff', font: FONTS[1].css, visible: true, opacity: 0.75 };
        const DEFAULT_OVERLAY = { type: 'color', value: '#000000', colorOpacity: 0.4, imageOpacity: 0.3, imageSrc: null }, DEFAULT_BRANDING = false;

        const EXPORT_DUAS = [
            // --- للوالدين (بر وإحسان) ---
            "اللهم اغفر لوالدي صاحب الموقع، وارحمهما رحمة واسعة، واجعل هذا العمل في ميزان حسناتهما، وارفعهما به درجات في الجنة.",
            "اللهم حرّم وجه والدي صاحب الموقع على النار، واجزهما عنه خير الجزاء، واجمع شملهما في الفردوس الأعلى مع النبيين والصديقين.",

            // --- لصاحب الموقع ---
            "اللهم صبّ الرزق والخير على صاحب الموقع صبّاً، واكتب له التوفيق في كل خطوة، واكفه بحلالك عن حرامك وبفضلك عمن سواك.",
            "اللهم اشرح صدر صاحب الموقع للإيمان، ويسّر أمره، وثبّته على الحق، واجعل القرآن العظيم ربيع قلبه ونور بصره.",

            // --- للزوجة (خاص ومنفصل) ---
            "اللهم احفظ لصاحب الموقع زوجتَه، وأدم بينهما المودة والرحمة والسكينة، واجعلها له نِعم العون على طاعتك ورضاك.",
            "اللهم بارك لصاحب الموقع في أهله، وألبسهم ثوب الصحة والعافية، واجعل بيته عامراً بذكرك وشكرك وحسن عبادتك.",

            // --- للذرية (خاص ومنفصل) ---
            "اللهم هب لصاحب الموقع ذرية طيبة صالحة، واجعلهم من حفظة كتابك، والعاملين به، وقرّ عينه بصلاحهم في الدنيا والآخرة.", // تم تعديل "والعاملين" حسب طلبك
            "اللهم اجعل ذرية صاحب الموقع مباركة أينما كانت، واحفظهم من الفتن ما ظهر منها وما بطن، واجعلهم للمتقين إماماً.",

            // --- للأصدقاء (طارق وعمر) ---
            "اللهم افتح على صديقي (طارق) فتوحاً مبيناً، وسخّر له ملائكة السماء وجنود الأرض، واكتب له النجاح حليفاً في كل أمر.",
            "اللهم أسعد صديقي (عمر) سعادة الدارين، وبارك له في عمره وعمله، ووفقه لما تحب وترضى، واجعل الخير كله في نصيبه.",

            // --- للمسلمين عامة ---
            "اللهم اغفر للمسلمين والمسلمات، والمؤمنين والمؤمنات، الأحياء منهم والأموات، وأصلح ذات بينهم، وألّف بين قلوبهم.",

            // --- القبول والختام ---
            "اللهم تقبل هذا العمل من صاحب الموقع خالصاً لوجهك الكريم، واجعله لوجهك خالصاً، لا رياء فيه ولا سمعة.",
            "اللهم اجمع صاحب الموقع ووالديه وزوجته وذريته وأصحابه (عمر وطارق) وسائر المسلمين والمسلمات تحت ظل عرشك يوم لا ظل إلا ظلك."
        ];

        // Professional Caption Templates for Instagram/TikTok Reels
        const CAPTION_TEMPLATES = [
            // الفئة الأولى: راحة نفسية وطمأنينة (High Retention & Watch Time)
            { text: "في زحام الدنيا وضجيج الأيام، يبقى القرآن هو الملاذ الذي تأنس به الأرواح وتطمئن به القلوب 🤍.\nأغلق عينيك للحظات، واستمع لتلاوة تلامس وجدانك وتغسل عنك تعب الأسبوع 🎧.\n\nاللهم اجعل القرآن العظيم ربيع قلوبنا ونور أبصارنا.\n\nشارك المقطع مع من تحب ليكون لك صدقة جارية 💌", hashtags: "#القرآن_الكريم #راحة_نفسية #quran7" },
            { text: "صوت يريح القلب المهموم ويسكن الروح 🎧🤍.\nقال الله تعالى: (أَلَا بِذِكْرِ اللَّهِ تَطْمَئِنُّ الْقُلُوبُ). خذ دقيقة من وقتك الآن لتجديد طاقتك الإيمانية والاستماع لكلام ربك.\n\nاحفظ هذا المقطع لتعود إليه كلما شعرت بضيق 🤍", hashtags: "#تلاوات_خاشعة #طمأنينة #quran7" },
            { text: "لعل هذه التلاوة تكون إشارة لقلبك في هذا الوقت بالتحديد ✋🤍.\nكثيراً ما نبحث عن راحة في الدنيا، وننسى أن الراحة الحقيقية في كلام خالقنا. استمع بتدبر ودع الآيات تلامس شغاف قلبك.\n\nاكتب 'آمين' إذا وجدت راحة في هذا المقطع 🤲", hashtags: "#خشوع #تدبر_القرآن #quran7" },
            { text: "وكلت أمري يا الله، فأنت خير وكيل 🤲🤍.\nلا تنم قبل أن تسمع شيئاً من القرآن، فإنه نور للقلب وصلاح للنفس وسكينة للجوارح. استمع لهذه التلاوة العطرة التي تريح الأعصاب وتذهب الهموم.\n\nمن تعرف يحتاج لسماع هذا المقطع اليوم؟ شاركه معه 📩", hashtags: "#راحة_نفسية #قرآن_كريم #quran7" },
            { text: "في هذا اليوم المبارك، اللهم اجعل القرآن ربيع قلوبنا 🤍.\nتلاوة آسرة تأخذك لعالم آخر من الطمأنينة والسكينة، بعيداً عن ضجيج الحياة وتفاصيلها المزعجة. استمع بقلبك 🎧.\n\nثمّن استماعك بكتابة 'الحمد لله' في التعليقات 🌿", hashtags: "#القرآن #سكينة_القلب #quran7" },
            { text: "أخي/أختي.. تأمل هذه الآيات كأنها نزلت لك وحدك 🤍.\nكلام الله فيه شفاء لما في الصدور، وفيه نور لمن أراد الهداية. استمع لتلاوة تلامس الروح وتوقظ الضمير.\n\nاحفظ المقطع واجعله ضمن أذكارك اليومية 📌", hashtags: "#تلاوة_قرآنية #شفاء_الصدور #quran7" },
            { text: "صوت ينقلك فجأة إلى عالم آخر من الطمأنينة والسكينة 🎧☁️.\nاستمع بقلبك وردد مع المقطع، فترقيق القلب بكلام الله من أعظم القربات. اللهم اجعلنا من أهل القرآن الذين هم أهلك وخاصتك.\n\nأحبك في الله، شارك المقطع ليعم الأجر 🤍", hashtags: "#راحة_نفسية #قرآن #quran7" },

            // الفئة الثانية: دعاء وتوكل (High Saves & Shares)
            { text: "من أعظم النعم أن يرزقك الله الأنس به والطمأنينة بذكره 🤲🏻.\nاللهم ارزقنا حبك، وحب من يحبك، وحب عمل يقربنا إلى حبك. استمع لهذه التلاوة التي تدمع لها العيون وتخشع لها القلوب.\n\nاحفظها لتعود إليها وقت حاجتك 🤍", hashtags: "#الدعاء #خشوع_القلب #quran7" },
            { text: "يا رب لا تحرمنا لذة مناجاتك، ولا تتركنا لأنفسنا طرفة عين 🤍.\nاللهم اجعل القرآن العظيم ربيع قلوبنا، واجعلنا ممن يقرؤونه آناء الليل وأطراف النهار. استمع بقلبك وردد معي الدعاء 🤲.\n\nثمّن هذا الدعاء بـ 'آمين' 🌿", hashtags: "#أدعية_قرآنية #قرآن #quran7" },
            { text: "ربِّ إني مسّني الضر وأنت أرحم الراحمين 🤲.\nدعوة نبي الله أيوب عليه السلام في شدته، ما لجأ بها مكروب إلى الله بيقين إلا كشف ضره وفرج كربه. استمع بقلبك وتأمل معاني التسليم في هذه الآيات.\n\nشاركها، فلعلها تكون سبب فرج لأحد إخوانك 🤍", hashtags: "#تفريج_الهموم #تلاوة #quran7" },
            { text: "اللهم اشرح صدورنا، ويسر أمورنا، وارزقنا السكينة في هذه الدنيا الزائلة 🤲🤍.\nتلاوة تهدئ النفس وتريح البال وتذكرنا بأن كل شيء بيد الله، فلا قلق ولا حزن مع التوكل عليه.\n\nأرسلها لمن تحب وقل له: اطمئن، الله معنا 💌", hashtags: "#تلاوات_مريحة #القرآن_الكريم #quran7" },

            // الفئة الثالثة: تذكير وموعظة (Viral Potential)
            { text: "\"وَمَا عِندَ اللَّهِ خَيْرٌ وَأَبْقَىٰ\" 🤍.\nكم من شيء فقدناه فعوضنا الله خيراً منه! لا تحزن على ما فاتك من الدنيا، فما عند الله أجمل وأبقى. تأمل هذه الآيات واجعلها منهج حياتك.\n\nهل لديك قصة فرج بعد ضيق؟ شاركها لتبشير الآخرين 🌿", hashtags: "#موعظة #تدبر #quran7" },
            { text: "\"أَلَا بِذِكْرِ اللَّهِ تَطْمَئِنُّ الْقُلُوبُ\" 🕊️.\nاجعل لسانك رطباً بذكر الله، واجعل سماع القرآن عادتك اليومية. في القلب شجن لا يزيله إلا كلام الرب، وفي الروح تعب لا يريحه إلا الأنس بالله.\n\nاحفظ المقطع كتذكير لنفسك 🤍", hashtags: "#ذكر_الله #قرآن #quran7" },
            { text: "استمع وأغلق عينيك 🎧🤍.\nدع القرآن يغسل قلبك من هموم الدنيا، ويعيد لك توازنك وسكينتك. نحن في حاجة ماسة للتوقف قليلاً والاستماع لنداء ربنا.\n\nشارك هذا المقطع ليكون صدقة جارية لك 🤲", hashtags: "#تلاوة_خاشعة #راحة #quran7" },
            { text: "هذا المقطع وصلك في هذا الوقت بالتحديد لسبب 💚🤲.\nلا شيء يصادف في هذه الحياة، فلعل قلبك يحتاج لسماع هذه الآيات الآن. تأملها بقلبك وثق أن الله يعلم سرك ونجواك.\n\nاكتب 'الحمد لله' شكراً لله على نعمة القرآن 🌿", hashtags: "#تذكير #القرآن_الكريم #quran7" },

            // الفئة الرابعة: صباح/مساء (Timing Specific)
            { text: "صباح القرآن والسكينة ☀️🤍.\nابدأ يومك بنور الله، فإن بدأت نهارك بكلامه بارك الله في وقتك ورزقك وفتح لك أبواب الخير. استمع لهذه التلاوة العطرة واجعلها بداية يومك.\n\nاكتب 'صباح الخير' لنشاركك الدعاء 🌿", hashtags: "#أذكار_الصباح #القرآن #quran7" },
            { text: "مساء السكينة والإيمان 🌙🤍.\nفي نهاية يومك، لا شيء يذهب التعب مثل كلام الله. استمع لهذه التلاوة قبل نومك، فإنها طمأنينة للنفس وأمان للجوارح.\n\nشاركها مع عائلتك ليكون مساءكم مباركاً 💌", hashtags: "#أذكار_المساء #تلاوة #quran7" },
            { text: "نور الله يضيء دروبكم 🌅🤍.\nاللهم اجعل هذا اليوم طيباً مباركاً، واكفنا شره بحولك وقوتك. دقائق من الاستماع للقرآن صباحاً تجدد العزيمة وتشرح الصدر.\n\nاحفظ المقطع كجزء من روتينك الصباحي 📌", hashtags: "#صباح_الخير #قرآن_كريم #quran7" },

            // الفئة الخامسة: تفاعل مع المتابعين (Engagement Hooks)
            { text: "لكل قلب سورة تأنس بها، وتقرأها في كل وقت وحين 📖🤍.\nعندما تتعب نفسك أو يضيق صدرك، ما هي الآية أو السورة التي تسرع لتقرأها؟ شاركنا إياها في التعليقات لنشاركك الأجر بالتأمل 🤲.", hashtags: "#خواطر_قرآنية #قرآن #quran7" },
            { text: "أرسل هذا المقطع لشخص تحبه في الله ولا تنتظر منه رداً 💌🤍.\nفقط قل له: لقد مررت بقلبي اليوم ودعوت لك، وهذه التلاوة أهديها لك. الدال على الخير كفاعله، كن أنت سبب السكينة لقلب مؤمن 🌿.", hashtags: "#حب_في_الله #صدقة_جارية #quran7" },
            { text: "ثواب الدال على الخير كفاعله، بل قد يكون أعظم أجراً 🌿.\nبضغطة زر واحدة، يمكنك أن تكون سبباً في وصول كلام الله إلى قلوب تنتظر هذه الرسالة. انشر المقطع واكسب الأجر المستمر 🤲.", hashtags: "#نشر_الخير #القرآن_الكريم #quran7" },
            { text: "اجعل مشاركتك لهذا المقطع صدقة جارية لك ولوالديك 🤲🤍.\nأرسله في مجموعاتك وحساباتك، فلعل هناك قلباً يهتدي، أو نفساً تطمئن، أو عيناً تدمع خشية لله بسبب مشاركتك 🌿.", hashtags: "#أجر_مستمر #تلاوة #quran7" },

            // الفئة السادسة: آيات محددة ملهمة (Contextual)
            { text: "\"إِنَّ مَعَ الْعُسْرِ يُسْرًا\" 🌿.\nوعد إلهي لا يتبدل ولا يتغير.. ما أصعب العسر إلا ويسره في طريقه إليك. ثق بالله وانتظر الفرج، فإن مع كل شدة رخاء، ومع كل تعب سكينة.\n\nاحفظها لتثبت قلبك وقت الضيق 🤍", hashtags: "#تفاؤل #القرآن_الكريم #quran7" },
            { text: "\"وَبَشِّرِ الصَّابِرِينَ\" 💚.\nالصبر ليس مجرد تحمل، بل هو حسن التوكل واليقين بأن ما بعد الصبر جميل. تأمل هذه الآيات التي ترفع الهمم وتجدد العزائم.\n\nمن تعرف يحتاج لسماع هذه البشارة اليوم؟ أرسلها له 🤍", hashtags: "#الصبر #تلاوة_قرآنية #quran7" },
            { text: "\"فَاذْكُرُونِي أَذْكُرْكُمْ\" 🤍.\nمن أعظم المراتب أن يذكرك الله في الملأ الأعلى. اجعل وقتك كله معموراً بالذكر والاستماع للقرآن، فهو سر السعادة في الدنيا والآخرة.\n\nثمّن هذا التذكير بكتابة 'سبحان الله وبحمده' 🌿", hashtags: "#ذكر_الله #تدبر_القرآن #quran7" },
            { text: "\"وَلَسَوْفَ يُعْطِيكَ رَبُّكَ فَتَرْضَىٰ\" 🌟.\nثق بموعود الله، فما أخطأك لم يكن ليصيبك، وما أصابك لم يكن ليخطئك. رضاك القادم مرتبط برضاك بقضاء الله.\n\nشاركها لتكون رسالة يقين لقلب متعب 🤍", hashtags: "#يقين_بالله #قرآن #quran7" },
            { text: "\"حَسْبُنَا اللَّهُ وَنِعْمَ الْوَكِيلُ\" 🤲.\nقالها إبراهيم عليه السلام حين ألقي في النار، وقالها نبينا ﷺ في الشدائد. فوض أمرك لله، واسترح من التفكير المبالغ فيه، فالله لا يضيع أجر من أحسن عملاً.\n\nاكتبها لتكون لك صدقة جارية 🤍", hashtags: "#توكل_على_الله #تلاوة #quran7" },

            // الفئة السابعة: عام وشامل (General Evergreen)
            { text: "اجعل القرآن صديقك في كل وقت 📖💚.\nدقائق من عمرنا نقضيها مع كتاب الله، هي بمثابة محطة إعادة شحن للروح. القرآن ليس مجرد كلمات تقرأ، بل هو نور يُقذف في القلب.\n\nاحفظ المقطع كأذكارك اليومية 🤍", hashtags: "#القرآن_الكريم #راحة_نفسية #quran7" },
            { text: "دقيقة واحدة مع القرآن قد تغير يومك بالكامل 🤍.\nلا تستهن بأثر كلام الله على نفسيتك وقلبك. استمع لتلاوة خاشعة تعيد ترتيب أفكارك وتهدئ من روعك.\n\nشارك المقطع ليكون لك أجر مستمر 🤲", hashtags: "#تلاوة #قرآن_كريم #quran7" },
            { text: "القرآن شفاء ورحمة ونور 💚🤍.\nاجعله دواءك اليومي من قسوة الدنيا، وهموم العمل، وأعباء الحياة. استمع بقلبك وقل: الحمد لله الذي هدانا لهذا.\n\nهل شعرت بالسكينة؟ اكتب 'نعم' في التعليقات 🌿", hashtags: "#خشوع #تلاوات_خاشعة #quran7" },
            { text: "استرح من ضجيج الدنيا قليلاً مع هذه التلاوة 🎧💚.\nأغمض عينيك، واستمع لصوت يأخذك لعالم آخر مليء بالطمأنينة والسكينة، بعيداً عن تفاصيل الحياة المرهقة.\n\nشاركها مع من تحب 🤍", hashtags: "#سكينة #قرآن #quran7" },
            { text: "لحظة سكون مع كلام الله 🕊️🤍.\nاللهم اجعل قلوبنا عامرة بذكره وألسنتنا رطبة بتلاوة كتابه. استمع بتدبر وتأمل، ففي كل آية نور وشفاء.\n\nاحفظ المقطع لتعود إليه لاحقاً 📌", hashtags: "#راحة_نفسية #القرآن_الكريم #quran7" },

            // الفئة الثامنة: أدعية قصيرة (Short Prayers)
            { text: "اللهم اغفر لي ولوالدي ولمن دخل بيتي مؤمناً وللمؤمنين والمؤمنات 🤲💚.\nدعوة صادقة في ظهر الغيب قد تغير قدراً وتفتح باباً من السماء. لا تنسَ والديك بدعوة في هذه اللحظة 🤍.\n\nاكتب 'آمين' 🌿", hashtags: "#الدعاء #أدعية #quran7" },
            { text: "اللهم يسر أمورنا واشرح صدورنا، واجعل القرآن العظيم قائدنا إلى الجنة 🤲🤍.\nاستمع لتلاوة تطمئن لها النفوس وتخشع لها القلوب. اللهم اجعلنا ممن قرأ القرآن فاتبعته على نور من ربهم.\n\nشاركها لتكون لك صدقة جارية 💌", hashtags: "#دعاء_مستجاب #قرآن #quran7" },
            { text: "اللهم ارزقنا حسن الخاتمة، واجعل آخر كلامنا من الدنيا لا إله إلا الله 🤲💚.\nتلاوة تذكرنا بحقيقة الدنيا الزائلة، وتوجه أنظارنا نحو الآخرة الباقية. استمع بقلبك واجعلها تذكرة لنفسك.\n\nثمّن المقطع بـ 'اللهم آمين' 🤍", hashtags: "#حسن_الخاتمة #تلاوة_قرآنية #quran7" },
            { text: "اللهم اجعلنا من أهل القرآن الذين هم أهلك وخاصتك 📖🤍.\nأهل القرآن هم أهل الله وخاصته، فاجعل القرآن دليلك في حياتك، وأنيسك في قبرك، وشفيعك يوم القيامة.\n\nاحفظ المقطع واكسب أجر النشر 🌿", hashtags: "#أهل_القرآن #خشوع #quran7" },

            // الفئة التاسعة: قصيرة وجذابة (Minimalist)
            { text: "استمع.. وأحسن الظن بالله 💚.\nالله أرحم بك من نفسك، وأعلم بحالك منك. تأمل هذه الآيات وثق أن الفرج قادم 🤍.\n\nشارك المقطع لنشر الأجر 🌿", hashtags: "#تلاوة #راحة_نفسية #quran7" },
            { text: "كلام الله.. نور للقلوب وشفاء للصدور 🤍.\nدقائق من السكينة مع آيات تلامس الروح وتذهب الهموم 🎧.\n\nاكتب 'سبحان الله' إذا أعجبك المقطع 🌿", hashtags: "#القرآن_الكريم #خشوع #quran7" },
            { text: "ريّح قلبك بكلام ربك 🎧💚.\nالقلوب تعبث بها هموم الدنيا، ولا يصلحها إلا من خلقها. استمع لتلاوة تريح الأعصاب وتجلي الهموم.\n\nاحفظها لتعود إليها وقت حاجتك 📌", hashtags: "#قرآن #تلاوات #quran7" },
            { text: "تلاوة تمس القلب وتوقظ الفطرة 🤍.\nاستمع بروحك، وتأمل بقلبك، وثق بأن الخير كله في كتاب الله 📖.\n\nشاركها مع من تحب 💌", hashtags: "#تلاوة_خاشعة #قرآن_كريم #quran7" },
            { text: "لحظة مع الله قد تغير حياتك بالكامل 💚.\nلا تمر على هذه الآيات مرور الكرام، بل توقف وتأمل، ففيها مفتاح سعادتك وراحتك 🤍.\n\nثمّن المقطع بكتابة 'الحمد لله' 🌿", hashtags: "#خواطر_قرآنية #القرآن #quran7" },

            // الفئة العاشرة: تشجيع على النشر (Share Boosters)
            { text: "كن سبباً في نشر الخير اليوم 💌.\nبمشاركتك لهذا المقطع، قد تكون سبباً في إدخال السكينة إلى قلب شخص مهموم، أو تذكير شخص غافل. الدال على الخير كفاعله، انشر واكسب الأجر 🤲🤍.", hashtags: "#صدقة_جارية #نشر_الخير #quran7" },
            { text: "انشر تؤجر.. واترك أثراً طيباً لا ينقطع 🌿.\nتخيل أن شخصاً يستمع لهذا المقطع بسبب مشاركتك، فيخشع قلبه ويدمع عينه، فتكون شريكاً في أجره حتى يوم القيامة. انشر الآن 🤍.", hashtags: "#أجر_مستمر #القرآن_الكريم #quran7" },
            { text: "الرسالة وصلتك.. فلا تحرم غيرك منها 🤲.\nمقاطع القرآن الكريم من أعظم الصدقات الجارية في عالم الرقميات. انشر المقطع في حالاتك (Story) أو في مجموعاتك ليصلك أجر كل من يسمعه بسببك 🤍.", hashtags: "#القرآن #صدقة #quran7" },
            { text: "اجعل مشاركتك (Share) اليوم صدقة جارية لك ولوالديك 🤲🤍.\nانشر هذه التلاوة الطيبة، فالرسول ﷺ قال: (الدال على الخير كفاعله). كن دليلاً على الخير في هذه الدنيا 🌿.", hashtags: "#الدال_على_الخير #تلاوة #quran7" }
        ];

        // === VIDEO OF THE DAY MODAL ===
        // === VIDEO OF THE DAY MODAL ===
        // === VIDEO OF THE DAY MODAL ===
        const VideoOfTheDayModal = ({ isOpen, onClose }) => {
            const [loading, setLoading] = useState(true);
            const [error, setError] = useState(null);
            const [videoData, setVideoData] = useState(null);
            const [countdown, setCountdown] = useState(0);
            const [downloading, setDownloading] = useState(false);

            // Custom Video Player Hooks
            const videoRef = useRef(null);
            const [isPlaying, setIsPlaying] = useState(false);
            const [currentTime, setCurrentTime] = useState(0);
            const [duration, setDuration] = useState(0);
            const [volume, setVolume] = useState(() => parseFloat(localStorage.getItem(VOLUME_KEY)) || 1);
            const [isMuted, setIsMuted] = useState(false);

            // Responsive Sizing State
            const [aspectRatio, setAspectRatio] = useState(16 / 9); // Default to 16:9

            // Sync volume to localStorage on change
            useEffect(() => {
                localStorage.setItem(VOLUME_KEY, volume);
                if (videoRef.current) videoRef.current.volume = volume;
            }, [volume]);

            useEffect(() => {
                if (isOpen) fetchVideoData();
            }, [isOpen]);

            useEffect(() => {
                let interval;
                if (videoData && videoData.time_remaining && videoData.time_remaining.total_seconds > 0) {
                    interval = setInterval(() => {
                        setCountdown(prev => {
                            if (prev <= 0) {
                                clearInterval(interval);
                                fetchVideoData(); // Refresh when timer hits zero
                                return 0;
                            }
                            return prev - 1;
                        });
                    }, 1000);
                    setCountdown(videoData.time_remaining.total_seconds);
                }
                return () => clearInterval(interval);
            }, [videoData]);

            const fetchVideoData = async () => {
                try {
                    setError(null);
                    setLoading(true);
                    const response = await fetch('tod-api.php?action=current&_t=' + Date.now(), { cache: 'no-store' });
                    const data = await response.json();
                    if (data.success) {
                        setVideoData(data);
                        setCountdown(data.time_remaining.total_seconds);
                    } else {
                        setError(data.message || 'حدث خطأ في تحميل الفيديو');
                    }
                } catch (err) {
                    setError('فشل الاتصال بالخادم');
                } finally {
                    setLoading(false);
                }
            };

            const handleDownload = () => {
                if (!videoData) return;
                setDownloading(true);
                window.location.href = `tod-api.php?action=download&video=${videoData.video_number}`;
                setTimeout(() => setDownloading(false), 2000);
            };

            const formatCountdown = (seconds) => {
                const h = Math.floor(seconds / 3600);
                const m = Math.floor((seconds % 3600) / 60);
                const s = seconds % 60;
                return `${h}س ${m}د ${s}ث`;
            };

            // Video Player Handlers
            const togglePlay = () => {
                if (videoRef.current) {
                    if (isPlaying) videoRef.current.pause();
                    else videoRef.current.play();
                    setIsPlaying(!isPlaying);
                }
            };

            const handleTimeUpdate = () => {
                if (videoRef.current) setCurrentTime(videoRef.current.currentTime);
            };

            const handleLoadedMetadata = () => {
                if (videoRef.current) {
                    setDuration(videoRef.current.duration);

                    // FIX: Isolate Volume Application on Load
                    videoRef.current.volume = volume;

                    // FIX: Responsive Sizing Calculation
                    const videoRatio = videoRef.current.videoWidth / videoRef.current.videoHeight;
                    setAspectRatio(videoRatio);
                }
            };

            const handleSeek = (e) => {
                const time = parseFloat(e.target.value);
                if (videoRef.current) {
                    videoRef.current.currentTime = time;
                    setCurrentTime(time);
                }
            };

            const handleVolumeChange = (e) => {
                const newVol = parseFloat(e.target.value);
                setVolume(newVol);
                if (videoRef.current) {
                    videoRef.current.volume = newVol;
                    setIsMuted(newVol === 0);
                }
            };

            // Determine dimensions based on aspect ratio
            const isVertical = aspectRatio < 1;
            // Vertical: Mobile-like width (max-w-md) and 9:16 aspect
            // Horizontal: Standard width (max-w-4xl) and video aspect
            const modalClass = isVertical
                ? "tod-modal relative bg-[#1a1a1a] border border-white/10 rounded-2xl w-full max-w-md aspect-[9/16] overflow-hidden shadow-2xl animate-in zoom-in-95 duration-300 flex flex-col"
                : "tod-modal relative bg-[#1a1a1a] border border-white/10 rounded-2xl w-full max-w-4xl md:aspect-video overflow-hidden shadow-2xl animate-in zoom-in-95 duration-300 flex flex-col";

            if (!isOpen) return null;

            return (
                <div className="tod-overlay fixed inset-0 z-[100] bg-black/80 backdrop-blur-sm flex items-center justify-center p-4 animate-in fade-in" onClick={onClose}>
                    <div className={modalClass} style={{ maxHeight: '95vh' }} onClick={e => e.stopPropagation()}>

                        {/* Header */}
                        <div className="flex justify-between items-center p-4 border-b border-white/5 relative z-10 bg-[#1a1a1a] shrink-0">
                            <h2 className="text-lg font-bold text-white flex items-center gap-2">
                                <span className="text-xl">🎬</span> فيديو اليوم (تجدد يومي)
                            </h2>
                            <button onClick={onClose} className="text-gray-400 hover:text-white transition-colors bg-white/5 p-2 rounded-full hover:bg-white/10">
                                <X size={20} />
                            </button>
                        </div>

                        {/* Video Container: Removed fixed aspect ratio and max-height constraints to fill modal */}
                        <div className="tod-video-container relative bg-black flex-1 group overflow-hidden w-full h-full !max-h-none !aspect-auto !mb-0 !border-0 !rounded-none">
                            {loading ? (
                                <div className="absolute inset-0 flex items-center justify-center">
                                    <Loader2 className="animate-spin text-emerald-500" size={40} />
                                </div>
                            ) : error ? (
                                <div className="absolute inset-0 flex flex-col items-center justify-center text-red-400 gap-2 p-4 text-center">
                                    <AlertCircle size={32} />
                                    <p>{error}</p>
                                    <button onClick={fetchVideoData} className="mt-2 text-sm bg-white/10 px-3 py-1 rounded hover:bg-white/20 text-white">إعادة المحاولة</button>
                                </div>
                            ) : (
                                <>
                                    <video
                                        ref={videoRef}
                                        src={videoData?.video_url}
                                        className="w-full h-full object-contain cursor-pointer"
                                        onClick={togglePlay}
                                        onTimeUpdate={handleTimeUpdate}
                                        onLoadedMetadata={handleLoadedMetadata}
                                        onEnded={() => setIsPlaying(false)}
                                        playsInline
                                    />

                                    {/* Big Play Button Overlay */}
                                    {!isPlaying && (
                                        <div
                                            className="absolute inset-0 flex items-center justify-center bg-black/40 cursor-pointer backdrop-blur-[1px] transition-all hover:bg-black/30 z-20"
                                            onClick={togglePlay}
                                        >
                                            <div className="w-16 h-16 rounded-full bg-emerald-500/90 flex items-center justify-center pl-1 shadow-[0_0_20px_rgba(16,185,129,0.4)] transform hover:scale-110 transition-transform">
                                                <Play size={32} className="text-black fill-black" />
                                            </div>
                                        </div>
                                    )}

                                    {/* Gradient Overlay for Controls */}
                                    <div className="absolute inset-x-0 bottom-0 h-32 bg-gradient-to-t from-black/90 via-black/60 to-transparent pointer-events-none opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>

                                    {/* Custom Controls Bar */}
                                    {/* Responsive Controls Layout */}
                                    {/* REDUCED PADDING: changed p-4 to p-3 and pb-8 to pb-4 for tighter spacing */}
                                    <div className={`absolute bottom-0 left-0 right-0 p-3 flex flex-col gap-2 opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-30 ${isVertical ? 'pb-4' : ''}`}>
                                        {/* Seek Bar - Forced LTR for correct seek direction */}
                                        <div className="relative w-full h-1.5 bg-white/20 rounded-full cursor-pointer group/seek transition-all hover:h-2" dir="ltr">
                                            <div
                                                className="absolute top-0 left-0 h-full bg-emerald-500 rounded-full shadow-[0_0_10px_#10b981]"
                                                style={{ width: `${(currentTime / duration) * 100}%` }}
                                            ></div>
                                            <input
                                                type="range"
                                                dir="ltr"
                                                min="0"
                                                max={duration || 100}
                                                value={currentTime}
                                                onChange={handleSeek}
                                                className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
                                            />
                                            {/* Thumb on Hover */}
                                            <div
                                                className="absolute top-1/2 -translate-y-1/2 w-3 h-3 bg-white rounded-full shadow-lg pointer-events-none opacity-0 group-hover/seek:opacity-100 transition-opacity"
                                                style={{ left: `${(currentTime / duration) * 100}%` }}
                                            ></div>
                                        </div>

                                        <div className="flex items-center justify-between text-xs font-mono font-medium text-gray-300 mt-1">
                                            <div className="flex items-center gap-4">
                                                <button onClick={togglePlay} className="hover:text-emerald-400 transition-colors">
                                                    {isPlaying ? <Pause size={20} className="fill-current" /> : <Play size={20} className="fill-current" />}
                                                </button>

                                                {/* Volume Control - Desktop Only, Hidden on Mobile */}
                                                {/* FIX: Added group/volume and scoped group-hover/volume to strictly show slider only on button hover */}
                                                <div className="hidden md:flex items-center justify-center group/volume relative mx-1">
                                                    {/* Button */}
                                                    <button className="p-2 text-gray-400 hover:text-white transition-colors rounded-full hover:bg-white/5 relative z-20">
                                                        {volume === 0 ? <VolumeX size={20} /> : volume < 0.5 ? <Volume1 size={20} /> : <Volume2 size={20} />}
                                                    </button>

                                                    {/* Hover Bridge (Invisible area to keep hover active) */}
                                                    <div className="absolute bottom-full left-0 w-full h-6 bg-transparent z-10"></div>

                                                    {/* Vertical Slider Container */}
                                                    <div className="absolute bottom-[calc(100%+4px)] left-1/2 -translate-x-1/2 bg-[#1a1a1a] border border-white/10 p-3 pb-4 rounded-[2rem] shadow-[0_4px_20px_rgba(0,0,0,0.5)] flex flex-col items-center opacity-0 invisible group-hover/volume:opacity-100 group-hover/volume:visible transition-all duration-300 transform origin-bottom translate-y-2 group-hover/volume:translate-y-0 z-20">

                                                        {/* Value Text */}
                                                        <span className="text-[10px] font-mono text-emerald-400 mb-2 font-bold">{Math.round(volume * 100)}</span>

                                                        {/* The Slider Track Wrapper */}
                                                        <div className="relative w-1.5 h-24 rounded-full bg-gray-700/50">
                                                            {/* The Green Fill */}
                                                            <div
                                                                className="absolute bottom-0 left-0 w-full bg-emerald-500 rounded-full transition-all duration-100"
                                                                style={{ height: `${volume * 100}%` }}
                                                            ></div>

                                                            {/* The Thumb (Visual) */}
                                                            <div
                                                                className="absolute left-1/2 -translate-x-1/2 w-3.5 h-3.5 bg-white rounded-full shadow-[0_0_10px_rgba(16,185,129,0.5)] pointer-events-none transition-all duration-100"
                                                                style={{ bottom: `calc(${volume * 100}% - 7px)` }}
                                                            ></div>

                                                            {/* The Actual Input (Invisible but interactive) */}
                                                            <input
                                                                dir="ltr"
                                                                type="range"
                                                                min="0"
                                                                max="1"
                                                                step="0.01"
                                                                value={volume}
                                                                onChange={handleVolumeChange}
                                                                className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[96px] h-6 opacity-0 cursor-pointer z-30"
                                                                style={{ transform: 'translate(-50%, -50%) rotate(-90deg)' }}
                                                            />
                                                        </div>
                                                    </div>
                                                </div>

                                                <span>{formatTime(currentTime)} / {formatTime(duration)}</span>
                                            </div>

                                            {/* Download Button inside controls */}
                                            <button
                                                onClick={handleDownload}
                                                disabled={downloading}
                                                className="flex items-center gap-2 px-3 py-1.5 rounded-lg bg-white/10 hover:bg-emerald-500/20 text-white hover:text-emerald-400 border border-white/5 hover:border-emerald-500/30 transition-all text-xs font-bold"
                                                title="تحميل الفيديو"
                                            >
                                                {downloading ? <Loader2 size={14} className="animate-spin" /> : <Download size={14} />}
                                                تحميل
                                            </button>
                                        </div>
                                    </div>
                                </>
                            )}
                        </div>

                        <div className="bg-[#151515] p-4 flex items-center justify-between border-t border-white/5">
                            <div className="flex items-center gap-3 bg-black/40 px-3 py-1.5 rounded-lg border border-white/5">
                                <Clock size={14} className="text-emerald-400" />
                                <div className="flex items-center gap-2">
                                    <span className="text-[10px] text-gray-400">التالي خلال:</span>
                                    <span className="text-xs font-mono font-bold text-white tracking-widest">{formatCountdown(countdown)}</span>
                                </div>
                            </div>

                            <div className="text-[10px] text-gray-600 font-mono">
                                {/* Server Time Removed */}
                            </div>
                        </div>
                    </div>
                </div>
            );
        };

        // === VIDEO OF THE DAY BUTTON (Header Icon) ===
        const VideoOfTheDayIcon = ({ onOpen }) => {
            return (
                <button
                    aria-label="فيديو اليوم"
                    onClick={onOpen}
                    className="text-gray-500 hover:text-emerald-400 p-2 md:p-1 transition-colors relative group"
                >
                    <Film size={20} className="md:w-[18px] md:h-[18px]" />
                    <span className="absolute top-1 right-1 w-2 h-2 bg-emerald-500 rounded-full animate-pulse border border-[#0f0f11]"></span>
                </button>
            );
        };

        const formatTime = (s) => { if (!s || isNaN(s)) return "00:00"; const m = Math.floor(s / 60), sc = Math.floor(s % 60); return `${m.toString().padStart(2, '0')}:${sc.toString().padStart(2, '0')}` };


        const formatTimePrecise = (s) => { if (s === undefined || isNaN(s)) return "00:00.0"; const m = Math.floor(s / 60), sc = s % 60; return `${m.toString().padStart(2, '0')}:${sc < 10 ? `0${sc.toFixed(1)}` : sc.toFixed(1)}` };
        const toArabicNumerals = (n) => n.toString().replace(/\d/g, d => '٠١٢٣٤٥٦٧٨٩'[d]);
        // دالة تطبيع النص القرآني - تستبدل الحروف والتشكيلات القرآنية الخاصة بالبديل المتوافق مع الخطوط
        // U+06DF (۟) Arabic Small High Rounded Zero -> U+0652 (ْ) Standard Sukun
        // يمكن إضافة المزيد من الاستبدالات هنا إذا لزم الأمر
        const normalizeArabicText = (text) => {
            if (!text) return text;
            return text
                .replace(/\u06ED/g, '')
                .replace(/\u06DF/g, '\u0652') // ۟ -> ْ (sukun)
                .replace(/ۡ/g, '\u0652');     // ۡ (U+06E1) -> ْ (another sukun variant)
        };
        const validateQuranSegments = (segments, range, options = {}) => {
            const result = window.QuranDataValidator?.validateSegments(segments, {
                start: range?.start,
                end: range?.end,
                absoluteTimings: options.absoluteTimings !== false,
                surahList: window.__quranSurahList || []
            });
            if (!result?.ok) {
                const details = (result?.errors || []).slice(0, 3).join('، ');
                throw new Error(`بيانات الآيات غير صالحة${details ? `: ${details}` : ''}`);
            }
            return result.normalized;
        };
        const describeQuranValidationErrors = (errors = []) => {
            const messages = [];
            const add = message => { if (!messages.includes(message)) messages.push(message); };
            errors.forEach(error => {
                const itemMatch = String(error).match(/segments\[(\d+)\]/);
                const itemLabel = itemMatch ? `المقطع رقم ${Number(itemMatch[1]) + 1}: ` : '';
                if (error.includes('text differs from its verified Quran text')) add(`${itemLabel}تم تغيير نص الآية عن النص القرآني الذي أُضيف من المصدر. أعد النص الأصلي أو احذف المقطع وأضف الآية مجددًا.`);
                else if (error.includes('.text is required')) add(`${itemLabel}نص الآية فارغ.`);
                else if (error.includes('.surah is not recognized')) add(`${itemLabel}اسم السورة غير معروف.`);
                else if (error.includes('.ayah exceeds the surah limit') || error.includes('.ayah is invalid')) add(`${itemLabel}رقم الآية غير صالح لهذه السورة.`);
                else if (error.includes('overlaps the previous segment')) add(`${itemLabel}يتداخل توقيته مع المقطع السابق.`);
                else if (error.includes('outside the audio range')) add(`${itemLabel}توقيته خارج الجزء الصوتي المحدد.`);
                else if (error.includes('must have end > start')) add(`${itemLabel}وقت النهاية يجب أن يكون بعد وقت البداية.`);
                else if (error.includes('start/end must be finite numbers')) add(`${itemLabel}وقت البداية أو النهاية غير صالح.`);
                else if (error.includes('must not exceed')) add('عدد المقاطع أكبر من الحد الآمن للمشروع.');
                else if (error.includes('non-empty array')) add('لا توجد آيات صالحة للتصدير.');
            });
            return messages.slice(0, 3).join(' • ') || 'توجد بيانات آيات أو توقيتات غير صالحة. راجع النص والترتيب وحدود الوقت.';
        };
        const repairLegacyOverlaps = (segments) => {
            const repaired = segments.map(segment => ({ ...segment })).sort((a, b) => Number(a.start) - Number(b.start));
            let changed = false;
            for (let i = 1; i < repaired.length; i++) {
                if (Number(repaired[i - 1].end) > Number(repaired[i].start)) {
                    repaired[i - 1].end = Number(repaired[i].start);
                    changed = true;
                }
            }
            return { segments: repaired, changed };
        };
        const prepareDisplaySegments = (segments, range, options = {}) => {
            const source = options.repairLegacyOverlaps ? repairLegacyOverlaps(segments) : { segments, changed: false };
            if (source.changed) console.warn('Legacy Quran timeline overlaps were repaired in memory; source files were not modified.');
            return validateQuranSegments(source.segments, range, options).map((s, i) => ({
            ...s,
            id: Date.now() + i,
            canonicalText: s.text,
            text: normalizeArabicText(s.text)
            }));
        };
        const selectSegmentsForRange = (segments, range) => {
            if (!Array.isArray(segments) || !Number.isFinite(range?.start) || !Number.isFinite(range?.end)) return [];
            return segments
                .filter(segment => Number(segment.end) > range.start && Number(segment.start) < range.end)
                .map(segment => ({
                    ...segment,
                    start: Math.max(Number(segment.start), range.start),
                    end: Math.min(Number(segment.end), range.end)
                }))
                .filter(segment => Number.isFinite(segment.start) && Number.isFinite(segment.end) && segment.end > segment.start);
        };
        const bufferToWav = (abuffer, len) => { let numOfChan = abuffer.numberOfChannels, length = len * numOfChan * 2 + 44, buffer = new ArrayBuffer(length), view = new DataView(buffer), channels = [], i, sample, offset = 0, pos = 0; function setUint16(d) { view.setUint16(pos, d, true); pos += 2 } function setUint32(d) { view.setUint32(pos, d, true); pos += 4 } setUint32(0x46464952); setUint32(length - 8); setUint32(0x45564157); setUint32(0x20746d66); setUint32(16); setUint16(1); setUint16(numOfChan); setUint32(abuffer.sampleRate); setUint32(abuffer.sampleRate * 2 * numOfChan); setUint16(numOfChan * 2); setUint16(16); setUint32(0x61746164); setUint32(length - pos - 4); for (i = 0; i < abuffer.numberOfChannels; i++)channels.push(abuffer.getChannelData(i)); while (pos < len) { for (i = 0; i < numOfChan; i++) { sample = Math.max(-1, Math.min(1, channels[i][pos])); sample = (0.5 + sample < 0 ? sample * 32768 : sample * 32767) | 0; view.setInt16(44 + offset, sample, true); offset += 2 } pos++ } return new Blob([buffer], { type: "audio/wav" }) };
        const extractAudioFromVideo = async (vf, s, e) => { const ctx = new (window.AudioContext || window.webkitAudioContext)(), ab = await vf.arrayBuffer(), audioB = await ctx.decodeAudioData(ab), sr = audioB.sampleRate, ss = Math.floor(s * sr), es = Math.floor(e * sr), fc = es - ss; if (fc <= 0) throw new Error("Invalid duration"); const nb = ctx.createBuffer(audioB.numberOfChannels, fc, sr); for (let i = 0; i < audioB.numberOfChannels; i++)nb.getChannelData(i).set(audioB.getChannelData(i).subarray(ss, es)); return bufferToWav(nb, fc) };

        // --- TOUR CONFIGURATION ---
        const TOUR_STEPS = [
            { id: 'intro', title: 'مرحباً بك في الاستوديو', content: 'جولة سريعة لاكتشاف أدوات الاستوديو الاحترافية.', target: null, tab: 'media' },
            { id: 'tab-media', title: 'قسم الوسائط', content: 'هنا تبدأ باختيار الصوت والفيديو.', target: '[data-tour="tab-media"]', tab: 'media' },
            { id: 'smart', title: 'الاختيار الذكي', content: 'دع الذكاء الاصطناعي يختار لك تلاوة وفيديو متناسقين تلقائياً.', target: '[data-tour="smart-btn"]', tab: 'media' },
            { id: 'lib', title: 'المكتبة الجاهزة', content: 'مجموعة مميزة من الفيديوهات الجاهزة للخلفية.', target: '[data-tour="video-lib-btn"]', tab: 'media' },
            { id: 'tab-content', title: 'قسم المحتوى', content: 'هنا تظهر الآيات ويمكنك تعديل توقيتها.', target: '[data-tour="tab-content"]', tab: 'content', action: 'addDummy' },
            { id: 'markers', title: 'أدوات التوقيت', content: 'استخدم أيقونات الدبوس لضبط بداية ونهاية الآية بدقة عند موقع المؤشر الحالي.', target: '[data-tour="time-markers"]', tab: 'content' },
            { id: 'tab-style', title: 'قسم التصميم', content: 'تحكم في المظهر والألوان.', target: '[data-tour="tab-style"]', tab: 'style' },
            { id: 'watermark', title: 'حقوق النشر', content: 'أضف اسمك أو شعارك.', target: '[data-tour="watermark"]', tab: 'style' },
            { id: 'tab-export', title: 'قسم التصدير', content: 'الإعدادات النهائية والحفظ.', target: '[data-tour="tab-export"]', tab: 'export' },
            { id: 'branding', title: 'شارك في الأجر', content: 'تفعيل هذا الخيار يظهر اسم الموقع، مساهمتك في نشره صدقة جارية.', target: '[data-tour="branding"]', tab: 'export' },
            { id: 'final-alert', title: 'تنبيه هام جداً', content: 'هذا الموقع أداة مساعدة فقط. يجب عليك تدقيق الآيات والتوقيت يدوياً قبل التصدير والنشر لضمان الخلو من الأخطاء.', target: null, tab: 'export' }
        ];

        const OnboardingTour = ({ active, stepIndex, onNext, onPrev, onSkip, setTab, setData, setSettingsCollapsed }) => {
            const [rect, setRect] = useState(null);
            const step = TOUR_STEPS[stepIndex];
            const requestRef = useRef();

            const updatePos = useCallback(() => {
                if (!step.target) { setRect(null); return; }
                const el = document.querySelector(step.target);
                if (el) {
                    const r = el.getBoundingClientRect();
                    setRect({ top: r.top - 4, left: r.left - 4, width: r.width + 8, height: r.height + 8, bottom: r.bottom + 4 });
                }
                if (active) requestRef.current = requestAnimationFrame(updatePos);
            }, [step, active]);

            useEffect(() => {
                if (!active) { cancelAnimationFrame(requestRef.current); return; }
                if (step.tab) setTab(step.tab);
                if (step.action === 'addDummy') {
                    setData(prev => {
                        if (prev.find(p => p.id === 'demo')) return prev;
                        return [{ id: 'demo', text: 'بِسْمِ اللَّهِ الرَّحْمَٰنِ الرَّحِيمِ', start: 0, end: 5, surah: 'الفاتحة', ayah: 1 }, ...prev];
                    });
                }
                if (step.action === 'openSettings' && setSettingsCollapsed) {
                    setSettingsCollapsed(false);
                }
                // Small delay to allow settings to expand before scrolling
                setTimeout(() => {
                    const el = document.querySelector(step.target);
                    if (el) { el.scrollIntoView({ behavior: 'smooth', block: 'center' }); }
                }, step.action === 'openSettings' ? 300 : 0);
                requestRef.current = requestAnimationFrame(updatePos);
                return () => cancelAnimationFrame(requestRef.current);
            }, [stepIndex, active, setTab, step, updatePos, setSettingsCollapsed]);

            useEffect(() => { if (!active) { setData(prev => prev.filter(p => p.id !== 'demo')); } }, [active, setData]);

            if (!active) return null;

            // Smart Positioning Logic with Transform
            let tooltipStyle = { top: '35%' };

            if (rect) {
                const screenHeight = window.innerHeight;
                const isBottomHalf = rect.top > screenHeight * 0.55; // Adjusted threshold

                if (isBottomHalf) {
                    // Position above
                    tooltipStyle = {
                        top: rect.top - 15,
                        transform: 'translateY(-100%)'
                    };
                } else {
                    // Position below
                    tooltipStyle = {
                        top: rect.bottom + 15,
                        transform: 'none'
                    };
                }
            }

            return (
                <div className="fixed inset-0 z-[100] overflow-hidden">
                    {rect ? (
                        <div className="tour-highlight" style={{ top: rect.top, left: rect.left, width: rect.width, height: rect.height }}></div>
                    ) : (
                        <div className="absolute inset-0 bg-black/50 backdrop-blur-sm transition-all duration-300"></div>
                    )}
                    <div className="tour-tooltip-container" style={tooltipStyle}>
                        <div className="tour-card border border-emerald-500/40 rounded-2xl p-6 shadow-2xl max-w-sm w-full mx-4 relative overflow-hidden animate-in zoom-in-95 duration-200">
                            <div className="absolute top-0 right-0 w-full h-1 bg-gray-700">
                                <div className="h-full bg-emerald-500 transition-all duration-300 ease-out" style={{ width: `${((stepIndex + 1) / TOUR_STEPS.length) * 100}%` }}></div>
                            </div>
                            <h3 className="text-lg font-bold text-white mb-2 flex items-center gap-2 mt-2">
                                {step.id === 'intro' ? <Sparkles size={20} className="text-yellow-400 animate-pulse" /> : (step.id === 'final-alert' ? <ShieldAlert size={18} className="text-red-400" /> : <LayoutTemplate size={18} className="text-emerald-400" />)}
                                {step.title}
                            </h3>
                            <p className="text-gray-300 text-sm leading-relaxed mb-6 font-light">{step.content}</p>
                            <div className="flex justify-between items-center pt-2 border-t border-white/5">
                                <button onClick={onSkip} className="text-gray-500 hover:text-white text-xs font-medium transition-colors px-2" aria-label="تخطي الجولة">إنهاء</button>
                                <div className="flex gap-2" dir="ltr">
                                    {stepIndex > 0 && <button onClick={onPrev} aria-label="السابق" className="p-2 rounded-lg bg-white/5 hover:bg-white/10 text-white border border-white/10 transition-colors"><ChevronRight size={18} /></button>}
                                    <button onClick={onNext} aria-label="التالي" className="px-5 py-2 rounded-lg bg-emerald-600 hover:bg-emerald-500 text-white text-sm font-bold shadow-lg shadow-emerald-900/20 flex items-center gap-2 transition-all transform hover:translate-y-[-1px]">
                                        {stepIndex === TOUR_STEPS.length - 1 ? 'موافق' : 'التالي'}
                                        {stepIndex !== TOUR_STEPS.length - 1 && <ChevronLeft size={16} />}
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            );
        };

        // Reusable Range Slider with Colored Fill
        const RangeSlider = ({ min = 0, max = 1, step = 0.05, value, onChange, className = "" }) => {
            const percentage = ((value - min) / (max - min)) * 100;
            const trackStyle = {
                background: `linear-gradient(to right, #10b981 ${percentage}%, #374151 ${percentage}%)`
            };
            return (
                <input
                    type="range"
                    dir="ltr"
                    min={min}
                    max={max}
                    step={step}
                    value={value}
                    onChange={onChange}
                    className={`w-full h-1 rounded-lg appearance-none cursor-pointer filled-slider ${className}`}
                    style={trackStyle}
                />
            );
        };

        // Professional Color Picker Component
        const ColorPicker = ({ value, onChange, label }) => {
            return (
                <div className="flex justify-between items-center">
                    <span className="text-xs text-gray-300">{label}</span>
                    <label className="relative cursor-pointer">
                        <div
                            className="w-8 h-8 rounded-lg border-2 border-white/30 shadow-md hover:border-emerald-500 hover:scale-110 transition-all duration-200"
                            style={{ backgroundColor: value }}
                        />
                        <input
                            type="color"
                            value={value}
                            onChange={onChange}
                            className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
                        />
                    </label>
                </div>
            );
        };

        // Professional Toggle Switch Component with Animation
        const Toggle = ({ checked, onChange, label }) => {
            return (
                <div className="flex justify-between items-center">
                    <span className="text-xs text-gray-300">{label}</span>
                    <button
                        onClick={() => onChange({ target: { checked: !checked } })}
                        className={`relative w-11 h-6 rounded-full transition-all duration-300 ease-out focus:outline-none focus:ring-2 focus:ring-emerald-500/50 ${checked ? 'bg-emerald-500' : 'bg-gray-600'}`}
                    >
                        <div
                            className={`absolute top-1 w-4 h-4 bg-white rounded-full shadow-md transition-all duration-300 ease-out ${checked ? 'left-6 scale-110' : 'left-1 scale-100'}`}
                        />
                        <div className={`absolute inset-0 rounded-full transition-opacity duration-300 ${checked ? 'bg-gradient-to-r from-emerald-400 to-emerald-600 opacity-100' : 'opacity-0'}`} />
                        <div
                            className={`absolute top-1 w-4 h-4 bg-white rounded-full shadow-lg transition-all duration-300 ease-out ${checked ? 'left-6' : 'left-1'}`}
                            style={{ boxShadow: checked ? '0 0 8px rgba(16, 185, 129, 0.5)' : 'none' }}
                        />
                    </button>
                </div>
            );
        };

        const TimeInput = ({ time, onChange, className }) => { const [val, setVal] = useState(formatTimePrecise(time)), [isFocused, setIsFocused] = useState(false); useEffect(() => { if (!isFocused) setVal(formatTimePrecise(time)) }, [time, isFocused]); const handleBlur = () => { setIsFocused(false); const parts = val.split(':'); let sec = parts.length === 2 ? parseInt(parts[0]) * 60 + parseFloat(parts[1]) : parseFloat(val); if (!isNaN(sec)) { onChange(sec); setVal(formatTimePrecise(sec)) } else setVal(formatTimePrecise(time)) }; return <input type="text" className={className} value={val} onChange={e => setVal(e.target.value)} onFocus={() => setIsFocused(true)} onBlur={handleBlur} onKeyDown={e => e.key === 'Enter' && e.target.blur()} dir="ltr" placeholder="00:00.0" /> };

        const WaveformSeeker = ({ currentTime, duration, onSeek, audioSrc }) => {
            const canvasRef = useRef(null);
            const [waveData, setWaveData] = useState([]);
            const [isAnalyzing, setIsAnalyzing] = useState(false);
            const analyzedSrcRef = useRef(null);

            // Cache for waveform data to prevent re-decoding
            const peakCache = useRef(new Map());

            // تحليل الصوت واستخراج الموجات الحقيقية - مع حماية من تسريب الذاكرة
            useEffect(() => {
                if (!audioSrc) {
                    setWaveData([]);
                    analyzedSrcRef.current = null;
                    return;
                }

                // Check cache first
                if (peakCache.current.has(audioSrc)) {
                    setWaveData(peakCache.current.get(audioSrc));
                    analyzedSrcRef.current = audioSrc;
                    setIsAnalyzing(false);
                    return;
                }

                // تجنب إعادة التحليل لنفس الملف إذا كان هو الحالي
                if (analyzedSrcRef.current === audioSrc) return;

                const abortController = new AbortController();
                let localAudioContext = null;
                let isMounted = true;

                const analyzeAudio = async () => {
                    setIsAnalyzing(true);
                    try {
                        const response = await fetch(audioSrc, { signal: abortController.signal });
                        if (!isMounted) return;

                        const arrayBuffer = await response.arrayBuffer();
                        if (!isMounted) return;

                        // Use OfflineAudioContext for decoding if available (more stable/faster for non-playback)
                        const AudioCtxClass = window.AudioContext || window.webkitAudioContext;
                        localAudioContext = new AudioCtxClass();

                        const audioBuffer = await localAudioContext.decodeAudioData(arrayBuffer);

                        if (!isMounted) {
                            if (localAudioContext.state !== 'closed') try { await localAudioContext.close(); } catch (e) { }
                            return;
                        }

                        // استخراج بيانات القناة الأولى
                        const rawData = audioBuffer.getChannelData(0);
                        const samples = 100; // Increased resolution for better precision
                        const blockSize = Math.floor(rawData.length / samples);
                        const peaks = [];

                        // حساب peak amplitude لكل قطاع
                        for (let i = 0; i < samples; i++) {
                            let max = 0;
                            const start = i * blockSize;
                            // Optimize loop: step by larger increments to save CPU on large files
                            const step = Math.ceil(blockSize / 10) || 1;
                            for (let j = 0; j < blockSize; j += step) {
                                const val = Math.abs(rawData[start + j]);
                                if (val > max) max = val;
                            }
                            peaks.push(max);
                        }

                        // تطبيع القيم (0.2 - 1.0)
                        const maxPeak = Math.max(...peaks, 0.01);
                        const normalized = peaks.map(p => 0.2 + (p / maxPeak) * 0.8);

                        // Update Cache
                        peakCache.current.set(audioSrc, normalized);

                        if (isMounted) {
                            setWaveData(normalized);
                            analyzedSrcRef.current = audioSrc;
                        }
                    } catch (error) {
                        if (error.name === 'AbortError') return;
                        console.warn('فشل تحليل الصوت:', error);
                        // Fallback للبيانات العشوائية
                        if (isMounted) {
                            // Cache fallback too to prevent retry loops
                            const emptyData = Array.from({ length: 80 }, () => Math.random() * 0.6 + 0.3);
                            peakCache.current.set(audioSrc, emptyData);
                            setWaveData(emptyData);
                            analyzedSrcRef.current = audioSrc;
                        }
                    } finally {
                        if (localAudioContext && localAudioContext.state !== 'closed') {
                            try { await localAudioContext.close(); } catch (e) { }
                        }
                        if (isMounted) {
                            setIsAnalyzing(false);
                        }
                    }
                };

                analyzeAudio();

                return () => {
                    isMounted = false;
                    abortController.abort();
                };
            }, [audioSrc]);

            // رسم الموجات على Canvas
            const draw = useCallback(() => {
                const c = canvasRef.current;
                if (!c) return;

                const ctx = c.getContext('2d');
                const { width, height } = c.getBoundingClientRect();
                const dpr = window.devicePixelRatio || 1;

                c.width = width * dpr;
                c.height = height * dpr;
                ctx.scale(dpr, dpr);

                let sourceData = waveData.length > 0 ? waveData : Array.from({ length: 100 }, () => 0.3);

                // Smart Downsampling Logic:
                // Desktop: 90-100 bars | Mobile: 45-50 bars
                // Calculation: Min bar width (5px) + gap (3px) = 8px per unit
                const gap = 3;
                const minUnitWidth = 8;
                const maxBarsPossible = Math.floor(width / minUnitWidth);
                const targetBars = Math.min(sourceData.length, maxBarsPossible);

                let dataToRender = sourceData;
                if (sourceData.length > targetBars) {
                    const step = sourceData.length / targetBars;
                    dataToRender = Array.from({ length: targetBars }, (_, i) => sourceData[Math.floor(i * step)]);
                }

                const bw = (width - (dataToRender.length - 1) * gap) / dataToRender.length;
                const prog = duration > 0 ? currentTime / duration : 0;

                ctx.clearRect(0, 0, width, height);

                dataToRender.forEach((amp, i) => {
                    const x = i * (bw + gap);
                    const bh = height * amp;
                    const y = (height - bh) / 2;
                    const isPlayed = (i / dataToRender.length) < prog;

                    ctx.fillStyle = isPlayed ? '#10b981' : '#374151';
                    ctx.shadowColor = isPlayed ? 'rgba(16,185,129,0.5)' : 'transparent';
                    ctx.shadowBlur = isPlayed ? 10 : 0;
                    ctx.beginPath();
                    if (ctx.roundRect) ctx.roundRect(x, y, bw, bh, 2);
                    else ctx.rect(x, y, bw, bh);
                    ctx.fill();
                });
            }, [currentTime, duration, waveData]);

            useEffect(() => {
                draw();
                window.addEventListener('resize', draw);
                return () => window.removeEventListener('resize', draw);
            }, [draw]);

            const handleInteract = (e) => {
                const r = canvasRef.current.getBoundingClientRect();
                const x = e.clientX - r.left;
                const ratio = Math.max(0, Math.min(1, x / r.width));
                onSeek(ratio * duration);
            };

            return (
                <div className="w-full h-12 flex items-center justify-center relative group" dir="ltr">
                    {isAnalyzing && (
                        <div className="absolute inset-0 flex items-center justify-center bg-gray-900/50 rounded z-10">
                            <div className="w-4 h-4 border-2 border-emerald-500 border-t-transparent rounded-full animate-spin" />
                        </div>
                    )}
                    <canvas
                        ref={canvasRef}
                        className="w-full h-full cursor-pointer touch-none"
                        onPointerDown={e => { handleInteract(e); e.target.setPointerCapture(e.pointerId) }}
                        onPointerMove={e => { if (e.buttons === 1) handleInteract(e) }}
                    />
                </div>
            );
        };


        const TrimmerModal = ({ file, type, onClose, onConfirm, isExtractingMode, previewVolume }) => {
            const [dur, setDur] = useState(0), [range, setRange] = useState({ start: 0, end: 15 }), [play, setPlay] = useState(false), [currTime, setCurrTime] = useState(0);
            const mediaRef = useRef(null), trackRef = useRef(null), rafRef = useRef(null), [dragMode, setDragMode] = useState(null), dragData = useRef({ startX: 0, initialRange: { start: 0, end: 0 } });

            useEffect(() => {
                let u = null;
                let disposed = false;
                const media = mediaRef.current;
                if (media) {
                    u = typeof file === 'string' ? file : URL.createObjectURL(file);
                    media.src = u;
                    media.onloadedmetadata = () => {
                        if (disposed) return;
                        const d = media.duration;
                        setDur(d);
                        setRange({ start: 0, end: Math.min(d, 60) })
                    }
                }
                return () => {
                    disposed = true;
                    // Detach the element before revoking its temporary URL.
                    // This prevents a pending Android media request from trying
                    // to read an already-revoked blob during modal transitions.
                    if (media) {
                        try { media.pause(); } catch (e) { }
                        media.onloadedmetadata = null;
                        media.removeAttribute('src');
                        try { media.load(); } catch (e) { }
                    }
                    if (u && typeof file !== 'string') {
                        URL.revokeObjectURL(u);
                    }
                };
            }, [file]);

            // Loop & Smooth Update Logic via requestAnimationFrame
            const updateLoop = () => {
                if (!mediaRef.current) return;
                setCurrTime(mediaRef.current.currentTime);

                if (mediaRef.current.currentTime >= range.end) {
                    mediaRef.current.currentTime = range.start;
                    if (mediaRef.current.paused && play) mediaRef.current.play().catch(console.log);
                }

                if (play) {
                    rafRef.current = requestAnimationFrame(updateLoop);
                }
            };

            useEffect(() => {
                if (play) {
                    rafRef.current = requestAnimationFrame(updateLoop);
                } else {
                    if (rafRef.current) cancelAnimationFrame(rafRef.current);
                }
                return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current); };
            }, [play, range]); // Depend on range to check end time correctly in loop

            // Apply global volume
            useEffect(() => { if (mediaRef.current && previewVolume !== undefined) { mediaRef.current.volume = previewVolume; } }, [previewVolume, play]);

            const handlePD = (e, m) => { e.preventDefault(); e.stopPropagation(); if (mediaRef.current && !mediaRef.current.paused) mediaRef.current.pause(); const cx = e.touches ? e.touches[0].clientX : e.clientX; setDragMode(m); dragData.current = { startX: cx, initialRange: { ...range } } };

            // Seek Logic attached to the Ruler
            const handleSeek = (e) => {
                if (!trackRef.current || dur === 0) return;
                const rect = trackRef.current.getBoundingClientRect();
                const cx = e.touches ? e.touches[0].clientX : e.clientX;
                const ratio = Math.max(0, Math.min(1, (cx - rect.left) / rect.width));
                const newTime = ratio * dur;
                setCurrTime(newTime);
                if (mediaRef.current) mediaRef.current.currentTime = newTime;
            };

            useEffect(() => {
                if (!dragMode) return; const hM = (e) => {
                    if (!trackRef.current || dur === 0) return; e.preventDefault(); const cx = e.touches ? e.touches[0].clientX : e.clientX, rect = trackRef.current.getBoundingClientRect();
                    // LTR Calculation: Delta is Current - Start
                    const dX = cx - dragData.current.startX;
                    const dT = (dX / rect.width) * dur;
                    const { start: iS, end: iE } = dragData.current.initialRange; let nS = range.start, nE = range.end; if (dragMode === 'start') { nS = Math.max(0, Math.min(iS + dT, iE - 0.5)); if (iE - nS > 60) nS = iE - 60 } else if (dragMode === 'end') { nE = Math.min(dur, Math.max(iE + dT, iS + 0.5)); if (nE - iS > 60) nE = iS + 60 } else if (dragMode === 'move') { const s = iE - iS; nS = iS + dT; nE = iE + dT; if (nS < 0) { nS = 0; nE = s } if (nE > dur) { nE = dur; nS = dur - s } }

                    // --- SNAP LOGIC ---
                    const SNAP_TOLERANCE = dur * 0.02; // Snap within 2% of timeline
                    if (dragMode === 'start') {
                        if (Math.abs(nS - currTime) < SNAP_TOLERANCE) nS = currTime;
                    } else if (dragMode === 'end') {
                        if (Math.abs(nE - currTime) < SNAP_TOLERANCE) nE = currTime;
                    }

                    setRange({ start: nS, end: nE }); if (mediaRef.current) { if (dragMode !== 'end') mediaRef.current.currentTime = nS; else mediaRef.current.currentTime = nE }
                }, hU = () => setDragMode(null); window.addEventListener('mousemove', hM); window.addEventListener('mouseup', hU); window.addEventListener('touchmove', hM, { passive: false }); window.addEventListener('touchend', hU); return () => { window.removeEventListener('mousemove', hM); window.removeEventListener('mouseup', hU); window.removeEventListener('touchmove', hM); window.removeEventListener('touchend', hU) }
            }, [dragMode, dur, range, currTime]);

            const togglePreview = async () => { const m = mediaRef.current; if (!m) return; if (m.paused) { if (m.currentTime < range.start || m.currentTime >= range.end) m.currentTime = range.start; await m.play() } else m.pause() };
            const sPct = (range.start / dur) * 100, wPct = ((range.end - range.start) / dur) * 100, ePct = sPct + wPct, currPct = (currTime / dur) * 100;

            return (
                <div className="fixed inset-0 z-[60] bg-black/90 flex items-center justify-center p-4 backdrop-blur-md" role="dialog" aria-modal="true" aria-labelledby="media-trimmer-title">
                    <div className="bg-[#111] border border-white/10 rounded-2xl w-full max-w-3xl p-6 shadow-2xl flex flex-col h-full md:h-auto md:max-h-[90vh] overflow-y-auto custom-scrollbar">
                        <div className="flex justify-between items-center mb-4 shrink-0"><h3 id="media-trimmer-title" className="text-lg font-bold flex items-center gap-2"><Scissors size={20} className="text-emerald-500" /> {isExtractingMode ? 'قص واستخراج الصوت' : 'محرر الوسائط'}</h3><button onClick={onClose} aria-label="إغلاق" className="p-2 bg-white/5 hover:bg-white/10 rounded-full transition"><X size={20} /></button></div>
                        <div className="bg-black rounded-xl overflow-hidden aspect-video mb-6 relative border border-white/5 flex items-center justify-center shrink-0">
                            {type === 'video' ? <video ref={mediaRef} className="w-full h-full object-contain" onPlay={() => setPlay(true)} onPause={() => setPlay(false)} onEnded={() => setPlay(false)} /> : <div className="text-center"><Music size={64} className="mx-auto text-emerald-500 mb-4 animate-pulse-slow" /><audio ref={mediaRef} onPlay={() => setPlay(true)} onPause={() => setPlay(false)} onEnded={() => setPlay(false)} /><p className="text-gray-400 font-mono text-sm">معاينة الملف الصوتي</p></div>}
                        </div>
                        <div className="space-y-6 shrink-0 pb-1" dir="ltr">
                            {/* Stats Info - Forced LTR Layout */}
                            <div className="flex justify-between items-end font-mono text-sm px-1">
                                <div className="text-left text-emerald-400"><span className="text-xs text-gray-500 block text-right font-sans">البداية</span>{formatTimePrecise(range.start)}</div>
                                <div className={`text-center ${range.end - range.start > 60 ? "text-red-500" : "text-white"} font-bold`}><span className="text-xs text-gray-500 block mb-1 font-sans">الموقع الحالي</span>{formatTimePrecise(currTime)}</div>
                                <div className="text-right text-emerald-400"><span className="text-xs text-gray-500 block text-left font-sans">النهاية</span>{formatTimePrecise(range.end)}</div>
                            </div>

                            {/* Enhanced Track Area - STRICT LTR */}
                            <div className="relative h-20 select-none group touch-none pt-6" ref={trackRef}>
                                {/* Timeline Ruler / Click Zone */}
                                <div
                                    className="absolute top-0 left-0 right-0 h-6 bg-gray-800/50 cursor-pointer z-50 flex items-end overflow-hidden hover:bg-gray-700/50 transition-colors rounded-t-lg border-b border-white/10"
                                    onPointerDown={handleSeek}
                                    onPointerMove={(e) => { if (e.buttons === 1) handleSeek(e); }}
                                >
                                    {/* Ruler Ticks */}
                                    <div className="absolute inset-x-0 bottom-0 h-2 w-full" style={{ backgroundImage: 'repeating-linear-gradient(90deg, rgba(255,255,255,0.3) 0, rgba(255,255,255,0.3) 1px, transparent 1px, transparent 10px)' }}></div>
                                </div>

                                {/* Current Playhead (Vertical Line) - Left positioned */}
                                <div className="absolute top-0 bottom-0 w-0.5 bg-white z-[60] pointer-events-none shadow-[0_0_10px_rgba(255,255,255,0.8)]" style={{ left: `${currPct}%` }}>
                                    <div className="absolute -top-1 -left-[5px] w-3 h-3 bg-white rotate-45 transform rounded-xs shadow-sm"></div>
                                </div>

                                {/* Track Background */}
                                <div className="absolute inset-0 top-6 bg-gray-800 rounded-b-lg overflow-hidden border border-white/5"><div className="w-full h-full opacity-10" style={{ backgroundImage: 'repeating-linear-gradient(90deg, transparent, transparent 19px, #fff 20px)' }}></div></div>

                                {/* Selection Region - Left positioned */}
                                <div className="absolute top-6 bottom-0 bg-emerald-500/20 border-y-2 border-emerald-500 cursor-grab active:cursor-grabbing z-10 group-hover:bg-emerald-500/30 transition-colors" style={{ left: `${sPct}%`, width: `${wPct}%` }} onMouseDown={e => handlePD(e, 'move')} onTouchStart={e => handlePD(e, 'move')}><div className="absolute inset-0 flex items-center justify-center opacity-0 hover:opacity-50 pointer-events-none transition-opacity"><Move size={16} className="text-white" /></div></div>

                                {/* Handles (CORRECTED CENTERING & LTR) */}
                                {/* Start Handle (Left Side) -> needs translateX(-100%) to look correct (sitting on the outside left of the cut) */}
                                <div className="absolute top-6 bottom-0 w-6 bg-emerald-500 rounded-l-md cursor-ew-resize z-20 flex items-center justify-center hover:brightness-110 shadow-lg -translate-x-full touch-none" style={{ left: `${sPct}%` }} onMouseDown={e => handlePD(e, 'start')} onTouchStart={e => handlePD(e, 'start')}><div className="h-4 w-0.5 bg-black/30 rounded-full mx-[1px]"></div><div className="h-4 w-0.5 bg-black/30 rounded-full mx-[1px]"></div></div>

                                {/* End Handle (Right Side) -> needs translateX(0) to sits on the outside right of the cut (default for left-positioned element) */}
                                <div className="absolute top-6 bottom-0 w-6 bg-emerald-500 rounded-r-md cursor-ew-resize z-20 flex items-center justify-center hover:brightness-110 shadow-lg translate-x-0 touch-none" style={{ left: `${ePct}%` }} onMouseDown={e => handlePD(e, 'end')} onTouchStart={e => handlePD(e, 'end')}><div className="h-4 w-0.5 bg-black/30 rounded-full mx-[1px]"></div><div className="h-4 w-0.5 bg-black/30 rounded-full mx-[1px]"></div></div>

                                {/* Darkened Outside Regions - Left positioned */}
                                <div className="absolute top-6 bottom-0 left-0 bg-black/60 pointer-events-none rounded-l-lg" style={{ width: `${sPct}%` }}></div><div className="absolute top-6 bottom-0 right-0 bg-black/60 pointer-events-none rounded-r-lg" style={{ width: `${100 - ePct}%` }}></div>
                            </div>
                            <div className="flex gap-3 pt-2" dir="rtl">
                                <button onClick={togglePreview} aria-label="معاينة" className="flex-1 py-4 rounded-xl bg-white/5 hover:bg-white/10 border border-white/5 font-bold transition flex items-center justify-center gap-2 text-white">{play ? <><Pause size={20} /> إيقاف</> : <><Play size={20} /> معاينة</>}</button>
                                <button onClick={() => { mediaRef.current.pause(); onConfirm(range) }} aria-label="تأكيد" className="flex-[2] py-4 rounded-xl bg-gradient-to-r from-emerald-600 to-emerald-500 hover:from-emerald-500 hover:to-emerald-400 text-black font-bold transition flex items-center justify-center gap-2 shadow-lg">{isExtractingMode ? <><Cpu size={20} /> قص واستخراج</> : <><Check size={20} /> قص واعتماد</>}</button>
                            </div>
                        </div>
                    </div>
                </div>
            );
        };

        const CompositionTrimmerModal = ({ duration, initialRange, onConfirm, onClose, canvasRef, isPlaying, onTogglePlayback, setPreviewTime, currentTime }) => {
            const [range, setRange] = useState(initialRange || { start: 0, end: duration });
            const [currTime, setCurrTime] = useState(currentTime || 0);
            const trackRef = useRef(null);
            const [dragMode, setDragMode] = useState(null);
            const dragData = useRef({ startX: 0, initialRange: { start: 0, end: 0 } });
            const previewCanvasRef = useRef(null);

            // Sync currTime for display, but trust parent loop for logic
            useEffect(() => { setCurrTime(currentTime); }, [currentTime]);

            // Loop Logic: Watch currentTime vs Range. If out of bounds during play, seek to start.
            useEffect(() => {
                if (isPlaying) {
                    if (currTime >= range.end - 0.1 || currTime < range.start) {
                        setPreviewTime(range.start);
                    }
                }
            }, [currTime, isPlaying, range, setPreviewTime]);

            // Preview Render Loop
            useEffect(() => {
                let rafId;
                const render = () => {
                    const src = canvasRef.current;
                    const dest = previewCanvasRef.current;
                    if (src && dest) {
                        const ctx = dest.getContext('2d');
                        if (dest.width !== src.width) dest.width = src.width;
                        if (dest.height !== src.height) dest.height = src.height;
                        ctx.drawImage(src, 0, 0, dest.width, dest.height);
                    }
                    rafId = requestAnimationFrame(render);
                };
                render();
                return () => cancelAnimationFrame(rafId);
            }, [canvasRef]);

            const handlePD = (e, m) => {
                e.preventDefault();
                e.stopPropagation();
                if (isPlaying) onTogglePlayback(); // Pause on drag start
                const cx = e.touches ? e.touches[0].clientX : e.clientX;
                setDragMode(m);
                dragData.current = { startX: cx, initialRange: { ...range } }
            };

            const handleSeek = (e) => {
                if (!trackRef.current || duration === 0) return;
                const rect = trackRef.current.getBoundingClientRect();
                const cx = e.touches ? e.touches[0].clientX : e.clientX;
                const ratio = Math.max(0, Math.min(1, (cx - rect.left) / rect.width));
                const newTime = ratio * duration;
                setPreviewTime(newTime);
            };

            useEffect(() => {
                if (!dragMode) return;
                const hM = (e) => {
                    if (!trackRef.current || duration === 0) return;
                    e.preventDefault();

                    const cx = e.touches ? e.touches[0].clientX : e.clientX, rect = trackRef.current.getBoundingClientRect();
                    const dX = cx - dragData.current.startX;
                    const dT = (dX / rect.width) * duration;
                    const { start: iS, end: iE } = dragData.current.initialRange;
                    let nS = range.start, nE = range.end;

                    if (dragMode === 'start') { nS = Math.max(0, Math.min(iS + dT, iE - 1)); }
                    else if (dragMode === 'end') { nE = Math.min(duration, Math.max(iE + dT, iS + 1)); }
                    else if (dragMode === 'move') {
                        const s = iE - iS;
                        nS = iS + dT;
                        nE = iE + dT;
                        if (nS < 0) { nS = 0; nE = s }
                        if (nE > duration) { nE = duration; nS = duration - s }
                    }

                    // --- SNAP LOGIC ---
                    const SNAP_TOLERANCE = duration * 0.02; // Snap within 2% of timeline
                    if (dragMode === 'start') {
                        if (Math.abs(nS - currTime) < SNAP_TOLERANCE) nS = currTime;
                    } else if (dragMode === 'end') {
                        if (Math.abs(nE - currTime) < SNAP_TOLERANCE) nE = currTime;
                    }

                    setRange({ start: nS, end: nE });


                };

                const hU = () => setDragMode(null);

                window.addEventListener('mousemove', hM);
                window.addEventListener('mouseup', hU);
                window.addEventListener('touchmove', hM, { passive: false });
                window.addEventListener('touchend', hU);
                return () => {
                    window.removeEventListener('mousemove', hM);
                    window.removeEventListener('mouseup', hU);
                    window.removeEventListener('touchmove', hM);
                    window.removeEventListener('touchend', hU)
                }
            }, [dragMode, duration, range, setPreviewTime]);

            const sPct = (range.start / duration) * 100, wPct = ((range.end - range.start) / duration) * 100, ePct = sPct + wPct, currPct = (currTime / duration) * 100;

            return (
                <div className="fixed inset-0 z-[60] bg-black/90 flex items-center justify-center p-4 backdrop-blur-md">
                    <div className="bg-[#111] border border-white/10 rounded-2xl w-full max-w-3xl p-6 shadow-2xl flex flex-col h-full md:h-auto md:max-h-[90vh] overflow-y-auto custom-scrollbar">
                        <div className="flex justify-between items-center mb-4 shrink-0"><h3 className="text-lg font-bold flex items-center gap-2"><Scissors size={20} className="text-emerald-500" /> قص الفيديو النهائي</h3><button onClick={onClose} aria-label="إغلاق" className="p-2 bg-white/5 hover:bg-white/10 rounded-full transition"><X size={20} /></button></div>
                        <div className="bg-black rounded-xl overflow-hidden aspect-[9/16] h-[50vh] mx-auto mb-6 relative border border-white/5 flex items-center justify-center shrink-0 shadow-2xl"><canvas ref={previewCanvasRef} className="h-full w-full object-contain" /></div>
                        <div className="space-y-6 shrink-0 pb-1" dir="ltr">
                            <div className="flex justify-between items-end font-mono text-sm px-1"><div className="text-left text-emerald-400"><span className="text-xs text-gray-500 block text-right font-sans">البداية</span>{formatTimePrecise(range.start)}</div><div className={`text-center font-bold text-white`}><span className="text-xs text-gray-500 block mb-1 font-sans">الموقع الحالي</span>{formatTimePrecise(currTime)}</div><div className="text-right text-emerald-400"><span className="text-xs text-gray-500 block text-left font-sans">النهاية</span>{formatTimePrecise(range.end)}</div></div>
                            <div className="relative h-20 select-none group touch-none pt-6" ref={trackRef}>
                                <div className="absolute top-0 left-0 right-0 h-6 bg-gray-800/50 cursor-pointer z-50 flex items-end overflow-hidden hover:bg-gray-700/50 transition-colors rounded-t-lg border-b border-white/10" onPointerDown={handleSeek} onPointerMove={(e) => { if (e.buttons === 1) handleSeek(e); }}><div className="absolute inset-x-0 bottom-0 h-2 w-full" style={{ backgroundImage: 'repeating-linear-gradient(90deg, rgba(255,255,255,0.3) 0, rgba(255,255,255,0.3) 1px, transparent 1px, transparent 10px)' }}></div></div>
                                <div className="absolute top-0 bottom-0 w-0.5 bg-white z-[60] pointer-events-none shadow-[0_0_10px_rgba(255,255,255,0.8)]" style={{ left: `${currPct}%` }}> <div className="absolute -top-1 -left-[5px] w-3 h-3 bg-white rotate-45 transform rounded-xs shadow-sm"></div></div>
                                <div className="absolute inset-0 top-6 bg-gray-800 rounded-b-lg overflow-hidden border border-white/5"><div className="w-full h-full opacity-10" style={{ backgroundImage: 'repeating-linear-gradient(90deg, transparent, transparent 19px, #fff 20px)' }}></div></div>
                                <div className="absolute top-6 bottom-0 bg-emerald-500/20 border-y-2 border-emerald-500 cursor-grab active:cursor-grabbing z-10 group-hover:bg-emerald-500/30 transition-colors" style={{ left: `${sPct}%`, width: `${wPct}%` }} onMouseDown={e => handlePD(e, 'move')} onTouchStart={e => handlePD(e, 'move')}><div className="absolute inset-0 flex items-center justify-center opacity-0 hover:opacity-50 pointer-events-none transition-opacity"><Move size={16} className="text-white" /></div></div>
                                <div className="absolute top-6 bottom-0 w-6 bg-emerald-500 rounded-l-md cursor-ew-resize z-20 flex items-center justify-center hover:brightness-110 shadow-lg -translate-x-full touch-none" style={{ left: `${sPct}%` }} onMouseDown={e => handlePD(e, 'start')} onTouchStart={e => handlePD(e, 'start')}><div className="h-4 w-0.5 bg-black/30 rounded-full mx-[1px]"></div><div className="h-4 w-0.5 bg-black/30 rounded-full mx-[1px]"></div></div>
                                <div className="absolute top-6 bottom-0 w-6 bg-emerald-500 rounded-r-md cursor-ew-resize z-20 flex items-center justify-center hover:brightness-110 shadow-lg translate-x-0 touch-none" style={{ left: `${ePct}%` }} onMouseDown={e => handlePD(e, 'end')} onTouchStart={e => handlePD(e, 'end')}><div className="h-4 w-0.5 bg-black/30 rounded-full mx-[1px]"></div><div className="h-4 w-0.5 bg-black/30 rounded-full mx-[1px]"></div></div>
                                <div className="absolute top-6 bottom-0 left-0 bg-black/60 pointer-events-none rounded-l-lg" style={{ width: `${sPct}%` }}></div><div className="absolute top-6 bottom-0 right-0 bg-black/60 pointer-events-none rounded-r-lg" style={{ width: `${100 - ePct}%` }}></div>
                            </div>
                            <div className="flex gap-3 pt-2" dir="rtl">
                                <button onClick={onTogglePlayback} aria-label="معاينة" className="flex-1 py-4 rounded-xl bg-white/5 hover:bg-white/10 border border-white/5 font-bold transition flex items-center justify-center gap-2 text-white">{isPlaying ? <><Pause size={20} /> إيقاف</> : <><Play size={20} /> معاينة</>}</button>
                                <button onClick={() => onConfirm(range)} aria-label="تأكيد" className="flex-[2] py-4 rounded-xl bg-gradient-to-r from-emerald-600 to-emerald-500 hover:from-emerald-500 hover:to-emerald-400 text-black font-bold transition flex items-center justify-center gap-2 shadow-lg"><Check size={20} /> تطبيق وقص</button>
                            </div>
                        </div>
                    </div>
                </div>
            );
        };

        const LazyGrid = ({ items, renderItem, gridClassName, initialCount = 20, batchSize = 20, fallbackText = "لا توجد عناصر" }) => {
            const [displayedCount, setDisplayedCount] = useState(initialCount);
            const sentinelRef = useRef(null);

            // Reset when items change
            useEffect(() => {
                setDisplayedCount(initialCount);
            }, [items, initialCount]);

            useEffect(() => {
                if (displayedCount >= items.length) return;

                const observer = new IntersectionObserver((entries) => {
                    if (entries[0].isIntersecting) {
                        setDisplayedCount(prev => Math.min(prev + batchSize, items.length));
                    }
                }, { threshold: 0.1, rootMargin: '100px' });

                if (sentinelRef.current) observer.observe(sentinelRef.current);
                return () => observer.disconnect();
            }, [displayedCount, items.length, batchSize]);

            const displayedItems = items.slice(0, displayedCount);

            if (items.length === 0) return <div className="text-center text-gray-500 py-10">{fallbackText}</div>;

            return (
                <>
                    <div className={gridClassName}>
                        {displayedItems.map((item, index) => renderItem(item, index))}
                    </div>
                    {displayedCount < items.length && (
                        <div ref={sentinelRef} className="py-8 flex justify-center w-full">
                            <div className="flex flex-col items-center gap-2">
                                <Loader2 className="animate-spin text-emerald-500" size={24} />
                                <span className="text-xs text-gray-500">جاري تحميل المزيد...</span>
                            </div>
                        </div>
                    )}
                </>
            );
        };

        const LibraryVideoItem = ({ filename, onSelect, isSelected, isFavorite, onToggleFavorite }) => {
            const vRef = useRef(null), [vis, setVis] = useState(false), [err, setErr] = useState(false), [hov, setHov] = useState(false), src = `video4all/${filename}`;
            const num = filename.split('.')[0];
            useEffect(() => { const o = new IntersectionObserver(([e]) => { if (e.isIntersecting) { setVis(true); o.disconnect() } }, { threshold: 0.1 }); if (vRef.current) o.observe(vRef.current); return () => o.disconnect() }, []);
            // Cleanup: تنظيف عنصر الفيديو عند إزالة المكون لمنع تسريب الذاكرة
            useEffect(() => {
                return () => {
                    if (vRef.current) {
                        vRef.current.pause();
                        vRef.current.src = '';
                        vRef.current.load();
                    }
                };
            }, []);
            if (err) return null;
            return <div className={`video-card group ${isSelected ? 'ring-2 ring-emerald-500 ring-offset-2 ring-offset-black' : ''}`} onMouseEnter={() => { setHov(true); if (vRef.current?.play) vRef.current.play().catch(() => { }) }} onMouseLeave={() => { setHov(false); if (vRef.current?.pause) { vRef.current.pause(); vRef.current.currentTime = 0 } }} onClick={() => onSelect(src)}>
                <span className="absolute top-2 left-2 z-20 bg-black/60 backdrop-blur-sm text-white text-[10px] px-2 py-0.5 rounded-md font-mono">#{num}</span>
                {onToggleFavorite && (
                    <button onClick={onToggleFavorite} className={`absolute bottom-2 left-2 z-30 p-1.5 rounded-full backdrop-blur-sm transition-all ${isFavorite ? 'bg-red-500/20 text-red-500' : 'bg-black/40 text-gray-400 opacity-0 group-hover:opacity-100 hover:text-white hover:bg-black/60'}`}>
                        <Heart size={14} className={isFavorite ? "fill-current" : ""} />
                    </button>
                )}
                {isSelected && <div className="absolute top-2 right-2 z-20 bg-emerald-500 text-black rounded-full p-1"><Check size={12} /></div>}
                {vis ? <video ref={vRef} src={src} className="w-full h-full object-cover" muted loop playsInline onError={() => setErr(true)} preload="metadata" /> : <div ref={vRef} className="w-full h-full bg-gray-800 animate-pulse flex items-center justify-center"><Video className="text-gray-700" size={24} /></div>}<div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition flex flex-col items-center justify-center gap-2"><Play size={32} className="text-white fill-white" /></div></div>;
        };

        const LibraryAudioItem = ({ filename, onSelect, playingFile, setPlayingFile, isSelected, previewVolume, isFavorite, onToggleFavorite }) => {
            const aRef = useRef(null), cRef = useRef(null), [vis, setVis] = useState(false), [err, setErr] = useState(false), [duration, setDuration] = useState(null), src = `audio4all/${filename}`, isPlaying = playingFile === src;
            const num = filename.split('.')[0];
            const formatDurationHMS = (sec) => { if (!sec || isNaN(sec)) return '--:--:--'; const h = Math.floor(sec / 3600); const m = Math.floor((sec % 3600) / 60); const s = Math.floor(sec % 60); return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`; };
            useEffect(() => { const o = new IntersectionObserver(([e]) => { if (e.isIntersecting) { setVis(true); o.disconnect() } }, { threshold: 0.1 }); if (cRef.current) o.observe(cRef.current); return () => o.disconnect() }, []);
            useEffect(() => { if (aRef.current) { if (isPlaying) aRef.current.play().catch(console.log); else { aRef.current.pause(); aRef.current.currentTime = 0 } } }, [isPlaying]);
            // Apply global volume to preview audio
            useEffect(() => { if (aRef.current && previewVolume !== undefined) { aRef.current.volume = previewVolume; } }, [previewVolume, isPlaying]);
            // Cleanup: تنظيف عنصر الصوت عند إزالة المكون لمنع تسريب الذاكرة
            useEffect(() => {
                return () => {
                    if (aRef.current) {
                        aRef.current.pause();
                        aRef.current.src = '';
                        aRef.current.load(); // يفرض تحرير الموارد
                    }
                };
            }, []);
            if (err) return null;
            return <div ref={cRef} className={`audio-card group relative ${isPlaying ? 'border-amber-500 shadow-[0_0_15px_rgba(245,158,11,0.3)]' : ''} ${isSelected ? 'ring-2 ring-amber-500 ring-offset-2 ring-offset-black' : ''}`} onClick={() => onSelect(src)}>
                <span className="absolute top-2 left-2 text-[10px] text-gray-600 font-mono group-hover:text-amber-500/50 transition-colors">#{num}</span>
                {onToggleFavorite && (
                    <button onClick={onToggleFavorite} className={`absolute bottom-2 left-2 z-30 p-1.5 rounded-full transition-all ${isFavorite ? 'bg-red-500/10 text-red-500' : 'bg-white/5 text-gray-400 opacity-0 group-hover:opacity-100 hover:text-white hover:bg-white/10'}`}>
                        <Heart size={14} className={isFavorite ? "fill-current" : ""} />
                    </button>
                )}
                {isSelected && <div className="absolute top-2 right-2 z-20 bg-amber-500 text-black rounded-full p-1"><Check size={12} /></div>}
                {vis ? <><audio ref={aRef} src={src} preload="metadata" onError={() => setErr(true)} onEnded={() => setPlayingFile(null)} onLoadedMetadata={(e) => setDuration(e.target.duration)} /><div className={`p-4 rounded-full mb-3 transition-all duration-300 ${isPlaying ? 'bg-amber-500 text-black scale-110' : 'bg-white/5 text-gray-400 group-hover:bg-amber-500/20 group-hover:text-amber-500'}`}>{isPlaying ? <Volume2 size={32} className="animate-pulse" /> : <Headphones size={32} />}</div><span className="text-[10px] font-mono text-gray-400 mb-1">{formatDurationHMS(duration)}</span><button aria-label={isPlaying ? "إيقاف" : "تشغيل"} onClick={e => { e.stopPropagation(); setPlayingFile(isPlaying ? null : src) }} className="mt-1 p-2 rounded-full bg-white/10 hover:bg-white/20 transition-colors z-10">{isPlaying ? <Pause size={16} fill="currentColor" /> : <Play size={16} fill="currentColor" />}</button></> : <div className="animate-pulse flex flex-col items-center"><div className="w-12 h-12 bg-white/5 rounded-full mb-2"></div><div className="w-20 h-4 bg-white/5 rounded"></div></div>}</div>;
        };

        const AutoGenerateModal = ({ onClose, onConfirm }) => {
            const [cat, setCat] = useState('any');
            const categories = [
                { id: 'any', label: 'تلقائي / أي مدة', sub: 'اختيار عشوائي شامل من كافة المدد' },
                { id: 'short', label: 'قصير جداً', sub: 'أقل من 20 ثانية' },
                { id: 'medium_short', label: 'قصير', sub: 'من 20 إلى 35 ثانية' },
                { id: 'medium', label: 'متوسط', sub: 'من 35 إلى 50 ثانية' },
                { id: 'long', label: 'طويل', sub: 'أكثر من 50 ثانية' }
            ];

            return (
                <div className="fixed inset-0 z-50 bg-black/80 flex items-center justify-center p-4 backdrop-blur-sm animate-in fade-in" role="dialog" aria-modal="true" aria-labelledby="extraction-mode-title">
                    <div className="bg-[#1a1a1a] border border-white/10 rounded-2xl p-6 md:p-8 max-w-lg w-full text-center space-y-5 shadow-2xl relative bg-gradient-to-br from-[#1a1a1a] to-[#0f0f0f] max-h-[90vh] overflow-y-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]">
                        <button aria-label="إغلاق" onClick={onClose} className="absolute top-4 left-4 text-gray-400 hover:text-white"><X /></button>

                        {/* Icon */}
                        <div className="mx-auto w-16 h-16 bg-gradient-to-tr from-purple-500 to-pink-500 rounded-full flex items-center justify-center shadow-lg shadow-purple-900/30">
                            <Wand2 size={32} className="text-white" />
                        </div>

                        {/* Title */}
                        <h3 className="text-2xl font-bold text-white">الإنشاء التلقائي الشامل</h3>

                        {/* Description */}
                        <p className="text-gray-400 text-sm leading-relaxed">
                            سيقوم النظام بذكاء باختيار تلاوة تناسب الفئة الزمنية المحددة مع خلفية غير مكررة
                        </p>

                        {/* Duration Selector */}
                        <div className="space-y-2">
                            <p className="text-xs text-gray-500 uppercase tracking-wider mb-3">اختر الفئة الزمنية</p>
                            <div className="grid grid-cols-2 gap-2">
                                {categories.map((c, idx) => (
                                    <button
                                        key={c.id}
                                        onClick={() => setCat(c.id)}
                                        className={`w-full rounded-xl border transition-all ${idx === 0 ? 'col-span-2 px-4 py-3 flex items-center justify-between gap-2' : 'col-span-1 px-2 py-3 flex flex-col items-center justify-center gap-1.5'} ${cat === c.id ? 'bg-purple-500/20 border-purple-500 text-white shadow-[0_0_15px_rgba(168,85,247,0.3)]' : 'bg-white/5 border-white/10 hover:bg-white/10 text-gray-400'}`}
                                    >
                                        <span className="font-bold">{c.label}</span>
                                        <span className={`text-[10px] opacity-70 ${idx === 0 ? '' : 'text-center leading-tight'}`}>{c.sub}</span>
                                    </button>
                                ))}
                            </div>
                        </div>

                        {/* Info Box */}
                        <div className="bg-purple-500/10 border border-purple-500/20 rounded-xl p-3 text-right">
                            <p className="text-[11px] text-purple-300 leading-relaxed">
                                <span className="font-bold">💡</span> الفهرسة الذكية تضمن لك تنوعاً عالياً دون تكرار التلاوات والخلفيات التي استخدمتها مؤخراً
                            </p>
                        </div>

                        {/* Start Button */}
                        <button
                            aria-label="بدء الإنشاء"
                            onClick={() => onConfirm(cat)}
                            className="w-full py-4 rounded-xl bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-500 hover:to-pink-500 text-white font-bold transition shadow-lg flex items-center justify-center gap-2"
                        >
                            <Sparkles size={20} /> ابدأ الإنشاء التلقائي
                        </button>
                    </div>
                </div>
            );
        };

        // === مكون اختيار طريقة استخراج الآيات ===
        const VerseExtractionModeModal = ({ onClose, onConfirm }) => {
            return (
                <div className="fixed inset-0 z-50 bg-black/80 flex items-center justify-center p-4 backdrop-blur-sm animate-in fade-in">
                    <div className="bg-[#1a1a1a] border border-white/10 rounded-2xl p-6 md:p-8 max-w-lg w-full text-center space-y-5 shadow-2xl relative bg-gradient-to-br from-[#1a1a1a] to-[#0f0f0f] max-h-[90vh] overflow-y-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]">
                        <button aria-label="إغلاق" onClick={onClose} className="absolute top-4 left-4 text-gray-400 hover:text-white"><X /></button>

                        {/* Icon */}
                        <div className="mx-auto w-16 h-16 bg-gradient-to-tr from-emerald-500 to-teal-500 rounded-full flex items-center justify-center shadow-lg shadow-emerald-900/30">
                            <ListMusic size={32} className="text-white" />
                        </div>

                        {/* Title */}
                        <h3 id="extraction-mode-title" className="text-2xl font-bold text-white">استخراج الآيات</h3>

                        {/* Description */}
                        <p className="text-gray-400 text-sm leading-relaxed">
                            كيف تريد إضافة الآيات للتلاوة؟
                        </p>

                        {/* Options */}
                        <div className="grid grid-cols-1 gap-3">
                            {/* Auto AI Option */}
                            <button
                                aria-label="استخراج تلقائي"
                                onClick={() => onConfirm('auto')}
                                className="w-full p-4 rounded-xl bg-gradient-to-r from-purple-600/20 to-pink-600/20 hover:from-purple-600/30 hover:to-pink-600/30 border border-purple-500/30 hover:border-purple-500/50 transition-all flex items-center gap-4 group"
                            >
                                <div className="p-3 rounded-full bg-purple-500/20 text-purple-400 group-hover:scale-110 transition-transform">
                                    <Cpu size={24} />
                                </div>
                                <div className="text-right flex-1">
                                    <h4 className="font-bold text-white mb-1">استخراج تلقائي (AI)</h4>
                                    <p className="text-[11px] text-gray-400">سيُرسل المقطع الصوتي إلى Google لمعالجته، ثم يمكنك مراجعة النتيجة قبل الحفظ</p>
                                </div>
                                <Sparkles size={18} className="text-purple-400 opacity-50 group-hover:opacity-100 transition-opacity" />
                            </button>

                            {/* Manual Option */}
                            <button
                                aria-label="إضافة يدوية"
                                onClick={() => onConfirm('manual')}
                                className="w-full p-4 rounded-xl bg-gradient-to-r from-blue-600/20 to-cyan-600/20 hover:from-blue-600/30 hover:to-cyan-600/30 border border-blue-500/30 hover:border-blue-500/50 transition-all flex items-center gap-4 group"
                            >
                                <div className="p-3 rounded-full bg-blue-500/20 text-blue-400 group-hover:scale-110 transition-transform">
                                    <Edit3 size={24} />
                                </div>
                                <div className="text-right flex-1">
                                    <h4 className="font-bold text-white mb-1">إضافة يدوية</h4>
                                    <p className="text-[11px] text-gray-400">سأقوم بإضافة الآيات وتحديد توقيتاتها يدوياً</p>
                                </div>
                                <ChevronLeft size={18} className="text-blue-400 opacity-50 group-hover:opacity-100 transition-opacity" />
                            </button>
                        </div>

                        {/* Info Box */}
                        <div className="bg-emerald-500/10 border border-emerald-500/20 rounded-xl p-3 text-right">
                            <p className="text-[11px] text-emerald-300 leading-relaxed">
                                اختيار التحليل التلقائي يعني موافقتك على إرسال هذا المقطع الصوتي إلى Google لهذه العملية فقط. يمكنك اختيار الإضافة اليدوية لإبقاء الملف على جهازك.
                            </p>
                        </div>
                    </div>
                </div>
            );
        };

        // === مكون اختيار السورة والآية من القرآن - النسخة المحسنة ===
        // دالة تطبيع النص للبحث الذكي (إزالة التشكيل، توحيد الألفات، التاء المربوطة، علامات الوقف، إلخ)
        const normalizeSearchText = (text) => {
            if (!text) return '';
            return text
                // إزالة علامات الوقف والرموز القرآنية (مثل ۚ ۗ ۦ ۙ ۞ ۝ وغيرها)
                .replace(/[\u06D6-\u06ED]/g, '')
                // إزالة التشكيل والتنوين
                .replace(/[\u064B-\u065F]/g, '')
                // إزالة الألف الخنجرية والوصلة
                .replace(/[\u0670\u0671]/g, '')
                // إزالة التطويل (الكشيدة)
                .replace(/\u0640/g, '')
                // توحيد الألفات (أ إ آ ٱ -> ا)
                .replace(/[أإآٱ]/g, 'ا')
                // توحيد التاء المربوطة -> هاء
                .replace(/ة/g, 'ه')
                // توحيد الألف المقصورة والياء -> ياء
                .replace(/[ىي]/g, 'ي')
                // توحيد الواو المهموزة -> واو
                .replace(/ؤ/g, 'و')
                // توحيد الياء المهموزة -> ياء
                .replace(/ئ/g, 'ي')
                // إزالة أي رموز غير عربية ما عدا الأرقام والمسافات
                .replace(/[^\u0600-\u06FF\s0-9]/g, '')
                // هام جداً: توحيد المسافات (مسافات متعددة -> مسافة واحدة)
                .replace(/\s+/g, ' ')
                .trim();
        };

        // Skeleton Loader Component
        const SkeletonLoader = ({ count = 3 }) => (
            <div className="space-y-3 animate-pulse">
                {[...Array(count)].map((_, i) => (
                    <div key={i} className="bg-white/5 border border-white/5 rounded-xl p-3">
                        <div className="flex justify-between items-center gap-4 mb-2">
                            <div className="h-3 w-16 bg-white/10 rounded-full"></div>
                            <div className="h-3 w-8 bg-emerald-500/10 rounded-full"></div>
                        </div>
                        <div className="space-y-2">
                            <div className="h-2 w-full bg-white/5 rounded-full"></div>
                            <div className="h-2 w-3/4 bg-white/5 rounded-full"></div>
                        </div>
                    </div>
                ))}
            </div>
        );

        const SurahSelectionView = ({
            search,
            onSearchChange,
            isGlobalSearching,
            loading,
            globalResults,
            recentSurahs,
            filteredSurahs,
            onSelectSurah,
            onSelectGlobalAyah,
            surahList
        }) => {
            return (
                <React.Fragment>
                    <div className="p-3 border-b border-white/5 shrink-0">
                        <div className="relative">
                            <Search size={16} className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-500" />
                            <input
                                type="text"
                                value={search}
                                onChange={e => onSearchChange(e.target.value)}
                                placeholder="ابحث عن آية أو اسم سورة..."
                                className="w-full bg-black/40 border border-white/10 rounded-xl py-2.5 pr-10 pl-4 text-sm placeholder:text-gray-600 focus:border-emerald-500 focus:outline-none transition-colors"
                            />
                            {isGlobalSearching && (
                                <div className="absolute left-3 top-1/2 -translate-y-1/2">
                                    <Loader2 className="animate-spin text-emerald-500" size={14} />
                                </div>
                            )}
                        </div>
                    </div>

                    <div className="flex-1 overflow-y-auto custom-scrollbar p-3">
                        {loading ? (
                            <div className="flex items-center justify-center py-12">
                                <Loader2 className="animate-spin text-emerald-500" size={32} />
                            </div>
                        ) : (
                            <React.Fragment>
                                {isGlobalSearching ? (
                                    <div className="mb-6">
                                        <div className="flex items-center gap-2 mb-2 px-1">
                                            <Loader2 size={12} className="animate-spin text-emerald-400" />
                                            <span className="text-[12px] text-emerald-400 font-bold">جاري البحث...</span>
                                        </div>
                                        <SkeletonLoader count={3} />
                                    </div>
                                ) : globalResults.length > 0 && (
                                    <div className="mb-6 animate-in fade-in slide-in-from-top-2">
                                        <div className="flex items-center gap-2 mb-2 px-1">
                                            <Sparkles size={12} className="text-emerald-400" />
                                            <span className="text-[12px] text-emerald-400 font-bold">آيات مقترحة</span>
                                        </div>
                                        <div className="space-y-2">
                                            {globalResults.map((result, idx) => {
                                                const surahName = surahList.find(s => s.number === result.s)?.name || `سورة ${result.s}`;
                                                return (
                                                    <button
                                                        key={`res-${idx}`}
                                                        onClick={() => onSelectGlobalAyah(result)}
                                                        className="w-full text-right p-3 bg-emerald-900/10 hover:bg-emerald-900/20 border border-emerald-500/10 hover:border-emerald-500/30 rounded-xl transition-all group"
                                                    >
                                                        <div className="flex justify-between items-start gap-2">
                                                            <span className="text-[10px] text-emerald-500 bg-emerald-500/10 px-2 py-0.5 rounded-full shrink-0">
                                                                {surahName} : {toArabicNumerals(result.a)}
                                                            </span>
                                                        </div>
                                                        <p className="mt-1 font-amiri text-gray-200 group-hover:text-white leading-relaxed text-sm line-clamp-2">
                                                            {result.t}
                                                        </p>
                                                    </button>
                                                );
                                            })}
                                        </div>
                                    </div>
                                )}

                                {recentSurahs.length > 0 && !search && (
                                    <div className="mb-4">
                                        <div className="flex items-center gap-2 mb-2">
                                            <Clock size={12} className="text-gray-500" />
                                            <span className="text-[10px] text-gray-500 font-bold uppercase">المستخدمة مؤخراً</span>
                                        </div>
                                        <div className="flex flex-wrap gap-2">
                                            {recentSurahs.map(surah => (
                                                <button
                                                    key={surah.number}
                                                    onClick={() => onSelectSurah(surah)}
                                                    className="px-3 py-1.5 bg-purple-500/10 hover:bg-purple-500/20 border border-purple-500/20 hover:border-purple-500/40 rounded-lg text-xs font-bold text-purple-300 transition-all"
                                                >
                                                    {surah.name}
                                                </button>
                                            ))}
                                        </div>
                                    </div>
                                )}

                                {!isGlobalSearching && filteredSurahs.length > 0 && (
                                    <React.Fragment>
                                        {search && <div className="text-[10px] text-gray-500 font-bold mb-2 px-1">السور</div>}
                                        <div className="grid grid-cols-2 gap-2">
                                            {filteredSurahs.map(surah => (
                                                <button
                                                    key={surah.number}
                                                    onClick={() => onSelectSurah(surah)}
                                                    className="flex items-center gap-3 p-3 bg-white/5 hover:bg-emerald-500/10 border border-white/5 hover:border-emerald-500/30 rounded-xl text-right transition-all group"
                                                >
                                                    <span className="w-8 h-8 flex items-center justify-center bg-emerald-500/20 text-emerald-400 rounded-lg text-xs font-bold group-hover:bg-emerald-500 group-hover:text-black transition-colors">
                                                        {toArabicNumerals(surah.number)}
                                                    </span>
                                                    <div className="flex-1 min-w-0">
                                                        <p className="font-bold text-white text-sm truncate">{surah.name}</p>
                                                        <p className="text-[10px] text-gray-500">{toArabicNumerals(surah.numberOfAyahs)} آية</p>
                                                    </div>
                                                </button>
                                            ))}
                                        </div>
                                    </React.Fragment>
                                )}

                                {filteredSurahs.length === 0 && globalResults.length === 0 && search && !isGlobalSearching && (
                                    <div className="text-center py-8 text-gray-500 text-sm">لا توجد نتائج</div>
                                )}
                            </React.Fragment>
                        )}
                    </div>
                </React.Fragment>
            );
        };

        const AyahSelectionView = ({
            search,
            onSearchChange,
            loading,
            filteredAyahs,
            onSelectAyah,
            existingKeys = new Set(),
            surahName,
            initialScrollIndex
        }) => {
            // Lazy Loading Logic
            const [visibleCount, setVisibleCount] = useState(initialScrollIndex ? Math.max(50, initialScrollIndex + 20) : 50);
            const loadMoreRef = useRef(null);

            // Scroll to initial index on mount if provided
            useEffect(() => {
                if (initialScrollIndex && !loading && filteredAyahs.length > 0) {
                    requestAnimationFrame(() => {
                        const el = document.getElementById(`ayah-btn-${initialScrollIndex}`);
                        if (el) el.scrollIntoView({ block: 'center', behavior: 'auto' });
                    });
                }
            }, [loading, initialScrollIndex]); // Run when loading finishes or index changes

            // Reset visible count when search or filters change
            useEffect(() => {
                if (search) {
                    setVisibleCount(50);
                } else if (initialScrollIndex && visibleCount < initialScrollIndex + 20) {
                    // Ensure we don't collapse if we need to see deep items
                    setVisibleCount(Math.max(50, initialScrollIndex + 20));
                }
            }, [search, filteredAyahs]);

            useEffect(() => {
                const observer = new IntersectionObserver(
                    (entries) => {
                        if (entries[0].isIntersecting) {
                            setVisibleCount(prev => Math.min(prev + 50, filteredAyahs.length));
                        }
                    },
                    { threshold: 0.5, rootMargin: '100px' }
                );

                if (loadMoreRef.current) {
                    observer.observe(loadMoreRef.current);
                }

                return () => observer.disconnect();
            }, [visibleCount, filteredAyahs.length]);

            return (
                <React.Fragment>
                    <div className="p-3 border-b border-white/5 shrink-0">
                        <div className="relative">
                            <Search size={16} className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-500" />
                            <input
                                type="text"
                                value={search}
                                onChange={e => onSearchChange(e.target.value)}
                                placeholder="ابحث في الآيات أو أدخل رقم الآية..."
                                className="w-full bg-black/40 border border-white/10 rounded-xl py-2.5 pr-10 pl-4 text-sm placeholder:text-gray-600 focus:border-emerald-500 focus:outline-none transition-colors"
                            />
                        </div>
                    </div>

                    <div className="flex-1 overflow-y-auto custom-scrollbar p-3">
                        {loading ? (
                            <div className="flex items-center justify-center py-12">
                                <Loader2 className="animate-spin text-emerald-500" size={32} />
                            </div>
                        ) : (
                            <div className="space-y-2">
                                {filteredAyahs.length === 0 ? (
                                    <div className="text-center py-8 text-gray-500 text-sm">لا توجد نتائج</div>
                                ) : (
                                    filteredAyahs.slice(0, visibleCount).map((ayah, index) => {
                                        const normalizedSurahName = window.QuranDataValidator?.normalizeSurahName(surahName) || surahName;
                                        const isAdded = normalizedSurahName && existingKeys.has(`${normalizedSurahName}:${ayah.numberInSurah}`);
                                        return (
                                            <button
                                                key={ayah.number}
                                                id={`ayah-btn-${ayah.numberInSurah}`}
                                                onClick={() => onSelectAyah(ayah)}
                                                className={`w-full p-4 border rounded-xl text-right transition-all group relative overflow-hidden ${isAdded ? 'bg-emerald-900/10 border-emerald-500/30' : 'bg-white/5 border-white/5 hover:bg-emerald-500/10 hover:border-emerald-500/30'}`}
                                            >
                                                {isAdded && (
                                                    <div className="absolute top-0 left-0 p-2 bg-emerald-500/20 rounded-br-xl">
                                                        <Check size={14} className="text-emerald-400" />
                                                    </div>
                                                )}
                                                <div className="flex items-start gap-4" dir="rtl">
                                                    <span className={`shrink-0 w-8 h-8 flex items-center justify-center rounded-lg text-xs font-bold transition-colors ${isAdded ? 'bg-emerald-500 text-white' : 'bg-emerald-500/20 text-emerald-400 group-hover:bg-emerald-500 group-hover:text-black'}`}>
                                                        {toArabicNumerals(ayah.numberInSurah)}
                                                    </span>
                                                    <p className={`flex-1 font-amiri text-lg leading-loose transition-colors line-clamp-2 ${isAdded ? 'text-emerald-100' : 'text-white group-hover:text-emerald-100'}`}>
                                                        {ayah.text}
                                                    </p>
                                                </div>
                                            </button>
                                        )
                                    })
                                )}
                                {visibleCount < filteredAyahs.length && (
                                    <div ref={loadMoreRef} className="py-4 text-center">
                                        <Loader2 className="animate-spin mx-auto text-emerald-500/50" size={24} />
                                    </div>
                                )}
                            </div>
                        )}
                    </div>
                </React.Fragment>
            );
        };

        const WordSelectionView = ({
            words,
            selectionStart,
            selectionEnd,
            onWordClick,
            onAdd, // (closeAfter) => void
            onAddFull, // (closeAfter) => void
            selectedAyah,
            isAdding = false // حالة التحميل
        }) => {


            const getSelectedWordCount = () => {
                if (selectionStart === null) return 0;
                const endIdx = selectionEnd !== null ? selectionEnd : selectionStart;
                return endIdx - selectionStart + 1;
            };

            const getSelectedText = () => {
                if (selectionStart === null) return '';
                const endIdx = selectionEnd !== null ? selectionEnd : selectionStart;
                return words.slice(selectionStart, endIdx + 1).join(' ');
            };

            // Keyboard navigation handler
            const handleKeyDown = (e, idx) => {
                if (e.key === 'Enter' || e.key === ' ') {
                    e.preventDefault();
                    onWordClick(idx);
                } else if (e.key === 'ArrowRight' && idx > 0) {
                    e.preventDefault();
                    const prevBtn = document.querySelector(`[data-word-idx="${idx - 1}"]`);
                    prevBtn?.focus();
                } else if (e.key === 'ArrowLeft' && idx < words.length - 1) {
                    e.preventDefault();
                    const nextBtn = document.querySelector(`[data-word-idx="${idx + 1}"]`);
                    nextBtn?.focus();
                }
            };

            return (
                <div className="flex-1 flex flex-col min-h-0 p-4">
                    {/* Audio Player and Tips */}
                    <div className="flex items-center gap-3 mb-4 shrink-0">


                        <div className="flex-1 bg-blue-500/10 border border-blue-500/20 rounded-xl p-3 flex items-center justify-between">
                            <p className="text-[11px] text-blue-300">
                                💡 اضغط على الكلمة الأولى ثم الأخيرة
                            </p>
                            <span className="px-2 py-0.5 bg-blue-500/20 text-blue-300 rounded text-[10px] font-bold">
                                {toArabicNumerals(getSelectedWordCount())} كلمة
                            </span>
                        </div>
                    </div>

                    <div className="flex-1 overflow-y-auto custom-scrollbar bg-black/20 rounded-xl p-4 border border-white/5" role="group" aria-label="كلمات الآية">
                        <div className="flex flex-wrap gap-2 justify-center" dir="rtl">
                            {words.map((word, idx) => {
                                const isInRange = selectionStart !== null && (
                                    selectionEnd !== null
                                        ? idx >= selectionStart && idx <= selectionEnd
                                        : idx === selectionStart
                                );
                                const isStart = idx === selectionStart;
                                const isEnd = idx === selectionEnd;

                                return (
                                    <button
                                        key={idx}
                                        data-word-idx={idx}
                                        onClick={() => onWordClick(idx)}
                                        onKeyDown={(e) => handleKeyDown(e, idx)}
                                        aria-label={`كلمة ${word}${isInRange ? ' - محددة' : ''}`}
                                        aria-pressed={isInRange}
                                        tabIndex={0}
                                        className={`px-3 py-2 rounded-lg font-amiri text-lg transition-all focus:outline-none focus:ring-2 focus:ring-emerald-400/50 ${isInRange
                                            ? 'bg-emerald-500 text-black shadow-lg shadow-emerald-500/30'
                                            : 'bg-white/5 text-white hover:bg-white/10'
                                            } ${isStart ? 'ring-2 ring-emerald-300' : ''} ${isEnd ? 'ring-2 ring-blue-300' : ''}`}
                                    >
                                        {word}
                                    </button>
                                );
                            })}
                        </div>
                    </div>

                    {selectionStart !== null && (
                        <div className="mt-3 p-3 bg-emerald-500/10 border border-emerald-500/20 rounded-xl shrink-0">
                            <p className="text-[10px] text-gray-400 mb-1">النص المحدد:</p>
                            <p className="font-amiri text-white text-sm leading-relaxed text-right line-clamp-2" dir="rtl">
                                {getSelectedText()}
                            </p>
                        </div>
                    )}

                    <div className="grid grid-cols-3 gap-2 mt-3 shrink-0">
                        <button
                            aria-label="إضافة كاملة"
                            onClick={() => onAddFull(true)}
                            disabled={isAdding}
                            className="py-2.5 bg-white/10 hover:bg-white/20 disabled:opacity-50 disabled:cursor-not-allowed text-white rounded-xl text-[10px] font-bold transition-all flex flex-col items-center gap-1"
                        >
                            {isAdding ? <Loader2 size={14} className="animate-spin" /> : <ListMusic size={14} />}
                            كاملة
                        </button>
                        <button
                            aria-label="إضافة والمتابعة"
                            onClick={() => onAdd(false)}
                            disabled={selectionStart === null || isAdding}
                            className="py-2.5 bg-purple-500/20 hover:bg-purple-500/30 text-purple-300 disabled:opacity-50 disabled:cursor-not-allowed rounded-xl text-[10px] font-bold transition-all flex flex-col items-center gap-1"
                        >
                            {isAdding ? <Loader2 size={14} className="animate-spin" /> : <RefreshCcw size={14} />}
                            إضافة ومتابعة
                        </button>
                        <button
                            aria-label="إضافة وإغلاق"
                            onClick={() => onAdd(true)}
                            disabled={selectionStart === null || isAdding}
                            className="py-2.5 bg-gradient-to-r from-emerald-600 to-teal-600 hover:from-emerald-500 hover:to-teal-500 disabled:opacity-50 disabled:cursor-not-allowed text-white rounded-xl text-[10px] font-bold transition-all flex flex-col items-center gap-1 shadow-lg"
                        >
                            {isAdding ? <Loader2 size={14} className="animate-spin" /> : <Check size={14} />}
                            إضافة وإغلاق
                        </button>
                    </div>
                </div>
            );
        };

        const QuranSelectorModal = ({ onClose, onAddAyah, audioRange, existingItems = [], audioFileSrc, volume }) => {
            const hasExistingItems = existingItems && existingItems.length > 0;
            const existingKeys = useMemo(() => new Set(existingItems.map(i => `${window.QuranDataValidator?.normalizeSurahName(i.surah) || i.surah}:${i.ayah}`)), [existingItems]);
            const [step, setStep] = useState(1); // 1: Surah, 2: Ayah, 3: Words
            const [surahList, setSurahList] = useState([]);
            const [selectedSurah, setSelectedSurah] = useState(null);
            const [surahAyahs, setSurahAyahs] = useState([]);
            const [selectedAyah, setSelectedAyah] = useState(null);
            const [lastVisitedAyahIndex, setLastVisitedAyahIndex] = useState(null); // To restore scroll position
            const [loadingSurahs, setLoadingSurahs] = useState(true);
            const [loadingAyahs, setLoadingAyahs] = useState(false);
            const [surahSearch, setSurahSearch] = useState('');
            const [ayahSearch, setAyahSearch] = useState('');
            const [error, setError] = useState(null);
            const [addedCount, setAddedCount] = useState(0);

            // Word selection state
            const [words, setWords] = useState([]);
            const [selectionStart, setSelectionStart] = useState(null);
            const [selectionEnd, setSelectionEnd] = useState(null);
            const [isAdding, setIsAdding] = useState(false); // حالة التحميل أثناء الإضافة

            // User Audio Player State
            const [isPlaying, setIsPlaying] = useState(false);
            const [duration, setDuration] = useState(0); // Full file duration
            // Effective Range Calculation
            const rangeStart = audioRange?.start || 0;
            const rangeEnd = (audioRange?.end && audioRange.end > rangeStart) ? audioRange.end : (duration || rangeStart + 0.1);
            const effectiveDuration = Math.max(0.1, rangeEnd - rangeStart);

            const [currentTime, setCurrentTime] = useState(rangeStart);
            const audioPlayerRef = useRef(null);

            // Sync User Audio Player Volume
            useEffect(() => {
                if (audioPlayerRef.current) {
                    audioPlayerRef.current.volume = volume ?? 1;
                }
            }, [volume]);

            // Helper for formatting time
            const formatTimePlayer = (seconds) => {
                if (!seconds) return "00:00";
                const mins = Math.floor(seconds / 60);
                const secs = Math.floor(seconds % 60);
                return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
            };

            // Global Smart Search State
            const [globalSearchResults, setGlobalSearchResults] = useState([]);
            const [isGlobalSearching, setIsGlobalSearching] = useState(false);
            const searchIndexRef = useRef(null);

            // Recent surahs from localStorage
            const [recentSurahs, setRecentSurahs] = useState(() => {
                try {
                    return JSON.parse(localStorage.getItem('recentSurahs') || '[]');
                } catch { return []; }
            });

            // Save to recent surahs
            const saveToRecent = (surah) => {
                const updated = [surah.number, ...recentSurahs.filter(n => n !== surah.number)].slice(0, 5);
                setRecentSurahs(updated);
                localStorage.setItem('recentSurahs', JSON.stringify(updated));
            };

            // تحميل قائمة السور والفهرس عند فتح Modal
            useEffect(() => {
                let isMounted = true;
                let timeoutId = null;
                const abortController = new AbortController();

                const initData = async () => {
                    // 1. Load Surahs
                    const cachedSurahs = localStorage.getItem('quranSurahList');
                    if (cachedSurahs) {
                        if (isMounted) {
                            try {
                                const parsedSurahs = JSON.parse(cachedSurahs);
                                if (!Array.isArray(parsedSurahs)) throw new Error('Invalid surah cache');
                                setSurahList(parsedSurahs);
                                window.__quranSurahList = parsedSurahs;
                            } catch (e) {
                                localStorage.removeItem('quranSurahList');
                                setError('تعذر قراءة بيانات القرآن المحفوظة. أعد فتح النافذة لتحديثها.');
                            }
                            setLoadingSurahs(false);
                        }
                    } else {
                        try {
                            const res = await fetch('https://api.alquran.cloud/v1/surah', { signal: abortController.signal });
                            const data = await res.json();
                            if (isMounted) {
                                if (data.code === 200 && data.data) {
                                    setSurahList(data.data);
                                    window.__quranSurahList = data.data;
                                    localStorage.setItem('quranSurahList', JSON.stringify(data.data));
                                } else { setError('فشل تحميل قائمة السور. يرجى المحاولة مرة أخرى.'); }
                            }
                        } catch (e) {
                            if (e.name !== 'AbortError' && isMounted) {
                                setError('خطأ في الاتصال بالخادم. تأكد من اتصالك بالإنترنت.');
                            }
                        }
                        if (isMounted) setLoadingSurahs(false);
                    }

                    // 2. Load Search Index (Lazily)
                    timeoutId = setTimeout(async () => {
                        if (!isMounted) return;
                        const cachedIndex = localStorage.getItem('quranSearchIndex');
                        if (cachedIndex) {
                            try {
                                const parsedIndex = JSON.parse(cachedIndex);
                                if (!Array.isArray(parsedIndex)) throw new Error('Invalid Quran search cache');
                                searchIndexRef.current = parsedIndex;
                            } catch (e) {
                                localStorage.removeItem('quranSearchIndex');
                                console.warn('Invalid Quran search cache cleared');
                            }
                        } else {
                            try {
                                // تحميل القرآن كاملاً (نص بسيط) لغرض البحث
                                const res = await fetch('https://api.alquran.cloud/v1/quran/quran-simple-clean', { signal: abortController.signal });
                                const data = await res.json();
                                if (isMounted && data.code === 200 && data.data && data.data.surahs) {
                                    const flatIndex = [];
                                    data.data.surahs.forEach(s => {
                                        s.ayahs.forEach(a => {
                                            flatIndex.push({ s: s.number, a: a.numberInSurah, t: a.text });
                                        });
                                    });
                                    searchIndexRef.current = flatIndex;
                                    try {
                                        localStorage.setItem('quranSearchIndex', JSON.stringify(flatIndex));
                                    } catch (e) {
                                        console.warn('Cannot cache search index, quota exceeded');
                                    }
                                }
                            } catch (e) {
                                if (e.name !== 'AbortError') {
                                    console.warn('Failed to load search index', e);
                                }
                            }
                        }
                    }, 500);
                };
                initData();

                // Cleanup function
                return () => {
                    isMounted = false;
                    if (timeoutId) clearTimeout(timeoutId);
                    abortController.abort();
                };
            }, []);


            // البحث الذكي
            useEffect(() => {
                if (step !== 1 || !surahSearch) {
                    setGlobalSearchResults([]);
                    setIsGlobalSearching(false);
                    return;
                }

                // إذا كان البحث رقماً أو قصيراً، نكتفي ببحث السور
                if (surahSearch.length < 3) {
                    setGlobalSearchResults([]);
                    setIsGlobalSearching(false);
                    return;
                }

                // Set loading immediately to prevent "No results" flash
                setIsGlobalSearching(true);

                // Debounce Search
                const timer = setTimeout(() => {
                    if (searchIndexRef.current) {
                        const normalizedQuery = normalizeSearchText(surahSearch);
                        const results = [];
                        let count = 0;

                        // بحث في الفهرس
                        const index = searchIndexRef.current;
                        for (let i = 0; i < index.length; i++) {
                            const normalizedAyah = normalizeSearchText(index[i].t);
                            if (normalizedAyah.includes(normalizedQuery)) {
                                results.push(index[i]);
                                count++;
                                if (count >= 20) break; // حد أقصى للنتائج
                            }
                        }

                        // محاكاة تأخير بسيط للجمالية (اختياري)
                        // setTimeout(() => {
                        setGlobalSearchResults(results);
                        setIsGlobalSearching(false);
                        // }, 300);
                    } else {
                        // Index not loaded yet?
                        setIsGlobalSearching(false);
                    }
                }, 400); // 400ms delay

                return () => clearTimeout(timer);
            }, [surahSearch, step]);

            // استعادة آخر حالة (السورة والآية) عند الفتح
            useEffect(() => {
                const abortController = new AbortController();
                let isMounted = true;

                const restoreState = async () => {
                    // فقط نطبق الاستعادة إذا كنا في الخطوة الأولى ولم يتم التحميل بعد، وكانت القائمة جاهزة، ولدينا عناصر سابقة
                    if (step !== 1 || surahList.length === 0 || loadingSurahs || !hasExistingItems) return;

                    // نتحقق مما إذا كان هناك بحث نشط لتجنب التضارب
                    if (surahSearch) return;

                    try {
                        const lastSurah = JSON.parse(localStorage.getItem('quranLastSurah'));
                        const lastAyah = JSON.parse(localStorage.getItem('quranLastAyah'));

                        if (lastSurah && isMounted) {
                            // 1. تحديد السورة
                            setSelectedSurah(lastSurah);
                            setLoadingAyahs(true);

                            // 2. تحميل الآيات
                            const res = await fetch(`https://api.alquran.cloud/v1/surah/${lastSurah.number}/quran-uthmani`, { signal: abortController.signal });
                            const data = await res.json();

                            if (isMounted && data.code === 200 && data.data?.ayahs) {
                                const normalizedAyahs = data.data.ayahs.map(ayah => ({
                                    ...ayah,
                                    text: normalizeArabicText(ayah.text)
                                }));
                                setSurahAyahs(normalizedAyahs);

                                // الانتقال للخطوة 2 (قائمة الآيات) بدلاً من تحديد الآية مباشرة
                                setStep(2);
                            }
                        }
                    } catch (e) {
                        if (e.name !== 'AbortError') {
                            console.error("Failed to restore state", e);
                            // في حال الخطأ نمسح التخزين لتجنب تكرار الخطأ
                            localStorage.removeItem('quranLastSurah');
                            localStorage.removeItem('quranLastAyah');
                        }
                    } finally {
                        if (isMounted) setLoadingAyahs(false);
                    }
                };

                restoreState();

                return () => {
                    isMounted = false;
                    abortController.abort();
                };
            }, [surahList, loadingSurahs]); // يعمل مرة واحدة عند جاهزية القائمة

            // تحميل آيات السورة المختارة
            const handleSelectSurah = async (surah) => {
                setSelectedSurah(surah);
                setLastVisitedAyahIndex(null); // Reset explanation scroll
                saveToRecent(surah);
                setStep(2);
                setLoadingAyahs(true);
                setError(null);
                setAyahSearch('');
                try {
                    const res = await fetch(`https://api.alquran.cloud/v1/surah/${surah.number}/quran-uthmani`);
                    const data = await res.json();
                    if (data.code === 200 && data.data?.ayahs) {
                        // تطبيع النص القرآني لإصلاح عرض السكون
                        const normalizedAyahs = data.data.ayahs.map(ayah => ({
                            ...ayah,
                            text: normalizeArabicText(ayah.text)
                        }));
                        setSurahAyahs(normalizedAyahs);
                    } else {
                        setError('فشل تحميل الآيات. يرجى المحاولة مرة أخرى.');
                    }
                } catch (e) {
                    setError('خطأ في الاتصال بالخادم. تأكد من اتصالك بالإنترنت.');
                } finally {
                    setLoadingAyahs(false);
                }
            };

            // التعامل مع اختيار آية من البحث العام
            const handleSelectGlobalAyah = async (item) => {
                setLoadingAyahs(true);
                setError(null);
                setSurahSearch(''); // clear search
                try {
                    // 1. تحديد السورة
                    const surahObj = surahList.find(s => s.number === item.s);
                    if (surahObj) {
                        setSelectedSurah(surahObj);
                        saveToRecent(surahObj);
                    } else {
                        // Fallback if surah list logic fails
                        setSelectedSurah({ number: item.s, name: `سورة ${item.s}` });
                    }

                    // 2. تحميل السورة كاملة (للحصول على النص العثماني)
                    const res = await fetch(`https://api.alquran.cloud/v1/surah/${item.s}/quran-uthmani`);
                    const data = await res.json();
                    if (data.code === 200 && data.data?.ayahs) {
                        const normalizedAyahs = data.data.ayahs.map(ayah => ({
                            ...ayah,
                            text: normalizeArabicText(ayah.text)
                        }));
                        setSurahAyahs(normalizedAyahs);

                        // 3. تحديد الآية والانتقال للخطوة 3
                        const targetAyah = normalizedAyahs.find(a => a.numberInSurah === item.a);
                        if (targetAyah) {
                            handleSelectAyah(targetAyah);
                        } else {
                            // إذا لم نجد الآية لسبب ما، نبقى في السورة
                            setStep(2);
                        }
                    } else { throw new Error('Failed'); }

                } catch (e) {
                    setError('فشل تحميل الآية. يرجى المحاولة مرة أخرى.');
                    setStep(1);
                } finally {
                    setLoadingAyahs(false);
                }
            };

            // اختيار آية للتحديد
            const handleSelectAyah = (ayah) => {
                setSelectedAyah(ayah);
                setLastVisitedAyahIndex(ayah.numberInSurah); // Remember position
                const wordsList = ayah.text.split(/\s+/).filter(w => w.length > 0);
                setWords(wordsList);
                setSelectionStart(0);
                setSelectionEnd(wordsList.length - 1);
                setStep(3);
            };



            // Custom Hook for extracting audio peaks - Optimized version
            const useAudioWaveform = (audioSrc, samples = 70) => {
                const [peaks, setPeaks] = useState([]);
                const audioContextRef = useRef(null);

                useEffect(() => {
                    if (!audioSrc) { setPeaks([]); return; }

                    let isActive = true;
                    const abortController = new AbortController();

                    // Reuse AudioContext if possible, or create new one
                    if (!audioContextRef.current || audioContextRef.current.state === 'closed') {
                        audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)();
                    }
                    const ctx = audioContextRef.current;

                    fetch(audioSrc, { signal: abortController.signal })
                        .then(r => r.arrayBuffer())
                        .then(ab => ctx.decodeAudioData(ab))
                        .then(audioBuffer => {
                            if (!isActive) return;

                            const rawData = audioBuffer.getChannelData(0); // Use first channel
                            const blockSize = Math.floor(rawData.length / samples);
                            const calculatedPeaks = [];

                            for (let i = 0; i < samples; i++) {
                                let sum = 0;
                                const start = i * blockSize;
                                for (let j = 0; j < blockSize; j++) {
                                    sum += Math.abs(rawData[start + j]);
                                }
                                calculatedPeaks.push(sum / blockSize);
                            }

                            // Normalize peaks to 0-1 range
                            const max = Math.max(...calculatedPeaks, 0.001); // Prevent divide by zero
                            setPeaks(calculatedPeaks.map(p => p / max));
                        })
                        .catch(err => {
                            if (err.name !== 'AbortError') {
                                console.error("Error decoding audio data:", err);
                            }
                            if (isActive) setPeaks([]);
                        });

                    return () => {
                        isActive = false;
                        abortController.abort();
                        // Suspend context instead of closing to allow reuse
                        if (ctx && ctx.state === 'running') {
                            ctx.suspend().catch(() => { });
                        }
                    };
                }, [audioSrc, samples]);

                // Cleanup on unmount
                useEffect(() => {
                    return () => {
                        if (audioContextRef.current && audioContextRef.current.state !== 'closed') {
                            audioContextRef.current.close().catch(() => { });
                        }
                    };
                }, []);

                return peaks;
            };

            // النقر على كلمة لتحديد النطاق
            const handleWordClick = (index) => {
                if (selectionStart === null || (selectionStart !== null && selectionEnd !== null && index < selectionStart)) {
                    setSelectionStart(index);
                    setSelectionEnd(null);
                } else if (selectionEnd === null) {
                    if (index >= selectionStart) {
                        setSelectionEnd(index);
                    } else {
                        setSelectionEnd(selectionStart);
                        setSelectionStart(index);
                    }
                } else {
                    setSelectionStart(index);
                    setSelectionEnd(null);
                }
            };

            // Helper to clean Surah name (remove "Surah" and diacritics)
            const cleanSurahName = (name) => {
                if (!name) return "";
                // 1. Remove diacritics (Tashkeel) first to ensure we match the word "Surah"
                let cleaned = name.replace(/[\u064B-\u065F\u0670]/g, "");
                // 2. Remove "سورة" and trim
                cleaned = cleaned.replace(/سورة\s*/g, "").trim();
                return cleaned;
            };

            // إضافة النص المحدد
            const handleAddSelection = async (closeAfter = true) => {
                if (selectionStart === null || isAdding) return;
                setIsAdding(true);
                const endIdx = selectionEnd !== null ? selectionEnd : selectionStart;
                const selectedWords = words.slice(selectionStart, endIdx + 1);

                let text = selectedWords.join(' ');
                // شرط إضافة رقم الآية: أن يكون التحديد واصلاً لآخر كلمة في الآية
                if (endIdx === words.length - 1) {
                    text += ' ' + toArabicNumerals(selectedAyah.numberInSurah);
                }

                // حفظ الحالة للمرة القادمة
                try {
                    localStorage.setItem('quranLastSurah', JSON.stringify(selectedSurah));
                    localStorage.setItem('quranLastAyah', JSON.stringify(selectedAyah));
                } catch (e) { console.error('Failed to save state'); }

                onAddAyah({
                    text: text,
                    surah: cleanSurahName(selectedSurah.name),
                    ayah: selectedAyah.numberInSurah,
                    start: audioRange?.start || 0,
                    end: audioRange?.end || 10
                });

                setAddedCount(prev => prev + 1);
                setIsAdding(false);

                if (closeAfter) {
                    onClose();
                } else {
                    // البقاء في نفس الخطوة ونفس الآية لإكمال التحديد
                    setSelectionStart(null);
                    setSelectionEnd(null);
                }
            };

            // إضافة الآية كاملة
            const handleAddFullAyah = async (closeAfter = true) => {
                // لا حاجة للتحقق من selectionStart لأننا نضيف الآية كاملة
                if (!selectedAyah || words.length === 0 || isAdding) return;
                setIsAdding(true);
                const fullText = words.join(' ');

                onAddAyah({
                    text: fullText + ' ' + toArabicNumerals(selectedAyah.numberInSurah),
                    surah: cleanSurahName(selectedSurah.name),
                    ayah: selectedAyah.numberInSurah,
                    start: audioRange?.start || 0,
                    end: audioRange?.end || 10
                });

                setAddedCount(prev => prev + 1);
                setIsAdding(false);

                if (closeAfter) {
                    onClose();
                } else {
                    setStep(2);
                    setSelectedAyah(null);
                    setWords([]);
                    setSelectionStart(null);
                    setSelectionEnd(null);
                }
            };

            // العودة للخطوة السابقة
            const handleBack = () => {
                if (step === 3) {
                    setStep(2);
                    setSelectedAyah(null);
                    setWords([]);
                    setSelectionStart(null);
                    setSelectionEnd(null);
                } else if (step === 2) {
                    setStep(1);
                    setSurahAyahs([]);
                    setSelectedSurah(null);
                    setAyahSearch('');
                }
            };

            // useMemo for expensive filtering
            const filteredSurahs = useMemo(() => {
                return surahList.filter(s =>
                    s.name.includes(surahSearch) ||
                    s.englishName.toLowerCase().includes(surahSearch.toLowerCase()) ||
                    s.number.toString().includes(surahSearch)
                );
            }, [surahList, surahSearch]);

            const recentSurahsData = useMemo(() => {
                return recentSurahs.map(n => surahList.find(s => s.number === n)).filter(Boolean);
            }, [recentSurahs, surahList]);

            const filteredAyahs = useMemo(() => {
                return ayahSearch
                    ? surahAyahs.filter(a => a.text.includes(ayahSearch) || a.numberInSurah.toString() === ayahSearch)
                    : surahAyahs;
            }, [surahAyahs, ayahSearch]);

            const audioPeaks = useAudioWaveform(audioFileSrc, 80);


            return (
                <div className="fixed inset-0 z-[60] bg-black/90 flex items-center justify-center p-4 backdrop-blur-sm animate-in fade-in">
                    <div className="bg-[#1a1a1a] border border-white/10 rounded-2xl w-full max-w-lg max-h-[85vh] flex flex-col shadow-2xl relative overflow-hidden">
                        {/* Header */}
                        <div className="flex items-center justify-between p-4 border-b border-white/10 bg-gradient-to-r from-emerald-900/20 to-teal-900/20 shrink-0">
                            <div className="flex items-center gap-3">
                                {step > 1 && (
                                    <button aria-label="رجوع" onClick={handleBack} className="p-2 hover:bg-white/10 rounded-lg transition-colors">
                                        <ChevronRight size={20} />
                                    </button>
                                )}
                                <div className="flex items-center gap-2">
                                    <BookOpen size={20} className="text-emerald-400" />
                                    <h3 className="text-lg font-bold text-white">
                                        {step === 1 ? 'اختر السورة' : step === 2 ? selectedSurah?.name : `تحديد النص`}
                                    </h3>
                                </div>
                            </div>
                            <div className="flex items-center gap-2">
                                {addedCount > 0 && (
                                    <span className="px-2 py-1 bg-emerald-500/20 text-emerald-400 rounded-lg text-xs font-bold">
                                        +{toArabicNumerals(addedCount)} مضافة
                                    </span>
                                )}
                                <button aria-label="إغلاق" onClick={onClose} className="p-2 hover:bg-white/10 rounded-lg transition-colors text-gray-400 hover:text-white">
                                    <X size={20} />
                                </button>
                            </div>
                        </div>

                        {/* Step Indicator - Compact */}
                        <div className="flex items-center justify-center gap-1 px-4 py-2 border-b border-white/5 bg-black/20 shrink-0">
                            {[1, 2, 3].map(s => (
                                <React.Fragment key={s}>
                                    <div className={`w-2 h-2 rounded-full transition-all ${step >= s ? 'bg-emerald-500 scale-110' : 'bg-white/20'}`} />
                                    {s < 3 && <div className={`w-6 h-0.5 transition-all ${step > s ? 'bg-emerald-500' : 'bg-white/10'}`} />}
                                </React.Fragment>
                            ))}
                        </div>

                        {/* Custom User Audio Player */}
                        {audioFileSrc && (
                            <div className="bg-[#050505] border-b border-white/5 relative group shrink-0" dir="ltr">


                                <div className="relative z-10 px-4 py-2 flex items-center gap-3">
                                    {/* Controls Group */}
                                    <div className="flex items-center gap-2">
                                        {/* Rewind 5s */}
                                        <button
                                            onClick={() => {
                                                const audio = audioPlayerRef.current;
                                                if (audio) {
                                                    let newTime = audio.currentTime - 5;
                                                    if (newTime < rangeStart) newTime = rangeStart;
                                                    audio.currentTime = newTime;
                                                    setCurrentTime(newTime);
                                                }
                                            }}
                                            className="w-8 h-8 rounded-full bg-white/5 hover:bg-white/10 text-gray-400 hover:text-white flex items-center justify-center transition-all active:scale-95"
                                            title="إرجاع 5 ثواني"
                                        >
                                            <RotateCcw size={14} />
                                        </button>

                                        {/* Play Button - Compact */}
                                        <button
                                            onClick={() => {
                                                const audio = audioPlayerRef.current;
                                                if (!audio) return;

                                                if (isPlaying) {
                                                    audio.pause();
                                                } else {
                                                    // Should we reset if at end?
                                                    if (audio.currentTime >= rangeEnd - 0.1 || audio.currentTime < rangeStart) {
                                                        audio.currentTime = rangeStart;
                                                    }
                                                    audio.play();
                                                }
                                                setIsPlaying(!isPlaying);
                                            }}
                                            className="w-10 h-10 rounded-full bg-emerald-500 hover:bg-emerald-400 text-black flex items-center justify-center hover:scale-110 transition-all shadow-[0_0_15px_rgba(16,185,129,0.3)] shrink-0 group/btn"
                                        >
                                            {isPlaying ?
                                                <Pause size={18} fill="currentColor" className="group-hover/btn:scale-90 transition-transform" /> :
                                                <Play size={18} fill="currentColor" className="ml-0.5 group-hover/btn:scale-110 transition-transform" />
                                            }
                                        </button>

                                        {/* Forward 5s */}
                                        <button
                                            onClick={() => {
                                                const audio = audioPlayerRef.current;
                                                if (audio) {
                                                    let newTime = audio.currentTime + 5;
                                                    if (newTime > rangeEnd) newTime = rangeEnd;
                                                    audio.currentTime = newTime;
                                                    setCurrentTime(newTime);
                                                }
                                            }}
                                            className="w-8 h-8 rounded-full bg-white/5 hover:bg-white/10 text-gray-400 hover:text-white flex items-center justify-center transition-all active:scale-95"
                                            title="تقديم 5 ثواني"
                                        >
                                            <RotateCw size={14} />
                                        </button>
                                    </div>

                                    {/* Scrubber Area */}
                                    <div className="flex-1 flex flex-col justify-center gap-1 min-w-0">

                                        <div className="relative h-10 group/slider w-full cursor-pointer flex items-center justify-center my-1.5">
                                            {/* Real Waveform Layer */}
                                            <div className="absolute inset-0 w-full h-full opacity-50 pointer-events-none flex items-center justify-between z-0 px-1">
                                                {audioPeaks.length > 0 ? (
                                                    audioPeaks.map((peak, i) => {
                                                        // Adjust visualization to show progress within the EFFECTIVE range
                                                        // This is a simplified visual approximation since peaks represent full file
                                                        const progress = (currentTime - rangeStart) / effectiveDuration;
                                                        return (
                                                            <div
                                                                key={i}
                                                                className={`w-0.5 rounded-full transition-all duration-300 ${i / 80 < progress ? 'bg-emerald-500 shadow-[0_0_10px_#10b981]' : 'bg-white/10'}`}
                                                                style={{
                                                                    height: `${Math.max(20, peak * 100)}%`,
                                                                }}
                                                            />
                                                        )
                                                    })
                                                ) : (
                                                    /* Fallback / Loading State */
                                                    Array.from({ length: 80 }).map((_, i) => (
                                                        <div
                                                            key={i}
                                                            className={`w-0.5 rounded-full transition-all duration-300 ${i / 80 < (currentTime - rangeStart) / effectiveDuration ? 'bg-emerald-500 shadow-[0_0_10px_#10b981]' : 'bg-white/10 animate-pulse'}`}
                                                            style={{
                                                                height: '20%',
                                                            }}
                                                        />
                                                    ))
                                                )}
                                            </div>

                                            {/* Native Range Input (Invisible) */}
                                            <input
                                                type="range"
                                                min={rangeStart}
                                                max={rangeEnd}
                                                step="0.01"
                                                value={currentTime}
                                                onChange={(e) => {
                                                    const val = parseFloat(e.target.value);
                                                    audioPlayerRef.current.currentTime = val;
                                                    setCurrentTime(val);
                                                }}
                                                className="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-30"
                                            />

                                            {/* Track Container */}
                                            <div className="absolute inset-x-0 top-1/2 -translate-y-1/2 h-1 bg-white/10 rounded-full overflow-hidden backdrop-blur-sm group-hover/slider:h-1.5 transition-all duration-300">
                                                {/* Progress Fill */}
                                                <div
                                                    className="h-full bg-gradient-to-r from-emerald-600 to-emerald-400 shadow-[0_0_10px_#10b981]"
                                                    style={{ width: `${Math.max(0, Math.min(100, ((currentTime - rangeStart) / effectiveDuration) * 100))}%` }}
                                                />
                                            </div>

                                            {/* Thumb Indicator */}
                                            <div
                                                className="absolute top-1/2 -translate-y-1/2 w-3 h-3 bg-white rounded-full shadow-[0_0_10px_white] pointer-events-none transition-all scale-0 group-hover/slider:scale-100 z-20"
                                                style={{ left: `${Math.max(0, Math.min(100, ((currentTime - rangeStart) / effectiveDuration) * 100))}%`, transform: 'translate(-50%, -50%)' }}
                                            />
                                        </div>

                                        <div className="flex justify-between items-center text-[10px] font-mono tracking-wider font-medium">
                                            <span className="text-emerald-400 bg-emerald-500/10 px-1.5 py-px rounded">
                                                {formatTimePlayer(Math.max(0, currentTime - rangeStart))}
                                            </span>
                                            <span className="text-gray-500">
                                                {formatTimePlayer(effectiveDuration)}
                                            </span>
                                        </div>
                                    </div>

                                    <audio
                                        ref={audioPlayerRef}
                                        src={audioFileSrc}
                                        onTimeUpdate={(e) => {
                                            const t = e.target.currentTime;
                                            if (t >= rangeEnd) {
                                                e.target.currentTime = rangeStart;
                                                setCurrentTime(rangeStart);
                                                // loop behavior
                                                if (isPlaying) e.target.play();
                                            } else {
                                                setCurrentTime(t);
                                            }
                                        }}
                                        onLoadedMetadata={(e) => setDuration(e.target.duration)}
                                        onEnded={() => setIsPlaying(false)}
                                        onError={(e) => console.error("Audio Load Error", e)}
                                        className="hidden"
                                    />
                                </div>
                            </div>
                        )}

                        {/* Content */}
                        <div className="flex-1 overflow-hidden flex flex-col min-h-0">
                            {error ? (
                                <div className="flex-1 flex items-center justify-center p-8">
                                    <div className="text-center space-y-3">
                                        <AlertCircle size={40} className="text-red-400 mx-auto" />
                                        <p className="text-red-400">{error}</p>
                                        <button onClick={() => { setError(null); window.location.reload(); }} className="px-4 py-2 bg-white/10 rounded-lg text-sm">إعادة المحاولة</button>
                                    </div>
                                </div>
                            ) : step === 1 ? (
                                <SurahSelectionView
                                    search={surahSearch}
                                    onSearchChange={setSurahSearch}
                                    isGlobalSearching={isGlobalSearching}
                                    loading={loadingSurahs}
                                    globalResults={globalSearchResults}
                                    recentSurahs={recentSurahsData}
                                    filteredSurahs={filteredSurahs}
                                    onSelectSurah={handleSelectSurah}
                                    onSelectGlobalAyah={handleSelectGlobalAyah}
                                    surahList={surahList}
                                />
                            ) : step === 2 ? (
                                <AyahSelectionView
                                    search={ayahSearch}
                                    onSearchChange={setAyahSearch}
                                    loading={loadingAyahs}
                                    filteredAyahs={surahAyahs.filter(a => a.text.includes(normalizeSearchText(ayahSearch)) || a.numberInSurah.toString().includes(ayahSearch))}
                                    onSelectAyah={handleSelectAyah}
                                    existingKeys={existingKeys}
                                    surahName={selectedSurah?.name}
                                    initialScrollIndex={lastVisitedAyahIndex}
                                />
                            ) : (
                                <WordSelectionView
                                    words={words}
                                    selectionStart={selectionStart}
                                    selectionEnd={selectionEnd}
                                    onWordClick={handleWordClick}
                                    onAdd={handleAddSelection}
                                    onAddFull={handleAddFullAyah}
                                    selectedAyah={selectedAyah}
                                    isAdding={isAdding}
                                />
                            )}
                        </div>

                        {/* Footer Stats */}
                        {step !== 3 && (
                            <div className="p-2 border-t border-white/5 bg-black/20 shrink-0 flex items-center justify-center gap-4 text-[10px] text-gray-500">
                                <span>📖 {toArabicNumerals(114)} سورة</span>
                                <span>•</span>
                                <span>✨ {step === 1 ? 'اختر السورة' : `${toArabicNumerals(surahAyahs.length)} آية`}</span>
                            </div>
                        )}
                    </div>
                </div>
            );
        };

        const AlertModal = ({ title, message, onClose, isSuccess }) => { const Icon = isSuccess ? BadgeCheck : ShieldAlert; return <div className="fixed inset-0 z-[70] bg-black/80 flex items-center justify-center p-4 backdrop-blur-sm animate-in fade-in"><div className={`bg-[#111] border ${isSuccess ? 'border-emerald-500/30' : 'border-red-500/30'} rounded-2xl p-6 max-w-sm w-full shadow-2xl relative transform transition-all scale-100`}><div className="flex flex-col items-center text-center space-y-4"><div className={`p-4 rounded-full ${isSuccess ? 'bg-emerald-500/10 text-emerald-500' : 'bg-red-500/10 text-red-500'} mb-2`}><Icon size={32} /></div><h3 className="text-xl font-bold text-white">{title}</h3><p className="text-gray-400 text-sm leading-relaxed">{message}</p><div className="w-full mt-4"><button aria-label="إغلاق" onClick={onClose} className={`w-full py-3 ${isSuccess ? 'bg-emerald-600 hover:bg-emerald-500' : 'bg-red-600 hover:bg-red-500'} text-white rounded-xl font-bold transition-colors shadow-lg`}>حسناً</button></div></div></div></div> };
        const ConfirmationModal = ({ title, message, onConfirm, onCancel, icon: Icon = AlertTriangle }) => <div className="fixed inset-0 z-[60] bg-black/80 flex items-center justify-center p-4 backdrop-blur-sm animate-in fade-in"><div className="bg-[#111] border border-white/10 rounded-2xl p-6 max-w-sm w-full shadow-2xl relative transform transition-all scale-100"><div className="flex flex-col items-center text-center space-y-4"><div className="p-4 rounded-full bg-amber-500/10 text-amber-500 mb-2"><Icon size={32} /></div><h3 className="text-xl font-bold text-white">{title}</h3><p className="text-gray-400 text-sm leading-relaxed">{message}</p><div className="flex gap-3 w-full mt-4"><button aria-label="إلغاء" onClick={onCancel} className="flex-1 py-3 bg-gray-800 hover:bg-gray-700 rounded-xl font-bold transition-colors">إلغاء</button><button aria-label="تأكيد" onClick={onConfirm} className="flex-1 py-3 bg-red-600 hover:bg-red-500 text-white rounded-xl font-bold transition-colors shadow-lg">تأكيد</button></div></div></div></div>;

        // --- Interactive Image Editor Component (Professional Version using react-easy-crop) ---
        const ImageCropperModal = ({ src, initialTransform, onSave, onClose }) => {
            const [crop, setCrop] = useState(initialTransform?.crop || { x: 0, y: 0 });
            const [zoom, setZoom] = useState(initialTransform?.zoom || 1);
            const [objectFit, setObjectFit] = useState(initialTransform?.objectFit || 'cover');
            const [croppedAreaPixels, setCroppedAreaPixels] = useState(initialTransform?.croppedAreaPixels || null);

            const onCropComplete = useCallback((croppedArea, croppedAreaPixels) => {
                setCroppedAreaPixels(croppedAreaPixels);
            }, []);

            return (
                <div className="fixed inset-0 z-[80] bg-black/95 flex flex-col items-center justify-center backdrop-blur-xl animate-in fade-in pb-safe">
                    {/* Header */}
                    <div className="w-full max-w-md p-4 flex justify-between items-center bg-black/50 border-b border-white/10 z-10 absolute top-0">
                        <button onClick={onClose} className="p-2 text-gray-400 hover:text-white rounded-full bg-white/5"><X size={20} /></button>
                        <h2 className="text-white font-bold">تعديل وقص الصورة</h2>
                        <div className="flex gap-2">
                            <button onClick={() => { setCrop({ x: 0, y: 0 }); setZoom(1); setObjectFit('cover'); }} className="px-3 py-1.5 bg-white/10 text-white font-bold rounded-lg hover:bg-white/20 transition flex items-center gap-1 text-xs"><RotateCcw size={14} /> استعادة</button>
                            <button onClick={() => onSave({ crop, zoom, croppedAreaPixels, objectFit })} className="px-4 py-1.5 bg-emerald-500 text-black font-bold rounded-lg shadow-lg">حفظ</button>
                        </div>
                    </div>

                    {/* Main Cropper Area */}
                    <div className="relative w-full max-w-[240px] sm:max-w-[280px] md:max-w-[320px] aspect-[9/16] mt-14 md:mt-16 mb-32 md:mb-24 overflow-hidden rounded-lg bg-[#111] shadow-[0_0_30px_rgba(16,185,129,0.15)]">
                        <Cropper
                            image={src}
                            crop={crop}
                            zoom={zoom}
                            aspect={9 / 16}
                            onCropChange={setCrop}
                            onCropComplete={onCropComplete}
                            onZoomChange={setZoom}
                            objectFit={objectFit}
                            showGrid={true}
                            style={{
                                containerStyle: { background: 'transparent' },
                                cropAreaStyle: { border: '1px solid rgba(255, 255, 255, 0.4)', boxShadow: '0 0 0 9999em rgba(0, 0, 0, 0.6)' },
                                mediaStyle: { filter: objectFit === 'contain' ? 'drop-shadow(0 0 20px rgba(0,0,0,0.5))' : 'none' }
                            }}
                        />
                    </div>

                    {/* Footer Controls */}
                    <div className="w-full max-w-md bg-[#111]/80 backdrop-blur-md p-4 pb-safe md:p-6 border-t border-white/10 rounded-t-3xl absolute bottom-0">
                        <div className="flex justify-center mb-4 md:mb-6 bg-black p-1 rounded-xl border border-white/5">
                            <button onClick={() => setObjectFit('cover')} className={`flex-1 py-1.5 md:py-2 text-[10px] md:text-xs font-bold rounded-lg transition-colors ${objectFit === 'cover' ? 'bg-emerald-500 text-black' : 'text-gray-400 hover:text-white'}`}>تعبئة (Cover)</button>
                            <button onClick={() => setObjectFit('contain')} className={`flex-1 py-1.5 md:py-2 text-[10px] md:text-xs font-bold rounded-lg transition-colors ${objectFit === 'contain' ? 'bg-emerald-500 text-black' : 'text-gray-400 hover:text-white'}`}>احتواء (Contain)</button>
                        </div>
                        <div className="flex items-center gap-3 md:gap-4 px-2">
                            <ZoomIn className="text-gray-400 shrink-0" size={16} />
                            <input
                                type="range"
                                min="1" max="5" step="0.05"
                                value={zoom}
                                onChange={(e) => setZoom(parseFloat(e.target.value))}
                                className="w-full h-1.5 md:h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-emerald-500"
                            />
                            <span className="text-emerald-400 font-mono text-[10px] md:text-xs w-8 md:w-10 text-center">{zoom.toFixed(1)}x</span>
                        </div>
                        <p className="text-[9px] md:text-[10px] text-gray-500 text-center mt-3 md:mt-4">اسحب بإصبعك للتحريك، واستخدم إصبعين للتكبير (Pinch-to-zoom)</p>
                    </div>
                </div>
            );
        };

        // --- Drag & Drop Overlay Component ---
        const DragOverlay = ({ item, x, y, width }) => {
            if (!item) return null;
            return (
                <div
                    className="drag-overlay"
                    style={{ top: y, left: x, width: width }}
                >
                    <div className="p-3 border border-emerald-500 rounded-lg bg-[#111] text-right text-xs">
                        <div className="flex gap-2 mb-2 items-center justify-between pl-6" dir="ltr">
                            <div className="flex items-center gap-1 opacity-50"><div className="p-1.5 bg-emerald-500/20 text-emerald-500 rounded"><MapPin size={14} /></div><div className="w-16 bg-black border border-gray-700 rounded px-1 py-1 text-center text-emerald-400 text-xs">{formatTimePrecise(item.start)}</div></div>
                            <span className="text-gray-500">-</span>
                            <div className="flex items-center gap-1 opacity-50"><div className="w-16 bg-black border border-gray-700 rounded px-1 py-1 text-center text-emerald-400 text-xs">{formatTimePrecise(item.end)}</div><div className="p-1.5 bg-red-500/20 text-red-500 rounded"><MapPin size={14} /></div></div>
                        </div>
                        <div className="w-full bg-transparent font-amiri text-lg text-white py-1 leading-loose">{item.text}</div>
                    </div>
                </div>
            );
        };

        const DevDialog = ({ onClose }) => (
            <div className="fixed inset-0 z-[100] flex items-center justify-center p-4" dir="rtl">
                {/* Backdrop with blur and fade animation */}
                <div
                    className="absolute inset-0 bg-black/60 backdrop-blur-md transition-opacity duration-300 animate-in fade-in"
                    onClick={onClose}
                ></div>

                {/* Dialog Card */}
                <div className="relative w-full max-w-[380px] bg-[#1a1a1a]/80 backdrop-filter backdrop-blur-xl border border-white/10 rounded-[32px] overflow-hidden shadow-2xl transform transition-all duration-300 animate-in zoom-in-95 scale-100 ring-1 ring-white/5">

                    {/* Decorative Background Elements */}
                    <div className="absolute top-0 right-0 w-64 h-64 bg-emerald-500/20 rounded-full blur-[80px] -translate-y-1/2 translate-x-1/2 pointer-events-none"></div>
                    <div className="absolute bottom-0 left-0 w-48 h-48 bg-blue-500/10 rounded-full blur-[60px] translate-y-1/3 -translate-x-1/3 pointer-events-none"></div>

                    {/* Header with Close Button */}
                    <div className="relative z-10 flex justify-between items-center p-6 pb-2">
                        <div className="w-10 h-10 rounded-full bg-white/5 flex items-center justify-center border border-white/5">
                            <Code2 size={20} className="text-emerald-400" />
                        </div>
                        <button
                            onClick={onClose}
                            className="w-10 h-10 rounded-full bg-white/5 hover:bg-white/10 flex items-center justify-center transition-colors border border-white/5 text-gray-400 hover:text-white"
                        >
                            <X size={20} />
                        </button>
                    </div>

                    {/* Content Section */}
                    <div className="relative z-10 px-6 pb-8 text-center flex flex-col items-center">

                        {/* Avatar / Icon */}
                        <div className="relative mb-6 group">
                            <div className="absolute inset-0 bg-gradient-to-tr from-emerald-500 to-teal-400 rounded-full blur opacity-40 group-hover:opacity-60 transition-opacity duration-500"></div>
                            <div className="w-24 h-24 bg-gradient-to-tr from-[#111] to-[#222] rounded-full p-1 relative border border-white/10">
                                <div className="w-full h-full rounded-full overflow-hidden flex items-center justify-center bg-gradient-to-br from-emerald-500/10 to-teal-500/10">
                                    <img src="images/me.webp" alt="Yaman" className="w-full h-full object-cover" />
                                </div>
                            </div>
                            <div className="absolute -bottom-2 right-0 bg-[#1a1a1a] p-1.5 rounded-full border border-white/10">
                                <BadgeCheck size={16} className="text-blue-400 fill-blue-400/20" />
                            </div>
                        </div>

                        {/* Text Info */}
                        <h2 className="text-2xl font-bold text-white mb-2 font-tajawal">تم التطوير بواسطة يمان</h2>
                        <p className="text-gray-400 text-sm font-medium mb-8 bg-white/5 px-4 py-1.5 rounded-full border border-white/5 inline-flex items-center gap-2">
                            <span className="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
                            Software Engineer
                        </p>

                        {/* Social Links */}
                        <div className="w-full space-y-3">
                            <a
                                href="https://instagram.com/wadl6"
                                target="_blank"
                                rel="noopener noreferrer"
                                className="flex items-center justify-between w-full p-4 bg-white/5 hover:bg-white/10 border border-white/5 hover:border-emerald-500/30 rounded-2xl transition-all duration-300 group"
                            >
                                <div className="flex items-center gap-4">
                                    <div className="p-2.5 bg-gradient-to-br from-purple-500/20 to-pink-500/20 text-pink-400 rounded-xl group-hover:scale-110 transition-transform duration-300">
                                        <svg viewBox="0 0 24 24" width="20" height="20" stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"></line></svg>
                                    </div>
                                    <div className="text-right">
                                        <div className="text-xs text-gray-500 font-medium mb-0.5">انستقرام</div>
                                        <div className="text-sm font-bold text-white text-right group-hover:text-emerald-400 transition-colors">تابعني على الانستقرام</div>
                                    </div>
                                </div>
                                <div className="w-8 h-8 rounded-full bg-white/5 flex items-center justify-center text-gray-400 group-hover:text-white group-hover:bg-emerald-500 group-hover:rotate-[-45deg] transition-all duration-300">
                                    <ArrowRight size={16} className="rotate-180" />
                                </div>
                            </a>

                            <a
                                href="https://syrdroid.com/y"
                                target="_blank"
                                rel="noopener noreferrer"
                                className="flex items-center justify-between w-full p-4 bg-white/5 hover:bg-white/10 border border-white/5 hover:border-blue-500/30 rounded-2xl transition-all duration-300 group"
                            >
                                <div className="flex items-center gap-4">
                                    <div className="p-2.5 bg-gradient-to-br from-blue-500/20 to-cyan-500/20 text-blue-400 rounded-xl group-hover:scale-110 transition-transform duration-300">
                                        <Layout size={20} />
                                    </div>
                                    <div className="text-right">
                                        <div className="text-xs text-gray-500 font-medium mb-0.5">معرض أعمالي</div>
                                        <div className="text-sm font-bold text-white text-right group-hover:text-blue-400 transition-colors">شاهد معرض أعمالي</div>
                                    </div>
                                </div>
                                <div className="w-8 h-8 rounded-full bg-white/5 flex items-center justify-center text-gray-400 group-hover:text-white group-hover:bg-blue-500 group-hover:rotate-[-45deg] transition-all duration-300">
                                    <ArrowRight size={16} className="rotate-180" />
                                </div>
                            </a>
                        </div>
                    </div>

                    {/* Bottom Gradient Line */}
                    <div className="h-1 w-full bg-gradient-to-r from-emerald-500/0 via-emerald-500/50 to-emerald-500/0 opacity-50"></div>
                </div>
            </div>
        );

        // === Analytics Tracking Helper ===
        /* ═══════════════════════════════════════════════════════════════
           ربط نوافذ React بزرّ الرجوع — المرحلة 3
           ═══════════════════════════════════════════════════════════════
           في TWA زرّ الرجوع من أول عنوان **يغلق التطبيق**. فمستخدمٌ فتح
           نافذة ثم ضغط رجوع — أكثر حركة متوقَّعة على أندرويد — كان يخرج من
           التطبيق كله بدل إغلاق النافذة.

           وهذه الصفحة فيها أحد عشر عَلَمًا لنوافذ (`showExportConfirm`،
           `showQuranSelector`، `showImageEditor`، `trimmingFile`، …) لكل
           منها مواضع فتح وإغلاق متفرّقة. ربطُ كلٍّ منها يدويًّا يعني نحو
           ثلاثين تعديلًا، وموضعُ إغلاق واحد يُنسى يترك مُدخلًا معلّقًا في
           السجل — فتصير أول ضغطة رجوع بعده بلا أثر مرئي، وهو عطبٌ **أسوأ من
           الأصل** لأنه يبدو تجمّدًا لا خطأ.

           فالربط يقع على **حالة** النافذة لا على مواضع فعلها: خُطّاف واحد
           يراقب العَلَم، ويتولّى السجل عند الفتح وينظّفه عند الإغلاق أيًّا
           كان الطريق الذي أغلقها. لا موضع فتح ولا إغلاق قائم يُلمس.

           ⚠️ حدٌّ معروف: السجل مكدّسٌ LIFO. فلو فُتحت نافذتان معًا وأُغلقت
           **السفلى** بزرّها، نُزع مُدخل العلوية. النوافذ هنا متعارضة عمليًّا
           (لا تُفتح إلا واحدة)، فلم يُبنَ لهذا احتياطٌ لا داعي له.
           ═══════════════════════════════════════════════════════════════ */
        const useBackClose = (isOpen, close) => {
            // مرجعٌ لا تبعية: `close` غالبًا دالة سهمية تُعاد بناؤها كل رسم،
            // ولو دخلت في مصفوفة التبعيات لأُعيد تسجيل مُدخل السجل مع كل
            // رسمة — أي تكديس مُدخلات لنافذة واحدة.
            const closeRef = useRef(close);
            closeRef.current = close;
            const [backGeneration, setBackGeneration] = useState(0);

            useEffect(() => {
                if (!isOpen || !window.AppShell) return;

                let viaBack = false;
                window.AppShell.openModal(() => {
                    viaBack = true;
                    try { closeRef.current(); } catch (e) { /* إغلاق فاشل لا يُسقط الصفحة */ }
                    // A back press consumes AppShell's history entry. If the
                    // closed layer revealed another modal, re-run this effect
                    // and register one fresh entry for the remaining layer.
                    setBackGeneration(generation => generation + 1);
                });

                return () => {
                    // أُغلقت بطريق آخر (زر X، نقر على الخلفية، إتمام العملية):
                    // يُنزَع مُدخل السجل هنا حتى يبقى الطريقان متّسقين.
                    if (!viaBack) window.AppShell.closeModal();
                };
            }, [isOpen, backGeneration]);
        };

        const trackAnalytics = async (action, data = {}) => {
            // Disabled until a real consent UI and a reviewed retention policy
            // exist. Call sites remain centralized for a future compliant
            // implementation without hidden collection.
            return { disabled: true, action };
        };

        function QuranFlowApp() {
            const savedSettings = (() => { try { const s = localStorage.getItem('quranShortsSettings'); return s ? JSON.parse(s) : null } catch (e) { return null } })();
            const [showTOD, setShowTOD] = useState(false);
            const [activeTab, setActiveTab] = useState('media'), [videoSrc, setVideoSrc] = useState(null), [audioSrc, setAudioSrc] = useState(null), [audioFile, setAudioFile] = useState(null), [selectedAudioName, setSelectedAudioName] = useState(null);
            const [trimmingFile, setTrimmingFile] = useState(null), [showAudioChoice, setShowAudioChoice] = useState(false), [showAutoGenerateModal, setShowAutoGenerateModal] = useState(false), [isProcessingAudio, setIsProcessingAudio] = useState(false), [isAutoGenerating, setIsAutoGenerating] = useState(false), [autoGenStep, setAutoGenStep] = useState(""), [showResetConfirm, setShowResetConfirm] = useState(false), [alertModal, setAlertModal] = useState({ visible: false, title: '', message: '', isSuccess: false });
            const [isPlaying, setIsPlaying] = useState(false), [currentTime, setCurrentTime] = useState(0), [videoRange, setVideoRange] = useState({ start: 0, end: 0 }), [audioRange, setAudioRange] = useState({ start: 0, end: 0 });
            const [timelineData, setTimelineData] = useState([]), [isAnalyzingAI, setIsAnalyzingAI] = useState(false), [aiError, setAiError] = useState(null), [aiStatus, setAiStatus] = useState("");
            const [overlaySettings, setOverlaySettings] = useState(savedSettings?.overlaySettings || DEFAULT_OVERLAY), [ayahStyle, setAyahStyle] = useState(savedSettings?.ayahStyle || DEFAULT_AYAH_STYLE), [watermark, setWatermark] = useState(savedSettings?.watermark || DEFAULT_WATERMARK), [showSiteBranding, setShowSiteBranding] = useState(savedSettings?.showSiteBranding !== undefined ? savedSettings.showSiteBranding : DEFAULT_BRANDING);

            // Background Image Support
            const [bgType, setBgType] = useState('video'); // 'video' | 'image'
            const [bgImageSrc, setBgImageSrc] = useState(null);
            const bgImageRef = useRef(null);

            // Image Transform Settings
            const DEFAULT_IMAGE_TRANSFORM = { crop: { x: 0, y: 0 }, zoom: 1, objectFit: 'cover', croppedAreaPixels: null };
            const [imageTransform, setImageTransform] = useState(DEFAULT_IMAGE_TRANSFORM);

            // Audio Database Cache for High-Performance Smart Selection
            const audioDBRef = useRef([]);
            useEffect(() => {
                const buildAudioDatabase = async () => {
                    const CACHE_KEY = 'quranShortsAudioDB';
                    const CACHE_VERSION = 2; // Incremented for new logic
                    const totalAudios = APP_CONFIG.audioCount;

                    try {
                        const cached = localStorage.getItem(CACHE_KEY);
                        if (cached) {
                            const parsed = JSON.parse(cached);
                            if (parsed.version === CACHE_VERSION && parsed.count === totalAudios) {
                                audioDBRef.current = parsed.db;
                                return;
                            }
                        }
                    } catch (e) { }

                    // Build cache in background
                    const db = [];
                    const batchSize = 10;
                    for (let batch = 0; batch < Math.ceil(totalAudios / batchSize); batch++) {
                        const batchPromises = [];
                        const startIdx = batch * batchSize + 1;
                        const endIdx = Math.min((batch + 1) * batchSize, totalAudios);
                        for (let i = startIdx; i <= endIdx; i++) {
                            const src = `audio4all/${i}.mp3`;
                            const loadPromise = new Promise((resolve) => {
                                const audio = new Audio();
                                const timeoutId = setTimeout(() => resolve(null), 10000);
                                audio.onloadedmetadata = () => {
                                    clearTimeout(timeoutId);
                                    resolve({ src, duration: audio.duration, id: i });
                                };
                                audio.onerror = () => { clearTimeout(timeoutId); resolve(null); };
                                audio.src = src;
                            });
                            batchPromises.push(loadPromise);
                        }
                        const results = await Promise.all(batchPromises);
                        db.push(...results.filter(r => r !== null));
                        // Save intermediate results
                        audioDBRef.current = db;
                    }

                    try { localStorage.setItem(CACHE_KEY, JSON.stringify({ version: CACHE_VERSION, count: totalAudios, db })); } catch (e) { }
                };
                // Adding a slight delay so it doesn't block main UI render
                setTimeout(buildAudioDatabase, 1500);
            }, []);

            // New States
            const [showExportConfirm, setShowExportConfirm] = useState(false);
            const [showDevDialog, setShowDevDialog] = useState(false);
            const [currentDua, setCurrentDua] = useState("");
            const [contextMenu, setContextMenu] = useState({ visible: false, x: 0, y: 0, segmentId: null });
            const [isSettingsCollapsed, setIsSettingsCollapsed] = useState(true); // NEW: Collapsible state for settings
            const [showCompositionTrimmer, setShowCompositionTrimmer] = useState(false);
            const [showImageEditor, setShowImageEditor] = useState(false); // Image Editor Modal State
            const [exportRange, setExportRange] = useState(null);

            // Favorites System State
            const [favorites, setFavorites] = useState(() => {
                try {
                    const saved = localStorage.getItem('quranShortsFavorites');
                    return saved ? JSON.parse(saved) : { video: [], audio: [], image: [], texture: [], combos: [] };
                } catch (e) {
                    return { video: [], audio: [], image: [], texture: [], combos: [] };
                }
            });
            const [showFavoritesOnly, setShowFavoritesOnly] = useState(false);

            // Auto-save favorites
            useEffect(() => {
                localStorage.setItem('quranShortsFavorites', JSON.stringify(favorites));
            }, [favorites]);

            const toggleFavorite = (type, filename) => {
                setFavorites(prev => {
                    const list = prev[type] || [];
                    const newList = list.includes(filename)
                        ? list.filter(f => f !== filename)
                        : [...list, filename];
                    return { ...prev, [type]: newList };
                });
            };
            // === States for Verse Extraction Mode Selection ===
            const [showExtractionModeModal, setShowExtractionModeModal] = useState(false);
            const [pendingAudioData, setPendingAudioData] = useState(null);
            // === State for Quran Selector Modal ===
            const [showQuranSelector, setShowQuranSelector] = useState(false);
            // Caption state for professional descriptions with hashtags
            const [currentCaption, setCurrentCaption] = useState(() => {
                const randomIndex = Math.floor(Math.random() * CAPTION_TEMPLATES.length);
                return CAPTION_TEMPLATES[randomIndex];
            });
            const [captionCopied, setCaptionCopied] = useState(false);

            /* مدخل رجوع واحد لكل طبقة النوافذ. الانتقال بين نافذتين (مثل
               اختيار ملف ثم فتح القص) يبقي المدخل نفسه؛ لو امتلكت كل نافذة
               مدخلًا مستقلًا فإن تنظيف الأولى ينفذ history.back بعد فتح
               الثانية، فيغلقها ويبطل blob URL الخاص بمعاينتها. */
            const hasOpenModal = Boolean(
                trimmingFile || showAudioChoice || showAutoGenerateModal ||
                showResetConfirm || alertModal.visible || showExportConfirm ||
                showDevDialog || showCompositionTrimmer || showImageEditor ||
                showExtractionModeModal || showQuranSelector || showTOD
            );
            useBackClose(hasOpenModal, () => {
                if (alertModal.visible) setAlertModal(p => ({ ...p, visible: false }));
                else if (showImageEditor) setShowImageEditor(false);
                else if (showCompositionTrimmer) setShowCompositionTrimmer(false);
                else if (trimmingFile) setTrimmingFile(null);
                else if (showQuranSelector) setShowQuranSelector(false);
                else if (showExtractionModeModal) { setShowExtractionModeModal(false); setPendingAudioData(null); }
                else if (showExportConfirm) setShowExportConfirm(false);
                else if (showResetConfirm) setShowResetConfirm(false);
                else if (showAutoGenerateModal) setShowAutoGenerateModal(false);
                else if (showAudioChoice) setShowAudioChoice(false);
                else if (showDevDialog) setShowDevDialog(false);
                else if (showTOD) setShowTOD(false);
            });

            // Volume State with Persistence
            // Volume State with Persistence
            const [volume, setVolume] = useState(() => {
                const s = localStorage.getItem(VOLUME_KEY);
                return s !== null ? parseFloat(s) : (window.innerWidth < 768 ? 1 : 0.5);
            });

            const gainNodeRef = useRef(null); // Add a reference for the GainNode

            // Effect to save volume & apply gain
            // Effect to save volume & apply gain
            useEffect(() => {
                localStorage.setItem(VOLUME_KEY, volume);

                // 1. Control Playback Volume via GainNode (User Experience)
                if (gainNodeRef.current && audioCtxRef.current) {
                    // Smooth transition to avoid clicking
                    gainNodeRef.current.gain.setTargetAtTime(volume, audioCtxRef.current.currentTime, 0.1);
                }

                // 2. Control Background Video Volume directly (User Experience)
                // ALWAYS MUTE VIDEO per user request
                if (videoRef.current) {
                    videoRef.current.muted = true;
                    videoRef.current.volume = 0;
                }

                // 3. CRITICAL: Keep Audio Element Volume at 100% for Recording
                // The MediaElementSourceNode extracts the audio. 
                // We want the source to be full strength for the export tap.
                if (audioRef.current) {
                    audioRef.current.volume = 1.0;
                }
            }, [volume]);

            // --- Custom Drag States ---
            const [isDragging, setIsDragging] = useState(false);
            const [draggedId, setDraggedId] = useState(null);
            const [dropTargetIndex, setDropTargetIndex] = useState(null);
            const [dragOverlayPos, setDragOverlayPos] = useState({ x: 0, y: 0 });
            const [dragStartOffset, setDragStartOffset] = useState({ x: 0, y: 0 });
            const [dragItemWidth, setDragItemWidth] = useState(0);
            const dragContainerRef = useRef(null);

            // Memory Management Ref
            const objectUrlsRef = useRef([]);

            // UseRef to store drag state for event listeners to avoid stale closures
            const dragLogicState = useRef({ draggedId: null, dropTargetIndex: null });

            // Tour State
            const [tourActive, setTourActive] = useState(false);
            const [tourStep, setTourStep] = useState(0);
            const longPressTimer = useRef(null);

            // Editor Panel Resizing State
            const [panelHeight, setPanelHeight] = useState(savedSettings?.panelHeight || 40);
            const [isPanelCollapsed, setIsPanelCollapsed] = useState(false);

            // Library View State (Embedded)
            const [panelSubView, setPanelSubView] = useState(null); // 'videoLib' | 'audioLib' | null
            const [playingAudioPreview, setPlayingAudioPreview] = useState(null);
            const videoLibScrollRef = useRef(null);
            const audioLibScrollRef = useRef(null);
            const imageLibScrollRef = useRef(null);

            // Scroll to top when library view opens and stop audio preview when closing
            useEffect(() => {
                if (panelSubView === 'videoLib' && videoLibScrollRef.current) {
                    videoLibScrollRef.current.scrollTop = 0;
                }
                if (panelSubView === 'imageLib' && imageLibScrollRef.current) {
                    imageLibScrollRef.current.scrollTop = 0;
                }
                if (panelSubView === 'audioLib' && audioLibScrollRef.current) {
                    audioLibScrollRef.current.scrollTop = 0;
                }
                // Stop audio preview when closing the library
                if (panelSubView !== 'audioLib') {
                    setPlayingAudioPreview(null);
                }
            }, [panelSubView]);


            const APP_STEPS = [
                { id: 'media', label: 'الوسائط', number: '1', icon: Layers },
                { id: 'content', label: 'الآيات', number: '2', icon: ListMusic },
                { id: 'style', label: 'التصميم', number: '3', icon: Palette },
                { id: 'export', label: 'الحفظ', number: '4', icon: Download }
            ];

            const videoLibraryFiles = useMemo(() => Array.from({ length: APP_CONFIG.videoCount }, (_, i) => `${i + 1}.mp4`), []);
            const imageLibraryFiles = useMemo(() => Array.from({ length: APP_CONFIG.imageCount }, (_, i) => `${i + 1}.jpg`), []);
            const audioLibraryFiles = useMemo(() => Array.from({ length: APP_CONFIG.audioCount }, (_, i) => `${i + 1}.mp3`), []);

            useEffect(() => {
                const tourDone = localStorage.getItem('quranShortsTourDone');
                if (!tourDone) setTourActive(true);
            }, []);

            useEffect(() => { localStorage.setItem('quranShortsSettings', JSON.stringify({ ayahStyle, watermark, overlaySettings, showSiteBranding, panelHeight })) }, [ayahStyle, watermark, overlaySettings, showSiteBranding, panelHeight]);

            // Comprehensive cleanup on unmount
            useEffect(() => {
                return () => {
                    // Cancel any running animations
                    if (animationRef.current) {
                        cancelAnimationFrame(animationRef.current);
                    }

                    // Clean all Object URLs
                    objectUrlsRef.current.forEach(url => {
                        try { URL.revokeObjectURL(url); } catch (e) { }
                    });
                    objectUrlsRef.current = [];

                    // Clean AudioContext and nodes
                    if (audioSourceNodeRef.current) {
                        try { audioSourceNodeRef.current.disconnect(); } catch (e) { }
                    }
                    if (gainNodeRef.current) {
                        try { gainNodeRef.current.disconnect(); } catch (e) { }
                    }
                    if (audioCtxRef.current) {
                        try { audioCtxRef.current.close(); } catch (e) { }
                    }

                    // Clean overlay image
                    if (overlayImageRef.current) {
                        overlayImageRef.current.src = '';
                        overlayImageRef.current = null;
                    }

                    // Release wake lock
                    if (wakeLockRef.current) {
                        try { wakeLockRef.current.release(); } catch (e) { }
                    }

                    // Clean video buffer canvas
                    if (videoBufferCanvas.current) {
                        const ctx = videoBufferCanvas.current.getContext('2d');
                        if (ctx) ctx.clearRect(0, 0, videoBufferCanvas.current.width, videoBufferCanvas.current.height);
                    }
                };
            }, []);

            // === Analytics: Track visitor and heartbeat ===
            useEffect(() => {
                trackAnalytics('visit');
                const heartbeat = setInterval(() => trackAnalytics('heartbeat'), 30000);
                return () => clearInterval(heartbeat);
            }, []);

            const createSafeUrl = (file) => {
                const url = URL.createObjectURL(file);
                objectUrlsRef.current.push(url);
                return url;
            };

            // Revoke only URLs that have actually been replaced. Active media
            // URLs must remain valid until their replacement is committed.
            const revokeTrackedUrls = (urls) => {
                const targets = new Set(urls || []);
                targets.forEach(url => {
                    try { URL.revokeObjectURL(url); } catch (e) { }
                });
                objectUrlsRef.current = objectUrlsRef.current.filter(url => !targets.has(url));
            };

            // Clean a specific URL (when replacing video/audio)
            const revokeUrl = (url) => {
                if (url && url.startsWith('blob:')) {
                    try { URL.revokeObjectURL(url); } catch (e) { }
                    objectUrlsRef.current = objectUrlsRef.current.filter(u => u !== url);
                }
            };

            // Clean up Audio Context nodes
            const cleanupAudioNodes = () => {
                if (audioSourceNodeRef.current) {
                    try { audioSourceNodeRef.current.disconnect(); } catch (e) { }
                    audioSourceNodeRef.current = null;
                }
            };

            // Clean up temporary HTML5 media elements
            const cleanupTempMediaElement = (element) => {
                if (element) {
                    try {
                        element.pause();
                        element.src = '';
                        element.load();
                    } catch (e) { }
                }
            };

            const handleTourNext = () => { if (tourStep < TOUR_STEPS.length - 1) setTourStep(tourStep + 1); else { setTourActive(false); localStorage.setItem('quranShortsTourDone', 'true'); setActiveTab('media'); } };
            const handleTourPrev = () => { if (tourStep > 0) setTourStep(tourStep - 1); };
            const handleTourSkip = () => { setTourActive(false); localStorage.setItem('quranShortsTourDone', 'true'); setActiveTab('media'); };

            const staticSurahInfo = useMemo(() => { if (!timelineData?.length) return ""; const v = timelineData.filter(s => s.surah && s.ayah); if (!v.length) return ""; const f = v[0], l = v[v.length - 1], s = toArabicNumerals(f.ayah), e = toArabicNumerals(l.ayah); return f.ayah === l.ayah ? `${f.surah} (${s})` : `${f.surah} (${s}) - (${e})` }, [timelineData]);
            const [dragState, setDragState] = useState({ isDragging: false, target: null, startY: 0, initialItemY: 0, startX: 0, initialItemX: 0 }), [snapState, setSnapState] = useState({ x: false, y: false }), [selectedElement, setSelectedElement] = useState(null), [isExporting, setIsExporting] = useState(false);
            const fileInputRef = useRef(null), renderState = useRef({ text: "", opacity: 0, surah: "", ayah: "" }), canvasRef = useRef(null), videoRef = useRef(null), audioRef = useRef(null), audioCtxRef = useRef(null), audioSourceNodeRef = useRef(null), animationRef = useRef(null), overlayImageRef = useRef(null), videoBufferCanvas = useRef(document.createElement('canvas'));

        const handleFileUpload = (e, type, mode = 'normal') => {
            const f = e.target.files[0]; if (!f) return;
            const limits = {
                bgImage: 32 * 1024 * 1024,
                audio: 40 * 1024 * 1024,
                video: (mode === 'extractAudio' ? 250 : 1024) * 1024 * 1024
            };
            const limit = limits[type] || (type === 'video' ? limits.video : limits.audio);
            if (f.size > limit) {
                setAlertModal({
                    visible: true,
                    title: 'الملف كبير جدًا',
                    message: `الحد المسموح لهذا النوع هو ${Math.round(limit / 1024 / 1024)} ميغابايت لحماية ذاكرة الجهاز.`,
                    isSuccess: false
                });
                e.target.value = null;
                return;
            }

                // Handle Background Image Upload
                if (type === 'bgImage') {
                    const u = createSafeUrl(f);
                    setBgType('image');
                    setBgImageSrc(u);
                    setImageTransform(DEFAULT_IMAGE_TRANSFORM);
                    const img = new Image();
                    img.onload = () => { bgImageRef.current = img; };
                    img.src = u;
                    e.target.value = null;
                    return;
                }

                if (type === 'video' && mode === 'extractAudio') { setTrimmingFile({ file: f, type: 'video', mode: 'extractAudio' }); setShowAudioChoice(false) } else { setTrimmingFile({ file: f, type, mode: 'normal' }); if (type === 'audio') { setShowAudioChoice(false); trackAnalytics('audio', { source: 'upload' }); } } e.target.value = null
            };
            const handleOverlayImageUpload = (e) => { const f = e.target.files[0]; if (f) { if (f.size > 8 * 1024 * 1024) { setAlertModal({ visible: true, title: 'الصورة كبيرة جدًا', message: 'الحد المسموح لصورة الطبقة هو 8 ميغابايت.', isSuccess: false }); e.target.value = null; return; } const r = new FileReader(); r.onloadend = () => setOverlaySettings(p => ({ ...p, imageSrc: r.result })); r.readAsDataURL(f) } };

            // ═══ استقبال مشاركة أندرويد (Share Target) — المرحلة 1 ═══
            //
            // هذا الطرف الثاني لما يفعله `sw.js`: لوحة مشاركة أندرويد تُرسل
            // POST إلى `/index.html`، فيلتقطه الـSW ويخزّن الملف ثم يحوّل إلى
            // هنا بـ`?shared=1`. بلا هذا المُستقبِل تُفتح الصفحة والملف قابعٌ
            // في المخزن لا يراه أحد — أي ميزةٌ معلَنة في لوحة النظام ولا تفعل
            // شيئًا، وهي أسوأ من غيابها.
            //
            // تُقرأ الحمولة من Cache API **مباشرة** لا بـ`fetch`: العنوان
            // `__shared-media` اصطناعي لا وجود له على الخادم، والقراءة المباشرة
            // تعني ألّا يحتاج معالج `fetch` أي استثناء له.
            useEffect(() => {
                if (new URLSearchParams(window.location.search).get('shared') !== '1') return;
                if (!window.caches) return;

                // تُنزَع العلامة من العنوان **قبل** أي `await`. لو أعاد المستخدم
                // التحميل بينما القراءة جارية لَأُعيد الاستقبال على مخزن قد
                // فُرِّغ، أو لَعاد فتح المشاهدة نفسها بلا سبب.
                try { window.history.replaceState(null, '', window.location.pathname); } catch (e) { /* لا شيء */ }

                (async () => {
                    try {
                        const cache = await window.caches.open('quran-share-inbox');
                        const res = await cache.match('./__shared-media');
                        if (!res) return;
                        // يُحذف بعد الالتقاط لا بعد النجاح: المقطع قد يبلغ مئات
                        // الميغابايت، وتركه محتجزًا في الحصة بلا واجهة تفرّغه
                        // تسريبُ تخزينٍ صامت.
                        await cache.delete('./__shared-media');

                        const blob = await res.blob();
                        if (!blob || !blob.size) return;

                        const name = decodeURIComponent(res.headers.get('X-Shared-Filename') || 'shared-media');
                        const mime = res.headers.get('X-Shared-Type') || blob.type || '';

                        // بعض تطبيقات المشاركة تُرسل بلا نوع MIME، فيُستأنس
                        // بالامتداد. والافتراض `video` لأن الفيديو هو الغالب
                        // ولأن مسار الفيديو يتعامل مع ملف بلا مسار صوت بأمان.
                        const isAudio = mime.startsWith('audio/') || /\.(mp3|m4a|aac|wav|ogg|opus|flac)$/i.test(name);

                        const file = new File([blob], name, { type: mime || (isAudio ? 'audio/mpeg' : 'video/mp4') });

                        // المسار نفسه الذي يسلكه الرفع اليدوي: نافذة التقليم
                        // ذاتها والتحقّق ذاته. لا فرع خاصًّا بالمشاركة يُصان
                        // على حدة ويتخلّف عن أخيه.
                        setTrimmingFile({ file, type: isAudio ? 'audio' : 'video', mode: 'normal' });
                        if (isAudio) setShowAudioChoice(false);
                        trackAnalytics(isAudio ? 'audio' : 'video', { source: 'share' });
                        if (window.AppShell) window.AppShell.haptic(12);
                    } catch (e) {
                        console.warn('[Share] تعذّر استقبال الملف المشارك:', e);
                    }
                })();
            }, []);
            useEffect(() => {
                if (overlaySettings.imageSrc) {
                    // Clean previous image if exists to prevent memory leak
                    if (overlayImageRef.current) {
                        overlayImageRef.current.src = '';
                        overlayImageRef.current = null;
                    }
                    const i = new Image();
                    i.src = overlaySettings.imageSrc;
                    i.onload = () => overlayImageRef.current = i;
                } else {
                    if (overlayImageRef.current) {
                        overlayImageRef.current.src = '';
                        overlayImageRef.current = null;
                    }
                }
            }, [overlaySettings.imageSrc]);
            const confirmReset = () => { setAyahStyle(DEFAULT_AYAH_STYLE); setWatermark(DEFAULT_WATERMARK); setOverlaySettings(DEFAULT_OVERLAY); setShowSiteBranding(DEFAULT_BRANDING); setPanelHeight(55); setImageTransform(DEFAULT_IMAGE_TRANSFORM); localStorage.removeItem('quranShortsSettings'); setShowResetConfirm(false) };
            // التصدير يمرّ عبر لوحة مشاركة أندرويد (`AppShell.saveFile`) لا عبر
            // `a.download`: النسخة الاحتياطية تُحفظ حيث يريدها المستخدم — درايف،
            // «ملفات»، واتساب — لا في مجلّد تنزيلات Chrome وحده. وهذا هو المعنى
            // العملي للنسخة الاحتياطية: أن تنجو من مسح بيانات Chrome، وحفظُها
            // داخل Chrome لا يُنجيها منه.
            //
            // وكانت النسخة السابقة لا تُبطل `createObjectURL` أبدًا — تسريبُ
            // ذاكرة يبقى إلى إغلاق التبويب. `saveFile` تتولّى الإبطال، والاحتياط
            // أدناه يفعله بمهلة سخيّة تناسب الأجهزة البطيئة.
            const handleExportSettings = () => {
                const b = new Blob([JSON.stringify({ ayahStyle, watermark, overlaySettings, showSiteBranding, panelHeight }, null, 2)], { type: 'application/json' });
                const name = `quran_shorts_settings_${Date.now()}.json`;
                if (window.AppShell) { window.AppShell.saveFile(b, name, { title: 'إعدادات قرآن شورتس' }); return; }
                const u = URL.createObjectURL(b), a = document.createElement('a');
                a.href = u; a.download = name; a.click();
                setTimeout(() => { try { URL.revokeObjectURL(u); } catch (e) { } }, 120000);
            };
            const handleImportSettings = (e) => { const f = e.target.files[0]; if (!f) return; const r = new FileReader(); r.onload = (ev) => { try { const i = JSON.parse(ev.target.result); if (i.ayahStyle) setAyahStyle(i.ayahStyle); if (i.watermark) setWatermark(i.watermark); if (i.overlaySettings) setOverlaySettings(i.overlaySettings); if (i.showSiteBranding !== undefined) setShowSiteBranding(i.showSiteBranding); if (i.panelHeight) setPanelHeight(i.panelHeight); setAlertModal({ visible: true, title: "تم بنجاح", message: "تم استيراد الإعدادات بنجاح!", isSuccess: true }) } catch (err) { setAlertModal({ visible: true, title: "خطأ", message: "ملف غير صالح", isSuccess: false }) } }; r.readAsText(f); e.target.value = null };

            const handleLibrarySelect = (src) => {
                setBgType('video');
                setTrimmingFile({ file: src, type: 'video', mode: 'normal' });
                setPanelSubView(null); // Close library view
            };

            const handleLibraryImageSelect = (src) => {
                setBgType('image');
                setBgImageSrc(src);
                setImageTransform(DEFAULT_IMAGE_TRANSFORM);
                // Preload image for canvas
                const img = new Image();
                img.onload = () => { bgImageRef.current = img; };
                img.src = src;
                setPanelSubView(null);
            };

            const handleAudioLibrarySelect = async (src) => {
                setPlayingAudioPreview(null); // Stop any playing preview
                setPanelSubView(null); // Close library view
                setShowAudioChoice(false);
                setIsProcessingAudio(true);
                setSelectedAudioName(src); // Track selected audio name
                trackAnalytics('audio', { source: 'library' }); // === Track audio from library ===
                try {
                    const r = await fetch(src), b = await r.blob(), f = new File([b], src.split('/').pop(), { type: "audio/mp3" }), js = src.replace('.mp3', '.json');
                    let jd = null;
                    try { const jr = await fetch(js); if (jr.ok) jd = await jr.json() } catch (e) { }
                    setTrimmingFile({ file: f, type: 'audio', mode: 'normal', jsonData: jd })
                } catch (e) {
                    setAiError("فشل تحميل الملف");
                    setSelectedAudioName(null); // Reset on error
                } finally {
                    setIsProcessingAudio(false)
                }
            };

            // --- Panel Resize Logic ---
            const handlePanelDragStart = (e) => {
                const startY = e.touches ? e.touches[0].clientY : e.clientY;
                const startHeight = panelHeight;
                const screenH = window.innerHeight;

                const handleMove = (moveEvent) => {
                    const currY = moveEvent.touches ? moveEvent.touches[0].clientY : moveEvent.clientY;
                    const deltaY = startY - currY; // Dragging up increases height (since top is 0)
                    const newH = startHeight + (deltaY / screenH * 100);

                    // Constraints: Min 20%, Max 85%
                    if (newH > 20 && newH < 85) {
                        setPanelHeight(newH);
                        setIsPanelCollapsed(false); // Auto expand if resizing
                    }
                };

                const handleUp = () => {
                    window.removeEventListener('mousemove', handleMove);
                    window.removeEventListener('mouseup', handleUp);
                    window.removeEventListener('touchmove', handleMove);
                    window.removeEventListener('touchend', handleUp);
                };

                window.addEventListener('mousemove', handleMove);
                window.addEventListener('mouseup', handleUp);
                window.addEventListener('touchmove', handleMove, { passive: false });
                window.addEventListener('touchend', handleUp);
            };

            const handleAutoGenerate = async (targetCategory) => {
                // Keep current media alive until every replacement is ready.
                // Revoking here used to leave <audio>/<video> pointing to a
                // dead blob URL while generation was still in progress.
                const supersededUrls = objectUrlsRef.current.slice();

                setShowAutoGenerateModal(false);
                setIsAutoGenerating(true);
                setAutoGenStep("جاري التجهيز...");

                // === Track smart selection ===
                trackAnalytics('smart', { category: targetCategory });

                try {
                    setAutoGenStep("اختيار تلاوة مناسبة من الفهرس...");
                    await new Promise(r => setTimeout(r, 400)); // Small delay for UI smoothness

                    let db = audioDBRef.current || [];

                    // Fallback just in case cache didn't finish loading
                    if (db.length === 0) {
                        setAutoGenStep("تحديث الفهرس (لمرة واحدة)...");
                        const totalAudios = APP_CONFIG.audioCount;
                        const batchSize = 10;
                        for (let batch = 0; batch < Math.ceil(totalAudios / batchSize); batch++) {
                            const batchPromises = [];
                            const startIdx = batch * batchSize + 1;
                            const endIdx = Math.min((batch + 1) * batchSize, totalAudios);
                            for (let i = startIdx; i <= endIdx; i++) {
                                const src = `audio4all/${i}.mp3`;
                                const loadPromise = new Promise((resolve) => {
                                    const audio = new Audio();
                                    const timeoutId = setTimeout(() => resolve(null), 10000);
                                    audio.onloadedmetadata = () => {
                                        clearTimeout(timeoutId);
                                        resolve({ src, duration: audio.duration, id: i });
                                    };
                                    audio.onerror = () => { clearTimeout(timeoutId); resolve(null); };
                                    audio.src = src;
                                });
                                batchPromises.push(loadPromise);
                            }
                            const results = await Promise.all(batchPromises);
                            db.push(...results.filter(r => r !== null));
                            setAutoGenStep(`تحديث الفهرس... ${Math.round((endIdx / totalAudios) * 100)}%`);
                        }
                        audioDBRef.current = db;
                    }

                    // 1. Filter by category
                    let validAudios = [];
                    if (targetCategory === 'any') validAudios = [...db];
                    else if (targetCategory === 'short') validAudios = db.filter(a => a.duration < 20);
                    else if (targetCategory === 'medium_short') validAudios = db.filter(a => a.duration >= 20 && a.duration < 35);
                    else if (targetCategory === 'medium') validAudios = db.filter(a => a.duration >= 35 && a.duration <= 50);
                    else if (targetCategory === 'long') validAudios = db.filter(a => a.duration > 50);

                    // Fallback if no files in category
                    if (validAudios.length === 0) validAudios = [...db];
                    if (validAudios.length === 0) validAudios = [{ id: 1, src: 'audio4all/1.mp3', duration: 60 }];

                    // 2. Advanced Anti-Repetition (LRU for Audio)
                    const AUDIO_HISTORY_KEY = 'quranShortsAudioHistory';
                    let audioHistory = [];
                    try { const stored = localStorage.getItem(AUDIO_HISTORY_KEY); if (stored) audioHistory = JSON.parse(stored); } catch (e) { }

                    let availableAudios = validAudios.filter(a => !audioHistory.includes(a.id));
                    if (availableAudios.length === 0) availableAudios = validAudios; // Reset if all used

                    const selectedAudio = availableAudios[Math.floor(Math.random() * availableAudios.length)];

                    audioHistory = [selectedAudio.id, ...audioHistory].slice(0, 20); // Keep last 20
                    try { localStorage.setItem(AUDIO_HISTORY_KEY, JSON.stringify(audioHistory)); } catch (e) { }

                    const sAud = selectedAudio.src;
                    const sDur = selectedAudio.duration;

                    // === SMART MEDIA SELECTION (Video OR Image) with Anti-Repetition ===
                    setAutoGenStep("اختيار خلفية عشوائية...");
                    await new Promise(r => setTimeout(r, 500));

                    // Anti-repetition system using localStorage
                    const HISTORY_KEY = 'quranShortsMediaHistory';
                    const MAX_HISTORY = 10; // Remember last 10 used media

                    // Get usage history from localStorage
                    let mediaHistory = { videos: [], images: [] };
                    try {
                        const stored = localStorage.getItem(HISTORY_KEY);
                        if (stored) mediaHistory = JSON.parse(stored);
                    } catch (e) { /* Use default empty history */ }

                    // Helper function to select random item avoiding recent history
                    const selectWithoutRepetition = (count, folder, ext, history) => {
                        // Create pool of all available items
                        const allItems = Array.from({ length: count }, (_, i) => i + 1);

                        // Filter out recently used items (if we have enough alternatives)
                        const available = allItems.filter(id => !history.includes(id));

                        // If all items are in history, use any item (reset scenario)
                        const pool = available.length > 0 ? available : allItems;

                        // Shuffle the pool for better randomness
                        for (let i = pool.length - 1; i > 0; i--) {
                            const j = Math.floor(Math.random() * (i + 1));
                            [pool[i], pool[j]] = [pool[j], pool[i]];
                        }

                        // Select first item from shuffled pool
                        const selectedId = pool[0];
                        return { id: selectedId, src: `${folder}/${selectedId}.${ext}` };
                    };

                    // 50% chance for video, 50% for image
                    const useVideo = Math.random() < 0.5;
                    let mediaSrc, mediaDur = 15, mediaType, selectedMediaId;

                    if (useVideo && APP_CONFIG.videoCount > 0) {
                        mediaType = 'video';
                        const selected = selectWithoutRepetition(
                            APP_CONFIG.videoCount,
                            'video4all',
                            'mp4',
                            mediaHistory.videos
                        );
                        mediaSrc = selected.src;
                        selectedMediaId = selected.id;

                        // Preload video metadata to get correct duration
                        const tempVideo = document.createElement('video');
                        tempVideo.preload = 'metadata';
                        tempVideo.src = mediaSrc;
                        await new Promise((resolve) => {
                            const timeoutId = setTimeout(resolve, 3000);
                            tempVideo.onloadedmetadata = () => {
                                clearTimeout(timeoutId);
                                mediaDur = tempVideo.duration || 15;
                                resolve();
                            };
                            tempVideo.onerror = () => {
                                clearTimeout(timeoutId);
                                resolve();
                            };
                        });
                        // Clean up temporary video element
                        cleanupTempMediaElement(tempVideo);

                        // Update video history
                        mediaHistory.videos = [selectedMediaId, ...mediaHistory.videos].slice(0, MAX_HISTORY);
                    } else if (APP_CONFIG.imageCount > 0) {
                        mediaType = 'image';
                        const selected = selectWithoutRepetition(
                            APP_CONFIG.imageCount,
                            'image4all',
                            'jpg',
                            mediaHistory.images
                        );
                        mediaSrc = selected.src;
                        selectedMediaId = selected.id;
                        mediaDur = sDur; // For images, duration matches audio

                        // Update image history
                        mediaHistory.images = [selectedMediaId, ...mediaHistory.images].slice(0, MAX_HISTORY);
                    } else {
                        // Fallback to video if no images available
                        mediaType = 'video';
                        mediaSrc = `video4all/1.mp4`;
                    }

                    // Save updated history to localStorage
                    try {
                        localStorage.setItem(HISTORY_KEY, JSON.stringify(mediaHistory));
                    } catch (e) { /* Storage might be full, ignore */ }

                    // === COMBINE MEDIA ===
                    setAutoGenStep("دمج الوسائط...");
                    await new Promise(r => setTimeout(r, 500));

                    const audioResponse = await fetch(sAud);
                    const audioBlob = await audioResponse.blob();
                    const audioFile = new File([audioBlob], sAud.split('/').pop(), { type: "audio/mp3" });

                    // Set media based on type
                    if (mediaType === 'video') {
                        setBgType('video');
                        setVideoSrc(mediaSrc);
                        setVideoRange({ start: 0, end: mediaDur });
                    } else {
                        setBgType('image');
                        setBgImageSrc(mediaSrc);
                        setImageTransform(DEFAULT_IMAGE_TRANSFORM);
                        // Preload image for canvas
                        const img = new Image();
                        img.onload = () => { bgImageRef.current = img; };
                        img.src = mediaSrc;
                        // For images, video range is set to match audio
                        setVideoRange({ start: 0, end: sDur });
                    }

                    setSelectedAudioName(sAud);

                    // Create audio URL
                    const audioUrl = createSafeUrl(audioFile);
                    setAudioSrc(audioUrl);
                    setAudioFile(audioFile);
                    setAudioRange({ start: 0, end: sDur });
                    setCurrentTime(0);
                    setExportRange(null);

                    // State now points at the new media. Keep the former blobs
                    // briefly so React and the media elements can commit/load
                    // the new src values even on a busy Android WebView.
                    setTimeout(() => revokeTrackedUrls(supersededUrls), 2000);

                    // Try to load JSON segments
                    const jsonPath = sAud.replace('.mp3', '.json');
                    let jsonData = null;
                    try {
                        const jsonResponse = await fetch(jsonPath);
                        if (jsonResponse.ok) jsonData = await jsonResponse.json();
                    } catch (e) { /* No JSON available */ }

                    if (jsonData?.segments) {
                        setTimelineData(prepareDisplaySegments(jsonData.segments, { start: 0, end: sDur }, { repairLegacyOverlaps: true }));
                        const mediaTypeLabel = mediaType === 'video' ? 'فيديو' : 'صورة';
                        setAlertModal({
                            visible: true,
                            title: "تم الإنشاء",
                            message: `تم اختيار تلاوة (${Math.round(sDur)}ث) وخلفية ${mediaTypeLabel} بنجاح.`,
                            isSuccess: true
                        });
                        setActiveTab('content');
                    } else {
                        await analyzeWithGemini(audioFile, { start: 0, end: sDur });
                    }

                } catch (e) {
                    console.error('Smart Generate Error:', e);
                    setAiError("خطأ في الإنشاء التلقائي");
                } finally {
                    setIsAutoGenerating(false);
                }
            };

            const handleTrimConfirm = async (rng) => {
                if (!trimmingFile) return;
                const { file, type, mode, jsonData } = trimmingFile;

                // Handle extractAudio mode (from video)
                if (mode === 'extractAudio') {
                    setIsProcessingAudio(true);
                    setTrimmingFile(null);
                    try {
                        const wb = await extractAudioFromVideo(file, rng.start, rng.end);
                        const wf = new File([wb], "extracted.wav", { type: "audio/wav" });
                        const u = createSafeUrl(wf);
                        setAudioSrc(u);
                        setAudioFile(wf);
                        const nd = rng.end - rng.start;
                        setAudioRange({ start: 0, end: nd });
                        setCurrentTime(0);
                        setExportRange(null);
                        // === Show extraction mode modal instead of direct AI analysis ===
                        setPendingAudioData({ file: wf, range: { start: 0, end: nd } });
                        setShowExtractionModeModal(true);
                    } catch (e) {
                        setAiError("فشل الاستخراج");
                    } finally {
                        setIsProcessingAudio(false);
                    }
                    return;
                }

                const u = typeof file === 'string' ? file : createSafeUrl(file);

                if (type === 'video') {
                    setBgType('video');
                    setVideoSrc(u);
                    setVideoRange(rng);
                    setTimeout(() => { if (videoRef.current) videoRef.current.currentTime = rng.start }, 50);
                } else {
                    // Audio type
                    setAudioSrc(u);
                    setAudioFile(file);
                    setAudioRange(rng);
                    setCurrentTime(rng.start);

                    if (jsonData?.segments) {
                        const rangedSegments = selectSegmentsForRange(jsonData.segments, rng);
                        if (rangedSegments.length > 0) {
                            setActiveTab('content');
                            setTimelineData(prepareDisplaySegments(rangedSegments, rng, { repairLegacyOverlaps: true }));
                            setAlertModal({ visible: true, title: "تم تحميل البيانات", message: "تم تحميل تفاصيل الآيات ضمن الجزء المحدد.", isSuccess: true });
                        } else {
                            setTimelineData([]);
                            setPendingAudioData({ file, range: rng });
                            setShowExtractionModeModal(true);
                        }
                    } else {
                        // === Show extraction mode modal instead of direct AI analysis ===
                        setPendingAudioData({ file, range: rng });
                        setShowExtractionModeModal(true);
                    }
                }

                setTrimmingFile(null);
                setExportRange(null);
            };

            // === Handler for extraction mode selection ===
            const handleExtractionModeConfirm = (mode) => {
                setShowExtractionModeModal(false);

                if (!pendingAudioData) return;

                if (mode === 'auto') {
                    // Use AI analysis as before
                    analyzeWithGemini(pendingAudioData.file, pendingAudioData.range);
                } else {
                    // Manual mode - go to content tab and open Quran selector
                    setActiveTab('content');
                    // Don't create empty segment - let user add via Quran selector
                    setTimelineData([]);
                    // Open Quran selector automatically
                    setTimeout(() => setShowQuranSelector(true), 300);
                    setAlertModal({
                        visible: true,
                        title: "الوضع اليدوي",
                        message: "اختر الآيات التي تريد إضافتها من القرآن الكريم",
                        isSuccess: true
                    });
                }

                setPendingAudioData(null);
            };

            // === Handler for adding ayah from Quran selector ===
            const handleAddAyah = (ayahData) => {
                const nextSegment = {
                    id: Date.now(),
                    text: ayahData.text,
                    canonicalText: ayahData.text,
                    surah: ayahData.surah,
                    ayah: ayahData.ayah,
                    start: ayahData.start,
                    end: ayahData.end
                };
                setTimelineData(prev => [...prev, nextSegment].sort((a, b) => a.start - b.start));
            };

            const handleSetCurrentTime = (id, f) => { if (!audioRef.current) return; const t = audioRef.current.currentTime; setTimelineData(p => p.map(i => i.id === id ? { ...i, [f]: parseFloat(t.toFixed(2)) } : i)) };
            // انظر شرح `handleExportSettings` أعلاه — الحفظ عبر لوحة المشاركة
            // وإبطال العنوان.
            const handleExportTimelineJSON = () => {
                const d = JSON.stringify({ segments: timelineData.map(({ id, ...r }) => r) }, null, 2);
                const b = new Blob([d], { type: "application/json" });
                const name = `quran_shorts_data_${Date.now()}.json`;
                if (window.AppShell) { window.AppShell.saveFile(b, name, { title: 'بيانات المقطع الزمني' }); return; }
                const u = URL.createObjectURL(b), a = document.createElement('a');
                a.href = u; a.download = name; a.click();
                setTimeout(() => { try { URL.revokeObjectURL(u); } catch (e) { } }, 120000);
            };
            const handleStepSeek = (amt) => { if (!audioSrc) return; const nt = Math.min(Math.max(audioRange.start, currentTime + amt), audioRange.end); if (audioRef.current) audioRef.current.currentTime = nt; if (videoRef.current && videoSrc) { const d = videoRange.end - videoRange.start; if (d > 0.1) videoRef.current.currentTime = videoRange.start + ((nt - audioRange.start) % d) } setCurrentTime(nt) };
            useEffect(() => { const h = (e) => { if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.repeat || !audioSrc) return; if (e.code === 'Space') { e.preventDefault(); togglePlay() } else if (e.code === 'ArrowRight') { e.preventDefault(); handleStepSeek(1) } else if (e.code === 'ArrowLeft') { e.preventDefault(); handleStepSeek(-1) } }; window.addEventListener('keydown', h); return () => window.removeEventListener('keydown', h) }, [audioSrc, isPlaying, currentTime, audioRange, videoRange]);

            // --- PROFESSIONAL LOOPING & SYNC ENGINE ---
            useEffect(() => {
                let rId;
                let lastTime = 0;

                const loop = (ts) => {
                    if (!isPlaying) return;

                    // Throttle updates slightly to spare CPU, but keep high enough for 60fps feel
                    if (ts - lastTime < 16) {
                        rId = requestAnimationFrame(loop);
                        return;
                    }
                    lastTime = ts;

                    const a = audioRef.current;
                    const v = videoRef.current;

                    if (a && audioSrc) {
                        const n = a.currentTime;

                        const aRange = exportRange || audioRange;
                        // Check Audio End
                        if (n >= aRange.end) {
                            pauseAll();
                            setCurrentTime(aRange.end);
                            return;
                        }

                        if (v && videoSrc) {
                            const vDuration = videoRange.end - videoRange.start;
                            // Calculate where the video SHOULD be based on audio progress
                            // Mapping audio elapsed time to video segment time (modulo duration)
                            // This effectively loops the video segment virtually
                            if (vDuration > 0.1) {
                                const audioElapsed = n - audioRange.start;
                                const expectedVideoTime = videoRange.start + (Math.max(0, audioElapsed) % vDuration);

                                // SMART SYNC: Only force seek if drift is noticeable (> 0.4s)
                                // This allows native playback to run smoothly without stuttering from constant seeking
                                const drift = Math.abs(v.currentTime - expectedVideoTime);

                                if (drift > 0.4) {
                                    // === FIX: Skip sync during export to prevent stuttering ===
                                    if (isExporting) {
                                        // During export, let video play naturally without seeking
                                        // This prevents the lag/stuttering at the start
                                    } else {
                                        // If we are at the loop point (end -> start), seeking is expected
                                        // But if we are just drifting in middle, correct it.
                                        // We check if the difference is due to wrapping around the loop
                                        const isLoopWrap = Math.abs(drift - vDuration) < 0.5;

                                        if (!isLoopWrap) {
                                            v.currentTime = expectedVideoTime;
                                        }
                                    }
                                }

                                // Ensure video is playing if audio is playing
                                if (v.paused && !a.paused && v.readyState >= 2) {
                                    v.play().catch(() => { });
                                }

                                // Use Native Looping for better performance if using full video
                                if (Math.abs(v.duration - vDuration) < 0.5) {
                                    if (!v.loop) v.loop = true;
                                } else {
                                    if (v.loop) v.loop = false;
                                    // Manual loop for segments
                                    if (v.currentTime >= videoRange.end - 0.2) {
                                        v.currentTime = videoRange.start;
                                    }
                                }
                            }
                        }
                        setCurrentTime(n);
                        rId = requestAnimationFrame(loop);
                    }
                };

                if (isPlaying) rId = requestAnimationFrame(loop);
                return () => cancelAnimationFrame(rId);
            }, [isPlaying, audioSrc, videoSrc, audioRange, videoRange, isExporting]);

            const pauseAll = () => { if (videoRef.current) videoRef.current.pause(); if (audioRef.current) audioRef.current.pause(); setIsPlaying(false); typeof releaseWakeLock === 'function' && releaseWakeLock(); };
            const togglePlay = async () => { if (!audioSrc || (bgType === 'video' && !videoSrc) || (bgType === 'image' && !bgImageSrc) || isAnalyzingAI || isProcessingAudio) return; const a = audioRef.current, v = videoRef.current; if (!a.paused) { setIsPlaying(false); a.pause(); if (bgType === 'video' && v) v.pause(); typeof releaseWakeLock === 'function' && releaseWakeLock(); } else { setIsPlaying(true); typeof requestWakeLock === 'function' && requestWakeLock(); try { const aRange = exportRange || audioRange; if (a.currentTime >= aRange.end - 0.1) a.currentTime = aRange.start; if (bgType === 'video' && v && videoSrc) { const vd = videoRange.end - videoRange.start; if (vd > 0.1) v.currentTime = videoRange.start + (Math.max(0, a.currentTime - audioRange.start) % vd); await Promise.all([a.play(), v.play()]) } else { await a.play(); } } catch (e) { if (a.paused) { setIsPlaying(false); typeof releaseWakeLock === 'function' && releaseWakeLock(); } } } };
            const handleWaveformSeek = (t) => { if (!audioSrc || isExporting) return; const at = audioRange.start + t; if (audioRef.current) audioRef.current.currentTime = at; if (videoRef.current && videoSrc) { const vd = videoRange.end - videoRange.start; if (vd > 0.1) videoRef.current.currentTime = videoRange.start + ((at - audioRange.start) % vd) } setCurrentTime(at) };
            const handleSegmentTimeChange = (id, f, v) => {
                const value = parseFloat(v);
                if (!Number.isFinite(value)) return;
                setTimelineData(previous => {
                    const candidate = previous.map(item => item.id === id ? { ...item, [f]: value } : item).sort((a, b) => a.start - b.start);
                    const result = window.QuranDataValidator.validateSegments(candidate, { start: audioRange.start, end: audioRange.end, surahList: window.__quranSurahList || [] });
                    if (!result.ok) {
                        setAiError('التوقيت غير صالح: يجب أن تكون المقاطع مرتبة وداخل مدة الصوت ومن دون تداخل.');
                    } else {
                        setAiError(null);
                    }
                    return candidate;
                });
            };

            // Initial Audio Context Setup
            useEffect(() => {
                if (audioSrc && audioRef.current) {
                    if (!audioCtxRef.current) audioCtxRef.current = new (window.AudioContext || window.webkitAudioContext)();

                    // Create Gain Node if not exists
                    if (!gainNodeRef.current) {
                        const g = audioCtxRef.current.createGain();
                        g.connect(audioCtxRef.current.destination);
                        gainNodeRef.current = g;
                        // Set initial volume immediately
                        g.gain.value = volume;
                    }

                    if (!audioSourceNodeRef.current) {
                        try {
                            const n = audioCtxRef.current.createMediaElementSource(audioRef.current);
                            n.connect(gainNodeRef.current); // Connect Source -> Gain -> Speakers
                            audioSourceNodeRef.current = n;
                        } catch (e) { console.error(e); }
                    }
                }
            }, [audioSrc]); // Remove volume dependency here to avoid recreating graph

            const analyzeWithGemini = async (file, rng) => {
                setActiveTab('content'); setIsAnalyzingAI(true); setAiError(null); setTimelineData([]); setAiStatus("جاري التحليل...");
                try {
                    if (!(file instanceof Blob)) throw new Error('ملف الصوت غير صالح');
                    if (file.size > 20 * 1024 * 1024) throw new Error('حجم الملف أكبر من الحد المسموح (20 ميغابايت)');
                    if (!Number.isFinite(rng?.start) || !Number.isFinite(rng?.end) || rng.start < 0 || rng.end <= rng.start || rng.end - rng.start > 300) {
                        throw new Error('نطاق التحليل غير صالح أو أطول من خمس دقائق');
                    }
                    const formData = new FormData();
                    formData.append('audio', file, file.name || 'recitation.mp3');
                    formData.append('start', String(rng.start));
                    formData.append('end', String(rng.end));
                    const res = await fetch(QURAN_ANALYSIS_ENDPOINT, { method: 'POST', body: formData, credentials: 'same-origin' });
                    const payload = await res.json().catch(() => ({}));
                    if (!res.ok || !payload.ok) throw new Error(payload.error || `تعذر التحليل (${res.status})`);
                    const rs = payload.result;
                    if (rs.refusal) { setAlertModal({ visible: true, title: "محتوى غير مطابق", message: "لم يتم التعرف على تلاوة قرآنية.", isSuccess: false }); return }
                    setTimelineData(prepareDisplaySegments(rs.segments, rng));
                    setAlertModal({ visible: true, title: "تم التحليل والتحقق", message: "اجتازت النتيجة التحقق البنيوي والزمني. راجع المطابقة السمعية قبل التصدير.", isSuccess: true });
                } catch (e) {
                    console.error(e);
                    setAiError("خطأ: " + e.message);
                    setAlertModal({ visible: true, title: "خطأ في التحليل", message: `حدث خطأ أثناء تحليل الملف: ${e.message}`, isSuccess: false });
                } finally { setIsAnalyzingAI(false); setAiStatus("") }
            };

            // --- Drag & Drop Handlers ---
            const handleDragStart = (e, id) => {
                e.preventDefault();
                e.stopPropagation();

                const itemEl = e.currentTarget.closest('.draggable-item');
                if (!itemEl) return;

                const rect = itemEl.getBoundingClientRect();
                const touch = e.touches ? e.touches[0] : e;

                setIsDragging(true);
                setDraggedId(id);
                setDragItemWidth(rect.width);
                setDragStartOffset({ x: touch.clientX - rect.left, y: touch.clientY - rect.top });
                setDragOverlayPos({ x: rect.left, y: rect.top });

                dragLogicState.current = { draggedId: id, dropTargetIndex: null };

                if (e.type === 'touchstart') {
                    window.addEventListener('touchmove', handleGlobalMove, { passive: false });
                    window.addEventListener('touchend', handleGlobalEnd);
                } else {
                    window.addEventListener('mousemove', handleGlobalMove);
                    window.addEventListener('mouseup', handleGlobalEnd);
                }
            };

            const handleGlobalMove = (e) => {
                e.preventDefault();
                const clientY = e.touches ? e.touches[0].clientY : e.clientY;
                const clientX = e.touches ? e.touches[0].clientX : e.clientX;

                setDragOverlayPos({ x: clientX - dragStartOffset.x, y: clientY - dragStartOffset.y });

                if (dragContainerRef.current) {
                    const items = Array.from(dragContainerRef.current.querySelectorAll('.draggable-item'));
                    let closestIndex = items.length;

                    for (let i = 0; i < items.length; i++) {
                        const rect = items[i].getBoundingClientRect();
                        const midY = rect.top + rect.height / 2;
                        if (clientY < midY) {
                            closestIndex = i;
                            break;
                        }
                    }
                    setDropTargetIndex(closestIndex);
                    dragLogicState.current.dropTargetIndex = closestIndex;
                }
            };

            const handleGlobalEnd = () => {
                const { draggedId: savedDraggedId, dropTargetIndex: savedDropTargetIndex } = dragLogicState.current;

                if (savedDraggedId !== null && savedDropTargetIndex !== null) {
                    setTimelineData(prev => {
                        const originalIndex = prev.findIndex(item => item.id === savedDraggedId);
                        if (originalIndex !== -1 && savedDropTargetIndex !== originalIndex && savedDropTargetIndex !== originalIndex + 1) {
                            const newData = [...prev];
                            const [movedItem] = newData.splice(originalIndex, 1);
                            let finalIndex = savedDropTargetIndex;
                            if (originalIndex < savedDropTargetIndex) finalIndex -= 1;
                            newData.splice(finalIndex, 0, movedItem);
                            return newData;
                        }
                        return prev;
                    });
                }

                setIsDragging(false);
                setDraggedId(null);
                setDropTargetIndex(null);
                dragLogicState.current = { draggedId: null, dropTargetIndex: null };

                window.removeEventListener('mousemove', handleGlobalMove);
                window.removeEventListener('mouseup', handleGlobalEnd);
                window.removeEventListener('touchmove', handleGlobalMove);
                window.removeEventListener('touchend', handleGlobalEnd);
            };

            // --- Context Menu Handlers ---
            const handleContextMenu = (e, segmentId) => { e.preventDefault(); setContextMenu({ visible: true, x: e.clientX, y: e.clientY, segmentId }); };
            const closeContextMenu = () => setContextMenu({ visible: false, x: 0, y: 0, segmentId: null });
            useEffect(() => { window.addEventListener('click', closeContextMenu); return () => window.removeEventListener('click', closeContextMenu); }, []);
            const handleDeleteSegment = () => { if (contextMenu.segmentId) setTimelineData(prev => prev.filter(s => s.id !== contextMenu.segmentId)); };
            const handleDuplicateSegment = () => { if (contextMenu.segmentId) { const segment = timelineData.find(s => s.id === contextMenu.segmentId); if (segment) { const newSegment = { ...segment, id: Date.now() }; const index = timelineData.findIndex(s => s.id === contextMenu.segmentId); const newTimeline = [...timelineData]; newTimeline.splice(index + 1, 0, newSegment); setTimelineData(newTimeline); } } };
            const startPress = (e, id) => { e.persist(); longPressTimer.current = setTimeout(() => { const touch = e.touches ? e.touches[0] : e; setContextMenu({ visible: true, x: touch.clientX, y: touch.clientY, segmentId: id }); }, 600); };
            const cancelPress = () => { if (longPressTimer.current) clearTimeout(longPressTimer.current); };

            useEffect(() => { const l = () => { draw(); animationRef.current = requestAnimationFrame(l) }; l(); return () => cancelAnimationFrame(animationRef.current) }, [timelineData, ayahStyle, watermark, currentTime, dragState, overlaySettings, overlayImageRef.current, snapState, selectedElement, showSiteBranding, bgType, videoSrc, bgImageSrc, imageTransform]);
            const activeRange = exportRange || audioRange;
            const totalDuration = audioSrc ? (activeRange.end - activeRange.start) : 0, currentProgress = audioSrc ? (currentTime - activeRange.start) : 0;
            const draw = () => {
                const c = canvasRef.current; if (!c) return; const ctx = c.getContext('2d');
                if (bgType === 'image' && bgImageRef.current) {
                    const img = bgImageRef.current;
                    const { croppedAreaPixels } = imageTransform;

                    // 1. Draw Blurred Background always (prevents empty frames/black bars)
                    ctx.save();
                    const bgS = Math.max(c.width / img.width, c.height / img.height);
                    const bgX = (c.width / 2) - (img.width / 2) * bgS;
                    const bgY = (c.height / 2) - (img.height / 2) * bgS;
                    ctx.filter = 'blur(25px) brightness(0.5)';
                    ctx.drawImage(img, bgX, bgY, img.width * bgS, img.height * bgS);
                    ctx.restore();

                    // 2. Draw Transformed Image based on exact croppedAreaPixels from react-easy-crop
                    if (croppedAreaPixels) {
                        const crop = croppedAreaPixels;
                        // Math: The crop area represents the window of the canvas over the image.
                        // So canvas scale ratio = Canvas Width / Crop Width
                        const ratioX = c.width / crop.width;
                        const ratioY = c.height / crop.height;

                        // We scale the whole image by this ratio, and translate it by -crop.x * ratio
                        const drawWidth = img.width * ratioX;
                        const drawHeight = img.height * ratioY;
                        const drawX = -crop.x * ratioX;
                        const drawY = -crop.y * ratioY;

                        ctx.drawImage(img, drawX, drawY, drawWidth, drawHeight);
                    } else {
                        // Fallback draw (just in case)
                        ctx.drawImage(img, bgX, bgY, img.width * bgS, img.height * bgS);
                    }
                } else if (bgType === 'video' && videoRef.current) { const v = videoRef.current, oc = videoBufferCanvas.current.getContext('2d'); if (v.readyState >= 2) { videoBufferCanvas.current.width = c.width; videoBufferCanvas.current.height = c.height; const s = Math.max(c.width / v.videoWidth, c.height / v.videoHeight), x = (c.width / 2) - (v.videoWidth / 2) * s, y = (c.height / 2) - (v.videoHeight / 2) * s; oc.drawImage(v, x, y, v.videoWidth * s, v.videoHeight * s) } if (videoBufferCanvas.current.width > 0) ctx.drawImage(videoBufferCanvas.current, 0, 0); else { ctx.fillStyle = '#111827'; ctx.fillRect(0, 0, c.width, c.height) } } else { ctx.fillStyle = '#111827'; ctx.fillRect(0, 0, c.width, c.height) }
                const colorOp = overlaySettings.colorOpacity !== undefined ? overlaySettings.colorOpacity : (overlaySettings.opacity || 0); if (colorOp > 0) { ctx.save(); ctx.globalAlpha = colorOp; ctx.fillStyle = overlaySettings.value || '#000000'; ctx.fillRect(0, 0, c.width, c.height); ctx.restore(); } if (overlayImageRef.current) { const imgOp = overlaySettings.imageOpacity !== undefined ? overlaySettings.imageOpacity : (overlaySettings.opacity || 0); if (imgOp > 0) { ctx.save(); ctx.globalAlpha = imgOp; const i = overlayImageRef.current, s = Math.max(c.width / i.width, c.height / i.height), x = (c.width / 2) - (i.width / 2) * s, y = (c.height / 2) - (i.height / 2) * s; ctx.drawImage(i, x, y, i.width * s, i.height * s); ctx.restore(); } }
                const seg = timelineData.find(s => currentTime >= s.start && currentTime < s.end);

                if (seg) {
                    const rs = renderState.current;
                    rs.text = seg.text; rs.surah = seg.surah; rs.ayah = seg.ayah;
                    const elapsed = currentTime - seg.start;
                    const duration = seg.end - seg.start;
                    const timeLeft = seg.end - currentTime;

                    let op = 1;
                    let offsetY = 0;
                    let scale = 1;
                    let drawText = rs.text;
                    const animType = ayahStyle.animation || 'fade';
                    const fadeTime = 0.4;

                    const actualFadeTime = Math.min(fadeTime, duration / 2);
                    const fadeOp = actualFadeTime > 0 ? Math.min(Math.max(elapsed / actualFadeTime, 0), Math.max(timeLeft / actualFadeTime, 0), 1) : 1;
                    const inProgress = actualFadeTime > 0 ? Math.min(elapsed / actualFadeTime, 1) : 1;
                    const outProgress = actualFadeTime > 0 ? Math.min(timeLeft / actualFadeTime, 1) : 1;

                    let blurVal = 0;
                    let isKaraoke = false;
                    let wipeProgress = 0;
                    let offsetX = 0;
                    let scaleY = 1;
                    let isReveal = false;
                    let revealProgress = 1;
                    let glowVal = 0;
                    let glowOpacity = 0;

                    if (animType === 'fade') {
                        op = fadeOp;
                    } else if (animType === 'slide_up') {
                        op = fadeOp;
                        offsetY = 30 * (1 - inProgress) + 30 * (1 - outProgress);
                    } else if (animType === 'scale') {
                        op = fadeOp;
                        scale = 1.0 - 0.2 * (1 - inProgress) - 0.2 * (1 - outProgress);
                    } else if (animType === 'pop') {
                        op = fadeOp;
                        const popIn = inProgress < 1 ? (inProgress < 0.7 ? (inProgress / 0.7) * 1.15 : 1.15 - ((inProgress - 0.7) / 0.3) * 0.15) : 1;
                        const popOut = outProgress < 1 ? (outProgress < 0.7 ? (outProgress / 0.7) * 1.15 : 1.15 - ((outProgress - 0.7) / 0.3) * 0.15) : 1;
                        scale = popIn * popOut;
                    } else if (animType === 'blur') {
                        op = fadeOp;
                        blurVal = 15 * (1 - inProgress) + 15 * (1 - outProgress);
                    } else if (animType === 'float') {
                        op = fadeOp;
                        offsetY = Math.sin(elapsed * 3) * 8;
                    } else if (animType === 'karaoke') {
                        op = fadeOp;
                        isKaraoke = true;
                        wipeProgress = duration > 0 ? Math.min(elapsed / (duration * 0.8), 1) : 1;
                    } else if (animType === 'glow_pulse') {
                        op = fadeOp;
                        const pulse = (Math.sin(elapsed * 2.5) + 1) / 2;
                        glowVal = 15 + pulse * 25;
                        glowOpacity = 0.5 + pulse * 0.5;
                        scale = 1.0 + pulse * 0.015;
                    } else if (animType === 'pan') {
                        op = fadeOp;
                        offsetX = duration > 0 ? 30 - 60 * (elapsed / duration) : 0;
                    } else if (animType === 'reveal') {
                        op = fadeOp;
                        isReveal = true;
                        revealProgress = Math.min(inProgress, outProgress);
                    } else if (animType === 'fold') {
                        op = fadeOp;
                        scaleY = Math.sin(inProgress * Math.PI / 2) * Math.sin(outProgress * Math.PI / 2);
                    } else if (animType === 'focus_pull') {
                        op = fadeOp;
                        blurVal = 20 * (1 - inProgress) + 20 * (1 - outProgress);
                        scale = 1.0 + 0.2 * (1 - inProgress) + 0.2 * (1 - outProgress);
                    } else if (animType === 'typewriter') {
                        op = Math.min(elapsed / 0.1, timeLeft / 0.1, 1);
                        const totalChars = rs.text.length;
                        const animDuration = duration / 3;
                        const inChars = animDuration > 0 ? Math.floor((elapsed / animDuration) * totalChars) : totalChars;
                        const outChars = animDuration > 0 ? Math.floor((timeLeft / animDuration) * totalChars) : totalChars;
                        const charsToShow = Math.min(inChars, outChars, totalChars);
                        drawText = rs.text.substring(0, Math.max(0, charsToShow));
                    } else if (animType === 'word_by_word') {
                        op = Math.min(elapsed / 0.1, timeLeft / 0.1, 1);
                        const words = rs.text.split(' ');
                        const totalWords = words.length;
                        const animDuration = duration / 3;
                        const inWords = animDuration > 0 ? Math.floor((elapsed / animDuration) * totalWords) : totalWords;
                        const outWords = animDuration > 0 ? Math.floor((timeLeft / animDuration) * totalWords) : totalWords;
                        const wordsToShow = Math.min(inWords, outWords, totalWords);
                        drawText = words.slice(0, Math.max(0, wordsToShow)).join(' ');
                    } else if (animType === 'calm_word') {
                        op = 1; // Handled dynamically per-word later
                        drawText = rs.text; // Ensure we pass the rendering condition
                    }

                    if (op > 0.01 && drawText) {
                        ctx.save();
                        ctx.globalAlpha = op;
                        ctx.textAlign = 'center';
                        ctx.textBaseline = 'middle';

                        let fs = ayahStyle.size;
                        const fw = ayahStyle.fontWeight || 'normal';
                        ctx.font = `${fw} ${fs}px ${ayahStyle.font.split(',')[0]}`;
                        const mw = CANVAS_WIDTH - 160;
                        let tw = ctx.measureText(rs.text).width;
                        while (tw > mw && fs > 20) {
                            fs -= 2;
                            ctx.font = `${fw} ${fs}px ${ayahStyle.font.split(',')[0]}`;
                            tw = ctx.measureText(rs.text).width;
                        }

                        if (selectedElement === 'ayah' && !isExporting) {
                            ctx.shadowColor = 'rgba(16,185,129,0.9)';
                            ctx.shadowBlur = 50;
                        } else {
                            const sOp = ayahStyle.shadowOpacity !== undefined ? ayahStyle.shadowOpacity : 0.5;
                            const hex = ayahStyle.shadowColor || '#000000';
                            const r = parseInt(hex.slice(1, 3), 16), g = parseInt(hex.slice(3, 5), 16), b = parseInt(hex.slice(5, 7), 16);
                            ctx.shadowColor = `rgba(${r},${g},${b},${sOp})`;
                            ctx.shadowBlur = 4;
                            ctx.shadowOffsetX = 4;
                            ctx.shadowOffsetY = 4;
                        }

                        ctx.lineWidth = 4;
                        ctx.strokeStyle = 'black';

                        ctx.translate(ayahStyle.x + offsetX, ayahStyle.y + offsetY);
                        if (scale !== 1 || scaleY !== 1) ctx.scale(scale, scale * scaleY);
                        if (blurVal > 0) ctx.filter = `blur(${blurVal}px)`;

                        if (animType === 'glow_pulse') {
                            const hex = ayahStyle.shadowColor || '#000000';
                            const colorHex = (hex === '#000000' && ayahStyle.color) ? ayahStyle.color : hex;
                            let r = 255, g = 255, b = 255;
                            if (colorHex.startsWith('#') && colorHex.length >= 7) {
                                r = parseInt(colorHex.slice(1, 3), 16);
                                g = parseInt(colorHex.slice(3, 5), 16);
                                b = parseInt(colorHex.slice(5, 7), 16);
                            }

                            ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0;
                            ctx.fillStyle = ayahStyle.color;

                            // Layer 1: Ambient wide bloom
                            ctx.shadowColor = `rgba(${r},${g},${b},${glowOpacity * 0.3})`;
                            ctx.shadowBlur = glowVal * 1.5;
                            ctx.fillText(drawText, 0, 0);

                            // Layer 2: Intense tight glow
                            ctx.shadowColor = `rgba(${r},${g},${b},${glowOpacity * 0.8})`;
                            ctx.shadowBlur = glowVal * 0.5;
                            ctx.fillText(drawText, 0, 0);

                            // Layer 3: Crisp core text
                            ctx.shadowColor = 'transparent';
                            ctx.strokeText(drawText, 0, 0);
                            ctx.fillText(drawText, 0, 0);
                        } else if (isKaraoke) {
                            ctx.globalAlpha = op * 0.4;
                            ctx.strokeText(drawText, 0, 0);
                            ctx.fillStyle = ayahStyle.color;
                            ctx.fillText(drawText, 0, 0);

                            ctx.globalAlpha = op;
                            ctx.save();
                            ctx.beginPath();
                            ctx.rect(tw / 2 - tw * wipeProgress, -fs * 2, tw * wipeProgress, fs * 4);
                            ctx.clip();
                            ctx.strokeText(drawText, 0, 0);
                            ctx.fillStyle = ayahStyle.color;
                            ctx.fillText(drawText, 0, 0);
                            ctx.restore();
                        } else if (animType === 'calm_word') {
                            const words = rs.text.split(' ');
                            const totalWords = words.length;

                            // 1. Line Wrapping Logic (Crucial for long verses)
                            let currentLine = [];
                            const lines = [];
                            let currentLineWidth = 0;
                            const spaceWidth = ctx.measureText(' ').width;
                            const wordWidths = words.map(w => ctx.measureText(w).width);

                            for (let i = 0; i < totalWords; i++) {
                                const w = wordWidths[i];
                                if (currentLine.length > 0 && currentLineWidth + spaceWidth + w > mw) {
                                    lines.push({ words: currentLine, width: currentLineWidth });
                                    currentLine = [{ index: i, text: words[i], width: w }];
                                    currentLineWidth = w;
                                } else {
                                    currentLine.push({ index: i, text: words[i], width: w });
                                    currentLineWidth += (currentLine.length > 1 ? spaceWidth : 0) + w;
                                }
                            }
                            if (currentLine.length > 0) {
                                lines.push({ words: currentLine, width: currentLineWidth });
                            }

                            // 2. Precalculate Exact (X, Y) Positions
                            const drawPositions = []; // Array of {x, y, text}
                            lines.forEach((lineObj, lineIdx) => {
                                const lineY = (lineIdx - (lines.length - 1) / 2) * (fs * 1.5);
                                let currentX = lineObj.width / 2; // RTL Start from right

                                lineObj.words.forEach(wordObj => {
                                    const drawX = currentX - wordObj.width / 2;
                                    drawPositions[wordObj.index] = {
                                        x: drawX,
                                        y: lineY,
                                        text: wordObj.text
                                    };
                                    currentX -= (wordObj.width + spaceWidth);
                                });
                            });

                            // Calculate Active Index
                            const exactActiveIndex = totalWords > 0 && duration > 0 ? (elapsed / duration) * totalWords : 0;
                            const safeExactIndex = Math.max(0, Math.min(exactActiveIndex, totalWords - 1));
                            const currentIndex = Math.floor(safeExactIndex);
                            const nextIndex = Math.min(currentIndex + 1, totalWords - 1);
                            const fraction = safeExactIndex - currentIndex;

                            // Smooth Tracking Easing
                            const easeFraction = fraction < 0.5 ? 2 * fraction * fraction : 1 - Math.pow(-2 * fraction + 2, 2) / 2;

                            const currentPos = drawPositions[currentIndex] || { x: 0, y: 0 };
                            const nextPos = drawPositions[nextIndex] || currentPos;
                            const glowX = currentPos.x * (1 - easeFraction) + nextPos.x * easeFraction;
                            const glowY = currentPos.y * (1 - easeFraction) + nextPos.y * easeFraction;

                            let globalAlpha = 1;
                            if (elapsed < 0.5) globalAlpha = elapsed / 0.5;
                            else if (timeLeft < 0.5) globalAlpha = timeLeft / 0.5;
                            globalAlpha = Math.max(0, Math.min(1, globalAlpha));

                            // Extract user's chosen text color for the glow and bloom
                            const hex = ayahStyle.color || '#ffffff';
                            let r = 255, g = 255, b = 255;
                            if (hex.startsWith('#') && hex.length >= 7) {
                                r = parseInt(hex.slice(1, 3), 16);
                                g = parseInt(hex.slice(3, 5), 16);
                                b = parseInt(hex.slice(5, 7), 16);
                            }

                            // Draw Cinematic Tracking Glow
                            ctx.save();
                            if (globalAlpha > 0.01 && totalWords > 0) {
                                const glowRadius = fs * 2.2; // Wider, extremely soft spread
                                const gradient = ctx.createRadialGradient(glowX, glowY, 0, glowX, glowY, glowRadius);
                                // Cinematic Lens Bloom Falloff (UI/UX enhancement)
                                gradient.addColorStop(0, `rgba(${r}, ${g}, ${b}, ${0.15 * globalAlpha})`); // Very subtle core
                                gradient.addColorStop(0.2, `rgba(${r}, ${g}, ${b}, ${0.08 * globalAlpha})`);
                                gradient.addColorStop(0.5, `rgba(${r}, ${g}, ${b}, ${0.03 * globalAlpha})`);
                                gradient.addColorStop(1, `rgba(${r}, ${g}, ${b}, 0)`);

                                ctx.fillStyle = gradient;
                                ctx.fillRect(glowX - glowRadius, glowY - glowRadius, glowRadius * 2, glowRadius * 2);
                            }
                            ctx.restore();

                            // Draw Words with Ethereal Bloom
                            drawPositions.forEach((pos, index) => {
                                const exactDist = Math.abs(exactActiveIndex - index);
                                let wordOp = 0.08; // Base dimmed state (barely visible)
                                let glowIntensity = 0;

                                if (exactDist <= 1) {
                                    wordOp = 1.0 - (0.5 * exactDist); // 1.0 to 0.5
                                    glowIntensity = 1.0 - exactDist; // 1.0 to 0
                                } else if (exactDist <= 2) {
                                    wordOp = 0.5 - (0.25 * (exactDist - 1)); // 0.5 to 0.25
                                } else if (exactDist <= 3) {
                                    wordOp = 0.25 - (0.17 * (exactDist - 2)); // 0.25 to 0.08
                                }

                                wordOp *= globalAlpha;
                                glowIntensity *= globalAlpha;

                                if (wordOp > 0.01) {
                                    ctx.save();
                                    ctx.font = `${fw} ${fs}px ${ayahStyle.font.split(',')[0]}`;

                                    // Layer 1: Ethereal Bloom (Inactive & Active)
                                    ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${0.5 * wordOp + 0.5 * glowIntensity})`;
                                    ctx.shadowColor = `rgba(${r}, ${g}, ${b}, ${0.2 * wordOp + 0.6 * glowIntensity})`;
                                    ctx.shadowBlur = 10;
                                    ctx.fillText(pos.text, pos.x, pos.y);

                                    // Layer 2: Core brightness for active word
                                    if (glowIntensity > 0.05) {
                                        ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${0.4 * glowIntensity})`;
                                        ctx.shadowColor = `rgba(${r}, ${g}, ${b}, ${0.6 * glowIntensity})`; // Softer core bloom
                                        ctx.shadowBlur = 25;
                                        ctx.fillText(pos.text, pos.x, pos.y);

                                        // Layer 3: Wide halo
                                        ctx.shadowColor = `rgba(${r}, ${g}, ${b}, ${0.3 * glowIntensity})`; // Softer wide bloom
                                        ctx.shadowBlur = 50;
                                        ctx.fillText(pos.text, pos.x, pos.y);
                                    }

                                    ctx.restore();
                                }
                            });
                        } else {
                            if (isReveal) {
                                ctx.save();
                                ctx.beginPath();
                                ctx.rect(-tw - 100, (fs * 2) - (fs * 4 * revealProgress), tw * 2 + 200, fs * 4 * revealProgress);
                                ctx.clip();
                            }
                            ctx.strokeText(drawText, 0, 0);
                            ctx.fillStyle = ayahStyle.color;
                            ctx.fillText(drawText, 0, 0);
                            if (isReveal) ctx.restore();
                        }

                        ctx.restore();
                    }
                }
                if (dragState.isDragging && !isExporting) { ctx.save(); ctx.lineWidth = 2; ctx.setLineDash([10, 10]); ctx.strokeStyle = '#ef4444'; if (snapState.y) { ctx.beginPath(); ctx.moveTo(0, CANVAS_HEIGHT / 2); ctx.lineTo(CANVAS_WIDTH, CANVAS_HEIGHT / 2); ctx.stroke() } if (snapState.x) { ctx.beginPath(); ctx.moveTo(CANVAS_WIDTH / 2, 0); ctx.lineTo(CANVAS_WIDTH / 2, CANVAS_HEIGHT); ctx.stroke() } ctx.restore() }

                // Modified drawing logic for Watermark section with Auto-Layout Stack
                ctx.save();
                ctx.globalAlpha = watermark.opacity;
                ctx.textAlign = 'center';
                ctx.shadowColor = 'transparent';
                ctx.fillStyle = watermark.color;

                const lines = [];
                const spacing = watermark.size * 1.3;

                // 1. Site Branding
                if (showSiteBranding) {
                    lines.push({
                        text: "انشئ بواسطة quran7.com",
                        isRtl: true,
                        font: `bold ${watermark.size}px ${watermark.font.split(',')[0]}`
                    });
                }

                // 2. User Watermark (only if enabled)
                if (watermark.visible && watermark.text) {
                    lines.push({
                        text: watermark.text,
                        isRtl: false,
                        font: `bold ${watermark.size}px ${watermark.font.split(',')[0]}`
                    });
                }

                // 3. Surah Info
                if (staticSurahInfo) {
                    const sfs = Math.max(18, watermark.size * 0.9);
                    lines.push({
                        text: staticSurahInfo,
                        isRtl: true,
                        font: `bold ${sfs}px ${FONTS[1].css.split(',')[0]}`
                    });
                }

                // Draw Stack Centered at watermark.y
                if (lines.length > 0) {
                    const totalHeight = (lines.length - 1) * spacing;
                    let currentY = watermark.y - (totalHeight / 2);

                    lines.forEach(line => {
                        ctx.font = line.font;
                        ctx.save();
                        ctx.direction = line.isRtl ? 'rtl' : 'ltr';
                        ctx.fillText(line.text, watermark.x, currentY);
                        ctx.restore();
                        currentY += spacing;
                    });
                }
                ctx.restore();

                if (totalDuration > 0) { const pr = Math.min(1, Math.max(0, currentProgress / totalDuration)), by = CANVAS_HEIGHT - 2; ctx.save(); ctx.fillStyle = 'rgba(255,255,255,0.1)'; ctx.fillRect(0, by, CANVAS_WIDTH, 2); const aw = CANVAS_WIDTH * pr; ctx.shadowColor = 'white'; ctx.shadowBlur = 10; ctx.fillStyle = 'white'; ctx.fillRect(CANVAS_WIDTH - aw, by, aw, 2); ctx.restore() }
            };
            const handleExportClick = () => { if (!audioSrc || (bgType === 'video' && !videoSrc) || (bgType === 'image' && !bgImageSrc)) return; setShowExportConfirm(true); };

            // Wake Lock for preventing screen sleep during export
            const wakeLockRef = useRef(null);
            const requestWakeLock = async () => {
                try {
                    if ('wakeLock' in navigator) {
                        wakeLockRef.current = await navigator.wakeLock.request('screen');
                        console.log('Wake Lock acquired');
                    }
                } catch (e) { console.log('Wake Lock not available:', e); }
            };
            const releaseWakeLock = () => {
                if (wakeLockRef.current) {
                    wakeLockRef.current.release();
                    wakeLockRef.current = null;
                    console.log('Wake Lock released');
                }
            };

            // Re-acquire wake lock on visibility change
            useEffect(() => {
                const handleVisibilityChange = async () => {
                    if (isExporting && document.visibilityState === 'visible' && !wakeLockRef.current) {
                        await requestWakeLock();
                    }
                };
                document.addEventListener('visibilitychange', handleVisibilityChange);
                return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
            }, [isExporting]);
            const handleTrimAndSave = () => {
                if (!audioSrc || (bgType === 'video' && !videoSrc) || (bgType === 'image' && !bgImageSrc)) return;
                setShowCompositionTrimmer(true);
            };

            const handleCompositionTrimConfirm = (range) => {
                setShowCompositionTrimmer(false);
                setExportRange(range);
                // Auto-export disabled per user request
            };

            const executeExport = async (customRange) => {
                setShowExportConfirm(false);

                const missingMediaMessage = !audioSrc
                    ? 'أضف ملفًا صوتيًا قبل التصدير.'
                    : bgType === 'video' && !videoSrc
                        ? 'أضف فيديو للخلفية قبل التصدير.'
                        : bgType === 'image' && !bgImageSrc
                            ? 'أضف صورة للخلفية قبل التصدير.'
                            : null;
                if (missingMediaMessage) {
                    setActiveTab('media');
                    setAlertModal({ visible: true, title: 'تعذر التصدير', message: missingMediaMessage, isSuccess: false });
                    return;
                }

                let validation;
                try {
                    if (!window.QuranDataValidator?.validateSegments) throw new Error('validator-unavailable');
                    validation = window.QuranDataValidator.validateSegments(timelineData, {
                        start: audioRange.start,
                        end: audioRange.end,
                        surahList: window.__quranSurahList || []
                    });
                } catch (error) {
                    console.error('Quran validation failed to run', error);
                    setActiveTab('content');
                    setAlertModal({
                        visible: true,
                        title: 'تعذر التحقق من الآيات',
                        message: 'لم تعمل أداة التحقق من بيانات الآيات. أعد تحميل الصفحة ثم حاول مجددًا؛ لم يبدأ التصدير حمايةً للنص القرآني.',
                        isSuccess: false
                    });
                    return;
                }
                if (!validation.ok) {
                    setActiveTab('content');
                    setAlertModal({
                        visible: true,
                        title: 'تعذر التصدير',
                        message: describeQuranValidationErrors(validation.errors),
                        isSuccess: false
                    });
                    return;
                }

                // CompositionTrimmer stores a range relative to the selected
                // audio clip. Convert it back to the media element's absolute
                // timeline before seeking and recording.
                const isArgRange = customRange && Number.isFinite(customRange.start) && Number.isFinite(customRange.end);
                const effectiveRange = isArgRange
                    ? customRange
                    : exportRange
                        ? {
                            start: audioRange.start + exportRange.start,
                            end: audioRange.start + exportRange.end
                        }
                        : audioRange;
                const rangeIsValid = Number.isFinite(effectiveRange.start) && Number.isFinite(effectiveRange.end)
                    && effectiveRange.start >= audioRange.start - 0.001
                    && effectiveRange.end <= audioRange.end + 0.001
                    && effectiveRange.end > effectiveRange.start;
                if (!rangeIsValid) {
                    setExportRange(null);
                    setAlertModal({
                        visible: true,
                        title: 'نطاق التصدير غير صالح',
                        message: 'لم يعد نطاق القص متوافقًا مع الملف الصوتي الحالي. أُعيد ضبط القص؛ حدده مجددًا ثم أعد التصدير.',
                        isSuccess: false
                    });
                    return;
                }

                // Smart Dua Selection with Anti-Repetition
                const historyKey = 'q7_dua_history_v1';
                // Get history or empty array
                let history = [];
                try { history = JSON.parse(localStorage.getItem(historyKey) || '[]'); } catch (e) { }

                // Filter duas that are NOT in recent history
                const available = EXPORT_DUAS.filter(d => !history.includes(d));

                // If we ran out of new duas, reset history (or just pick from full list to be safe)
                const pool = available.length > 0 ? available : EXPORT_DUAS;

                // Pick random
                const randomDua = pool[Math.floor(Math.random() * pool.length)];

                // Update history (keep last 6)
                const newHistory = [randomDua, ...history].slice(0, 6);
                try { localStorage.setItem(historyKey, JSON.stringify(newHistory)); } catch (e) { }

                setCurrentDua(randomDua);
                let failedInitializationCleanup = null;
                try {
                    if (document.visibilityState !== 'visible') { await new Promise(r => { const h = () => { if (document.visibilityState === 'visible') { document.removeEventListener('visibilitychange', h); r() } }; document.addEventListener('visibilitychange', h) }) }
                    await requestWakeLock();

                    console.log('🎬 Export started...');
                    const startTime = effectiveRange.start;
                    const duration = effectiveRange.end - effectiveRange.start;

                    pauseAll();
                    const vs = videoRange.start;
                    setCurrentTime(startTime);
                    setIsExporting(true);
                    renderState.current = { text: "", opacity: 0, surah: "", ayah: "" };

                    // === FIX: Set media positions first ===
                    if (audioRef.current) audioRef.current.currentTime = startTime;
                    if (bgType === 'video' && videoRef.current) {
                        const vd = videoRange.end - videoRange.start;
                        if (vd > 0.1) videoRef.current.currentTime = videoRange.start + (Math.max(0, startTime - audioRange.start) % vd);
                    }

                    // === FIX: Wait for media to be ready (canplaythrough) ===
                    const waitForMediaReady = (element, timeoutMs = 3000) => {
                        return new Promise((resolve) => {
                            if (!element) { resolve(); return; }
                            if (element.readyState >= 4) { resolve(); return; } // HAVE_ENOUGH_DATA
                            const timeout = setTimeout(() => { element.removeEventListener('canplaythrough', handler); resolve(); }, timeoutMs);
                            const handler = () => { clearTimeout(timeout); element.removeEventListener('canplaythrough', handler); resolve(); };
                            element.addEventListener('canplaythrough', handler);
                        });
                    };

                    console.log('⏳ Waiting for media to be ready...');
                    const waitPromises = [waitForMediaReady(audioRef.current)];
                    if (bgType === 'video') waitPromises.push(waitForMediaReady(videoRef.current));
                    await Promise.all(waitPromises);
                    console.log('✅ Media ready');

                    // === FIX: Draw first frame to canvas before recording ===
                    draw();
                    await new Promise(r => requestAnimationFrame(() => { draw(); requestAnimationFrame(r); }));

                    // Resume audio context
                    await audioCtxRef.current.resume();
                    const d = audioCtxRef.current.createMediaStreamDestination();
                    if (audioSourceNodeRef.current) {
                        // Connect Source DIRECTLY to Recorder (Bypassing GainNode/Volume)
                        audioSourceNodeRef.current.connect(d);
                    }
                    const cs = canvasRef.current.captureStream(30); // 30 FPS for Instagram compatibility
                    const t = [...cs.getVideoTracks(), ...d.stream.getAudioTracks()];

                    // Smart MimeType Selection for Best Quality / Compatibility (Prefer MP4 for Instagram)
                    const types = [
                        "video/mp4;codecs=avc1.42E01E,mp4a.40.2", // H.264 + AAC (Most compatible)
                        "video/mp4;codecs=h264,aac",
                        "video/mp4",
                        "video/webm;codecs=h264,opus",
                        "video/webm;codecs=vp9,opus",
                        "video/webm;codecs=vp8,opus",
                        "video/webm"
                    ];
                    const mimeType = types.find(type => MediaRecorder.isTypeSupported(type)) || "video/webm";
                    const exportExtension = mimeType.includes("mp4") ? "mp4" : "webm";
                    const exportNonce = globalThis.crypto && typeof globalThis.crypto.randomUUID === 'function'
                        ? globalThis.crypto.randomUUID()
                        : `${Date.now()}-${Math.random().toString(16).slice(2)}`;
                    const tempExportFilename = `quran_shorts_temp_${exportNonce}.${exportExtension}`;
                    console.log('Export using codec:', mimeType);

                    const rec = new MediaRecorder(new MediaStream(t), {
                        mimeType: mimeType,
                        videoBitsPerSecond: 12000000, // 12 Mbps (Instagram limit is 25Mbps, lower for better upload)
                        audioBitsPerSecond: 128000
                    });

                    // ═══════════════════════════════════════
                    // OPFS: Origin Private File System Setup
                    // ═══════════════════════════════════════
                    let opfsFileHandle = null;
                    let opfsWritable = null;
                    let useOPFS = false;
                    const ch = [];
                    let opfsWriteChain = Promise.resolve();
                    let recorderWriteError = null;
                    let stopCheckTimer = null;

                    const clearStopCheck = () => {
                        if (stopCheckTimer !== null) {
                            clearInterval(stopCheckTimer);
                            stopCheckTimer = null;
                        }
                    };

                    const stopRecorderSafely = () => {
                        clearStopCheck();
                        if (rec.state !== 'inactive') {
                            try { rec.stop(); } catch (e) { }
                        }
                    };

                    try {
                        if (navigator.storage && navigator.storage.getDirectory) {
                            const rootDir = await navigator.storage.getDirectory();
                            opfsFileHandle = await rootDir.getFileHandle(tempExportFilename, { create: true });
                            opfsWritable = await opfsFileHandle.createWritable();
                            useOPFS = true;
                            console.log('✅ OPFS is ACTIVE: Video chunks will stream directly to disk.');
                        }
                    } catch (error) {
                        console.warn('⚠️ OPFS not available or failed, falling back to RAM Blob array.', error);
                        if (opfsFileHandle) {
                            try {
                                const rootDir = await navigator.storage.getDirectory();
                                await rootDir.removeEntry(tempExportFilename);
                            } catch (e) { }
                        }
                        opfsFileHandle = null;
                        opfsWritable = null;
                        useOPFS = false;
                    }

                    rec.ondataavailable = e => {
                        if (e.data.size > 0) {
                            if (useOPFS && opfsWritable) {
                                // MediaRecorder does not await async event
                                // handlers. Serialize writes explicitly so
                                // onstop cannot close/read a partial OPFS file.
                                opfsWriteChain = opfsWriteChain
                                    .then(() => opfsWritable.write(e.data))
                                    .catch(error => {
                                        recorderWriteError = error;
                                    });
                            } else {
                                ch.push(e.data);
                            }
                        }
                    };

                    rec.onstop = async () => {
                        clearStopCheck();
                        try {
                            console.log('✅ Export completed, preparing file...');
                            await opfsWriteChain;
                            if (recorderWriteError) throw recorderWriteError;
                            let u = null;
                            let finalFile = null;

                            if (useOPFS && opfsWritable) {
                                await opfsWritable.close();
                                const storedFile = await opfsFileHandle.getFile();
                                finalFile = storedFile.type === mimeType
                                    ? storedFile
                                    : new Blob([storedFile], { type: mimeType });
                            } else {
                                finalFile = new Blob(ch, { type: mimeType });
                            }

                            if (!finalFile || finalFile.size === 0) throw new Error('empty-export');

                            // Extension based on selected MimeType
                            const exportName = `QURAN_SHORTS_Quran7.com_${Date.now()}.${exportExtension}`;

                        /* ═══ الحفظ في استوديو التطبيق — المرحلة 4 ═══
                           تصدير الفيديو طويل، فحين ينتهي يكون «التفعيل العابر»
                           الذي تشترطه `navigator.share` قد انقضى → كانت الدعوة
                           تُرفَض بـ`NotAllowedError` وتسقط إلى `a.download` فيظهر
                           **إشعار تنزيل بهوية Chrome**. الحل: `mode:'studio'`
                           يحفظ الملف بصمت في مجلّد التطبيق (OPFS) بلا صلاحية ولا
                           إشعار Chrome، ثم يعرض إشعارًا داخليًّا فيه «مشاركة/فتح»؛
                           وزرّ المشاركة إيماءةٌ طازجة فلا ينقضي تفعيلها.
                           التفصيل في `assets/app-shell.js`. */
                            if (window.AppShell) {
                                await window.AppShell.saveFile(finalFile, exportName, {
                                    mode: 'studio',
                                    studioLabel: 'الاستوديو',
                                    title: 'مقطع قرآني'
                                });
                            } else {
                                u = URL.createObjectURL(finalFile);
                                const a = document.createElement('a');
                                a.href = u;
                                a.download = exportName;
                                a.click();
                            }

                        // === Track export for analytics ===
                            trackAnalytics('export');

                        // Clean up export blob URL after delay for download to complete
                            setTimeout(async () => {
                                if (u) try { URL.revokeObjectURL(u); } catch (e) { }
                                if (useOPFS && opfsFileHandle) {
                                    try {
                                        const rootDir = await navigator.storage.getDirectory();
                                        await rootDir.removeEntry(tempExportFilename);
                                    } catch (e) { }
                                }
                            }, 120000);

                            setIsExporting(false);
                            releaseWakeLock();
                            pauseAll();
                        } catch (error) {
                            console.error('Export finalization failed', error);
                            try { if (opfsWritable) await opfsWritable.abort(); } catch (e) { }
                            if (useOPFS && opfsFileHandle) {
                                try {
                                    const rootDir = await navigator.storage.getDirectory();
                                    await rootDir.removeEntry(tempExportFilename);
                                } catch (e) { }
                            }
                            setIsExporting(false);
                            releaseWakeLock();
                            pauseAll();
                            setAlertModal({
                                visible: true,
                                title: 'فشل حفظ الفيديو',
                                message: 'تعذر إنهاء ملف الفيديو بصورة سليمة. أعد المحاولة وتأكد من توفر مساحة تخزين كافية.',
                                isSuccess: false
                            });
                        } finally {
                            // Stop all media tracks from the stream to free resources
                            t.forEach(track => { try { track.stop(); } catch (e) { } });

                            // Disconnect recorder tap and keep normal playback connected.
                            if (audioSourceNodeRef.current) {
                                try { audioSourceNodeRef.current.disconnect(d); } catch (e) { }
                                if (gainNodeRef.current) {
                                    try { audioSourceNodeRef.current.connect(gainNodeRef.current); } catch (e) { }
                                }
                            }
                        }
                    };

                    rec.onerror = event => {
                        console.error('MediaRecorder error', event.error || event);
                        recorderWriteError = event.error || new Error('media-recorder-error');
                        stopRecorderSafely();
                    };

                    failedInitializationCleanup = async () => {
                        clearStopCheck();
                        try { if (opfsWritable) await opfsWritable.abort(); } catch (e) { }
                        if (useOPFS && opfsFileHandle) {
                            try {
                                const rootDir = await navigator.storage.getDirectory();
                                await rootDir.removeEntry(tempExportFilename);
                            } catch (e) { }
                        }
                        t.forEach(track => { try { track.stop(); } catch (e) { } });
                        if (audioSourceNodeRef.current) {
                            try { audioSourceNodeRef.current.disconnect(d); } catch (e) { }
                        }
                    };

                    // === FIX: Start playback first, wait for frames to render, then start recording ===
                    setIsPlaying(true);
                    await audioRef.current.play();
                    if (bgType === 'video' && videoRef.current) await videoRef.current.play();

                    // Wait for first rendered frame after playback starts
                    await new Promise(r => requestAnimationFrame(() => { draw(); r(); }));
                    // Small buffer to ensure smooth start
                    await new Promise(r => setTimeout(r, 150));

                    // Now start recording after everything is playing and rendered
                    // Request periodic chunks so long exports stream to OPFS
                    // instead of retaining one very large final chunk in RAM.
                    rec.start(1000);
                    // From this point rec.onstop owns every resource.
                    failedInitializationCleanup = null;
                    console.log('🔴 Recording started');

                    // Use audio time for stop check to perfectly match playback and avoid lag desync
                    const st = Date.now();
                    stopCheckTimer = setInterval(() => {
                        if (!audioRef.current) return;
                        const ct = audioRef.current.currentTime;
                        // Stop if we hit the exact end time, OR if audio paused natively near the end
                        if (ct >= effectiveRange.end || (audioRef.current.paused && (Date.now() - st) / 1000 > duration * 0.8)) {
                            stopRecorderSafely();
                        } else if ((Date.now() - st) / 1000 >= duration + 2.0) { 
                            stopRecorderSafely();
                        } 
                    }, 50);
                } catch (e) {
                    console.error("Export Failed", e);
                    if (failedInitializationCleanup) await failedInitializationCleanup();
                    setIsExporting(false);
                    pauseAll();
                    releaseWakeLock();
                    setAlertModal({
                        visible: true,
                        title: 'فشل التصدير',
                        message: 'تعذر إكمال التصدير. تأكد من بقاء ملفات الصوت والخلفية متاحة، ثم أعد المحاولة.',
                        isSuccess: false
                    });
                }
            };
            const getCC = e => { const c = canvasRef.current, r = c.getBoundingClientRect(), sx = c.width / r.width, sy = c.height / r.height, cx = e.touches ? e.touches[0].clientX : e.clientX, cy = e.touches ? e.touches[0].clientY : e.clientY; return { x: (cx - r.left) * sx, y: (cy - r.top) * sy } };
            const hPD = e => { if (isExporting) return; const { x, y } = getCC(e), hr = 100; let ct = null; if (Math.abs(y - ayahStyle.y) < hr && Math.abs(x - ayahStyle.x) < CANVAS_WIDTH) { ct = 'ayah'; setDragState({ isDragging: true, target: 'ayah', startY: y, initialItemY: ayahStyle.y, startX: x, initialItemX: ayahStyle.x }) } else if (Math.abs(y - watermark.y) < hr && Math.abs(x - watermark.x) < hr) { ct = 'watermark'; setDragState({ isDragging: true, target: 'watermark', startY: y, initialItemY: watermark.y, startX: x, initialItemX: watermark.x }) } setSelectedElement(ct) };
            const hPM = e => { if (isExporting) return; const { x, y } = getCC(e), hr = 100, ioa = Math.abs(y - ayahStyle.y) < hr, iow = Math.abs(y - watermark.y) < hr && Math.abs(x - watermark.x) < hr; e.target.style.cursor = (dragState.isDragging || ioa || iow) ? 'move' : 'default'; if (!dragState.isDragging) return; e.preventDefault(); const cx = CANVAS_WIDTH / 2, cy = CANVAS_HEIGHT / 2, sd = 30; let nx = dragState.initialItemX + (x - dragState.startX), ny = dragState.initialItemY + (y - dragState.startY), sx = false, sy = false; if (Math.abs(nx - cx) < sd) { nx = cx; sx = true } if (Math.abs(ny - cy) < sd) { ny = cy; sy = true } setSnapState({ x: sx, y: sy }); if (dragState.target === 'ayah') setAyahStyle(p => ({ ...p, x: nx, y: ny })); else if (dragState.target === 'watermark') setWatermark(p => ({ ...p, x: nx, y: ny })) };

            return (
                <div className="h-[100dvh] bg-[#0a0a0a] text-white font-tajawal flex flex-col-reverse md:flex-row overflow-hidden selection:bg-emerald-500/30 relative">

                    {/* --- SMART HEADER (Fixed Top Bar - Mobile Only) --- */}
                    <div className="absolute top-0 left-0 right-0 app-header-safe bg-[#0f0f11] border-b border-white/10 z-50 flex items-center justify-between md:hidden">
                        <div className="flex flex-col justify-center">
                            <h1 className="text-lg font-bold bg-clip-text text-transparent bg-gradient-to-r from-emerald-400 to-teal-200">قرآن شورتس</h1>
                            <span className="text-[9px] text-gray-400 font-mono tracking-widest uppercase leading-none">Quran Shorts Studio</span>
                        </div>
                        <div className="flex items-center gap-2">
                            <VideoOfTheDayIcon onOpen={() => setShowTOD(true)} />
                            {/* <a href="hadith-studio.html" target="_blank" aria-label="ستوديو الأحاديث" className="text-gray-500 hover:text-emerald-400 p-2 transition-colors relative group" title="ستوديو الأحاديث">
                                <BookOpen size={20} />
                                <span className="absolute top-1.5 right-1.5 w-2 h-2 bg-emerald-500 rounded-full animate-ping opacity-75"></span>
                                <span className="absolute top-1.5 right-1.5 w-2 h-2 bg-emerald-500 rounded-full border border-[#0f0f11]"></span>
                            </a> */}
                            <a href="quiz.html" aria-label="تحدي القرآن" className="text-gray-500 hover:text-amber-400 p-2 transition-colors relative group" title="تحدي القرآن — مسابقات قرآنية">
                                <Trophy size={20} />
                                <span className="absolute top-1.5 right-1.5 w-2 h-2 bg-amber-400 rounded-full animate-ping opacity-75"></span>
                                <span className="absolute top-1.5 right-1.5 w-2 h-2 bg-amber-400 rounded-full border border-[#0f0f11]"></span>
                            </a>
                            <button aria-label="المطور" onClick={() => setShowDevDialog(true)} className="text-gray-500 hover:text-purple-400 p-2"><Code2 size={20} /></button>

                        </div>
                    </div>

                    <video ref={videoRef} src={videoSrc || ""} muted={true} playsInline crossOrigin="anonymous" preload="auto" loop className="hidden" />
                    <audio ref={audioRef} src={audioSrc} onEnded={pauseAll} className="hidden" crossOrigin="anonymous" />

                    {/* Drag Overlay Portal */}
                    {isDragging && <DragOverlay item={timelineData.find(i => i.id === draggedId)} x={dragOverlayPos.x} y={dragOverlayPos.y} width={dragItemWidth} />}

                    {/* Context Menu */}
                    {contextMenu.visible && (
                        <div className="context-menu" style={{ top: contextMenu.y, left: contextMenu.x }}>
                            <button aria-label="تكرار" onClick={handleDuplicateSegment}><Copy size={16} /> تكرار</button>
                            <button aria-label="حذف" className="delete" onClick={handleDeleteSegment}><Trash2 size={16} /> حذف</button>
                        </div>
                    )}

                    <OnboardingTour active={tourActive} stepIndex={tourStep} onNext={handleTourNext} onPrev={handleTourPrev} onSkip={handleTourSkip} setTab={setActiveTab} setData={setTimelineData} setSettingsCollapsed={setIsSettingsCollapsed} />

                    {showAudioChoice && <div className="fixed inset-0 z-50 bg-black/80 flex items-center justify-center p-4 backdrop-blur-sm animate-in fade-in"><div className="bg-[#1a1a1a] border border-white/10 rounded-2xl p-8 max-w-lg w-full text-center space-y-6 shadow-2xl relative"><button aria-label="إغلاق" onClick={() => setShowAudioChoice(false)} className="absolute top-4 left-4 text-gray-400 hover:text-white"><X /></button><h3 className="text-xl font-bold">رفع صوت</h3><div className="grid grid-cols-2 gap-3"><label className="flex flex-col items-center gap-3 p-4 bg-white/5 hover:bg-emerald-500/10 border border-white/10 rounded-xl cursor-pointer group"><div className="p-4 rounded-full bg-emerald-500/20 text-emerald-400 group-hover:scale-110 transition"><FileAudio size={28} /></div><span className="font-bold text-xs">ملف صوتي</span><input type="file" accept="audio/*" className="hidden" onChange={e => handleFileUpload(e, 'audio')} /></label><label className="flex flex-col items-center gap-3 p-4 bg-white/5 hover:bg-blue-500/10 border border-white/10 rounded-xl cursor-pointer group"><div className="p-4 rounded-full bg-blue-500/20 text-blue-400 group-hover:scale-110 transition"><Film size={28} /></div><span className="font-bold text-xs">استخراج من فيديو</span><input type="file" accept="video/*" className="hidden" onChange={e => handleFileUpload(e, 'video', 'extractAudio')} /></label></div></div></div>}
                    {showDevDialog && <DevDialog onClose={() => setShowDevDialog(false)} />}
                    {isProcessingAudio && <div className="fixed inset-0 z-50 bg-black/90 flex items-center justify-center backdrop-blur-md"><div className="text-center space-y-4"><Loader2 size={48} className="animate-spin text-emerald-500 mx-auto" /><p className="text-lg font-bold">جاري المعالجة...</p></div></div>}
                    {isAutoGenerating && <div className="fixed inset-0 z-[80] bg-black/95 flex flex-col items-center justify-center backdrop-blur-xl animate-in fade-in"><div className="relative"><div className="absolute inset-0 bg-purple-500/30 blur-3xl rounded-full animate-pulse-slow"></div><Dna size={80} className="text-purple-500 relative z-10 animate-spin duration-[3000ms]" /></div><h3 className="text-2xl font-bold mt-8 bg-clip-text text-transparent bg-gradient-to-r from-purple-400 to-pink-400 animate-pulse">{autoGenStep}</h3></div>}
                    {showResetConfirm && <ConfirmationModal title="إعادة تعيين" message="هل أنت متأكد؟ سيتم فقدان التخصيصات." onConfirm={confirmReset} onCancel={() => setShowResetConfirm(false)} />}
                    {showExportConfirm && <ConfirmationModal title="تنبيه قبل الحفظ" message="يرجى عدم إغلاق المتصفح أو الخروج من الموقع أثناء عملية الحفظ، حيث قد يؤدي ذلك إلى توقف العملية وفقدان الفيديو." onConfirm={executeExport} onCancel={() => setShowExportConfirm(false)} icon={ShieldAlert} />}
                    {showAutoGenerateModal && <AutoGenerateModal onClose={() => setShowAutoGenerateModal(false)} onConfirm={handleAutoGenerate} />}
                    {alertModal.visible && <AlertModal title={alertModal.title} message={alertModal.message} isSuccess={alertModal.isSuccess} onClose={() => setAlertModal({ ...alertModal, visible: false })} />}
                    {trimmingFile && <TrimmerModal file={trimmingFile.file} type={trimmingFile.type} isExtractingMode={trimmingFile.mode === 'extractAudio'} onClose={() => setTrimmingFile(null)} onConfirm={handleTrimConfirm} previewVolume={volume} />}
                    {showExtractionModeModal && <VerseExtractionModeModal onClose={() => { setShowExtractionModeModal(false); setPendingAudioData(null); }} onConfirm={handleExtractionModeConfirm} />}
                    {showQuranSelector && <QuranSelectorModal onClose={() => setShowQuranSelector(false)} onAddAyah={handleAddAyah} audioRange={audioRange} existingItems={timelineData} audioFileSrc={audioSrc} volume={volume} />}

                    {/* Image Editor Modal */}
                    {showImageEditor && bgImageSrc && (
                        <ImageCropperModal
                            src={bgImageSrc}
                            initialTransform={imageTransform}
                            onClose={() => setShowImageEditor(false)}
                            onSave={(newTransform) => {
                                setImageTransform(newTransform);
                                setShowImageEditor(false);
                            }}
                        />
                    )}

                    {/* Mobile Bottom Navigation */}
                    <div className="md:hidden fixed bottom-0 left-0 right-0 bg-[#0f0f11] border-t border-white/10 flex justify-around items-center app-bottomnav-safe z-50">
                        {APP_STEPS.map((step) => {
                            const isActive = activeTab === step.id;
                            return (
                                <button
                                    key={step.id}
                                    onClick={() => { setActiveTab(step.id); setPanelSubView(null); setIsPanelCollapsed(false); }}
                                    className={`flex flex-col items-center justify-center gap-1 w-full h-full transition-colors ${isActive ? 'text-emerald-400' : 'text-gray-500'}`}
                                >
                                    <step.icon size={isActive ? 24 : 20} className={isActive ? 'drop-shadow-[0_0_8px_rgba(16,185,129,0.4)]' : ''} />
                                    <span className="text-[10px] font-bold">{step.label}</span>
                                    {isActive && <div className="absolute top-0 w-8 h-0.5 bg-emerald-500 rounded-b-full shadow-[0_2px_8px_rgba(16,185,129,0.6)]"></div>}
                                </button>
                            );
                        })}
                    </div>

                    {/* Editor Sidebar */}
                    <div
                        className={`w-full md:w-[380px] md:!h-full flex flex-col bg-[#0f0f11] border-t md:border-t-0 md:border-l border-white/5 shadow-2xl z-20 transition-all duration-300 relative ${isExporting ? 'hidden md:flex opacity-30 pointer-events-none grayscale' : ''} pb-16 md:pb-0`}
                        style={{ height: window.innerWidth < 768 ? (isPanelCollapsed ? '40px' : '50vh') : `${panelHeight}vh` }}
                    >
                        {/* Toggle Button Only (No Drag) */}
                        <div
                            className="w-full h-8 bg-[#0f0f11] border-t border-white/10 flex items-center justify-center cursor-pointer md:hidden absolute -top-8 left-0 right-0 rounded-t-xl z-20 shadow-[0_-5px_15px_rgba(0,0,0,0.5)]"
                            onClick={(e) => { e.stopPropagation(); setIsPanelCollapsed(!isPanelCollapsed); }}
                        >
                            <div className="p-1 text-gray-400 hover:text-white transition-colors">
                                {isPanelCollapsed ? <ChevronUp size={20} /> : <ChevronDown size={20} />}
                            </div>
                        </div>

                        {/* DESKTOP Title Block (Hidden on Mobile, Visible on Desktop) */}
                        <div className="hidden md:flex p-3 border-b border-white/5 flex-col gap-1 shrink-0">
                            <h1 className="text-lg md:text-2xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-emerald-400 to-teal-200 flex justify-between items-center">
                                <span className="flex items-center gap-2">قرآن شورتس</span>
                                <div className="flex items-center gap-1">
                                    <VideoOfTheDayIcon onOpen={() => setShowTOD(true)} />
                                    {/* <a href="hadith-studio.html" target="_blank" aria-label="ستوديو الأحاديث" className="text-gray-500 hover:text-emerald-400 p-1 transition-colors relative group" title="ستوديو الأحاديث">
                                        <BookOpen size={18} />
                                        <span className="absolute top-0.5 right-0.5 w-2 h-2 bg-emerald-500 rounded-full animate-ping opacity-75"></span>
                                        <span className="absolute top-0.5 right-0.5 w-2 h-2 bg-emerald-500 rounded-full border border-[#0f0f11]"></span>
                                    </a> */}
                                    <a href="quiz.html" aria-label="تحدي القرآن" className="text-gray-500 hover:text-amber-400 p-1 transition-colors relative group" title="تحدي القرآن — مسابقات قرآنية">
                                        <Trophy size={18} />
                                        <span className="absolute top-0.5 right-0.5 w-2 h-2 bg-amber-400 rounded-full animate-ping opacity-75"></span>
                                        <span className="absolute top-0.5 right-0.5 w-2 h-2 bg-amber-400 rounded-full border border-[#0f0f11]"></span>
                                    </a>
                                    <button aria-label="المطور" onClick={() => setShowDevDialog(true)} className="text-gray-500 hover:text-purple-400 p-1"><Code2 size={18} /></button>

                                </div>
                            </h1>
                            <span className="text-[10px] md:text-xs text-gray-400 font-mono tracking-widest uppercase">Quran Shorts Studio</span>
                        </div>

                        <div className={`flex flex-col flex-1 overflow-hidden transition-opacity duration-200 ${isPanelCollapsed ? 'opacity-0 pointer-events-none' : 'opacity-100'}`}>
                            {/* Hidden on Mobile - Tabs moved to Bottom Bar */}
                            <div className={`hidden md:grid grid-cols-4 gap-1 px-2 pt-5 pb-2 md:py-2 border-b border-white/5 shrink-0 bg-[#0a0a0a]/50 backdrop-blur-sm ${(panelSubView === 'videoLib' || panelSubView === 'audioLib') ? 'hidden md:grid' : ''}`}>
                                {APP_STEPS.map((step) => {
                                    const isActive = activeTab === step.id;
                                    return (
                                        <button
                                            key={step.id}
                                            data-tour={`tab-${step.id}`}
                                            onClick={() => { setActiveTab(step.id); setPanelSubView(null); }}
                                            className={`group relative flex flex-col items-center justify-center gap-1.5 py-2 rounded-xl transition-all duration-300 ${isActive ? 'bg-emerald-500/10 text-emerald-400' : 'text-gray-500 hover:text-gray-300 hover:bg-white/5'}`}
                                        >
                                            <div className="relative">
                                                <step.icon size={isActive ? 22 : 20} className={`transition-all ${isActive ? 'drop-shadow-[0_0_8px_rgba(16,185,129,0.4)]' : ''}`} />
                                                <span className={`absolute -top-2 -right-3 w-4 h-4 text-[12px] font-bold flex items-center justify-center rounded-full border ${isActive ? 'bg-emerald-500 text-black border-emerald-500' : 'bg-[#1a1a1a] text-gray-600 border-gray-800'}`}>
                                                    {step.number}
                                                </span>
                                            </div>
                                            <span className={`text-[10px] font-bold tracking-wide ${isActive ? 'opacity-100' : 'opacity-70'}`}>
                                                {step.label}
                                            </span>
                                            {isActive && <div className="absolute bottom-0 w-8 h-0.5 bg-emerald-500 rounded-t-full shadow-[0_-2px_8px_rgba(16,185,129,0.6)]"></div>}
                                        </button>
                                    );
                                })}
                            </div>
                            <div className="flex-1 flex flex-col min-h-0" ref={dragContainerRef}>
                                {activeTab === 'media' && (
                                    <div className="flex-1 flex flex-col min-h-0">
                                        {!panelSubView ? (
                                            <div className="flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4">
                                                <button aria-label="اختيار ذكي" data-tour="smart-btn" onClick={() => setShowAutoGenerateModal(true)} className="w-full py-4 bg-gradient-to-r from-purple-600 to-pink-600 text-white rounded-xl shadow-lg flex items-center justify-center gap-3 group relative overflow-hidden"><Wand2 className="animate-pulse" size={20} /> <span className="font-bold">اختيار ذكي تلقائي</span></button>



                                                <div className="flex items-center gap-4 text-gray-500 text-xs font-bold my-2 opacity-60">
                                                    <div className="h-px bg-white/10 flex-1"></div>
                                                    <span>أو</span>
                                                    <div className="h-px bg-white/10 flex-1"></div>
                                                </div>
                                                <div data-tour="libraries" className="bg-white/5 p-4 rounded-xl border border-white/5 space-y-4">

                                                    <div className="flex items-center justify-between">
                                                        <h3 className="text-xs font-bold text-gray-400 uppercase flex items-center gap-2"><Layout size={14} /> خلفية المشهد</h3>
                                                        <div className="flex bg-black/40 rounded-lg p-1 border border-white/5">
                                                            <button onClick={() => setBgType('video')} className={`px-3 py-1 text-[10px] font-bold rounded-md transition-all ${bgType === 'video' ? 'bg-emerald-500 text-black shadow-lg' : 'text-gray-400 hover:text-white'}`}>فيديو</button>
                                                            <button onClick={() => setBgType('image')} className={`px-3 py-1 text-[10px] font-bold rounded-md transition-all ${bgType === 'image' ? 'bg-emerald-500 text-black shadow-lg' : 'text-gray-400 hover:text-white'}`}>صورة</button>
                                                        </div>
                                                    </div>

                                                    {bgType === 'video' ? (
                                                        <div className="space-y-3 animate-in fade-in slide-in-from-right-4 duration-300">
                                                            <div className="grid grid-cols-2 gap-2">
                                                                <label className="flex flex-col items-center justify-center gap-2 p-3 bg-black/40 border border-white/10 rounded-lg cursor-pointer h-24 text-center group hover:border-emerald-500/50 transition-colors">
                                                                    <div className="p-2 rounded-full bg-emerald-500/20 text-emerald-400 group-hover:scale-110 transition-transform"><Upload size={20} /></div>
                                                                    <span className="text-xs font-bold text-gray-300">رفع فيديو</span>
                                                                    <input type="file" accept="video/*" className="hidden" onChange={e => handleFileUpload(e, 'video')} />
                                                                </label>
                                                                <button aria-label="مكتبة الفيديو" data-tour="video-lib-btn" onClick={() => setPanelSubView('videoLib')} className="flex flex-col items-center justify-center gap-2 p-3 bg-black/40 border border-white/10 rounded-lg h-24 text-center group hover:border-blue-500/50 transition-colors">
                                                                    <div className="p-2 rounded-full bg-blue-500/20 text-blue-400 group-hover:scale-110 transition-transform"><Grid size={20} /></div>
                                                                    <span className="text-xs font-bold text-gray-300">معرض الفيديوهات</span>
                                                                </button>
                                                            </div>
                                                            <p className="text-[10px] text-gray-500 text-center flex items-center justify-center gap-2">
                                                                {videoSrc ? <><Check size={12} className="text-emerald-500" /> تم اختيار فيديو</> : <><AlertCircle size={12} /> لم يتم اختيار فيديو</>}
                                                            </p>
                                                        </div>
                                                    ) : (
                                                        <div className="space-y-3 animate-in fade-in slide-in-from-left-4 duration-300">
                                                            <div className="grid grid-cols-2 gap-2">
                                                                <label className="flex flex-col items-center justify-center gap-2 p-3 bg-black/40 border border-white/10 rounded-lg cursor-pointer h-24 text-center group hover:border-emerald-500/50 transition-colors">
                                                                    <div className="p-2 rounded-full bg-emerald-500/20 text-emerald-400 group-hover:scale-110 transition-transform"><ImageIcon size={20} /></div>
                                                                    <span className="text-xs font-bold text-gray-300">رفع صورة</span>
                                                                    <input type="file" accept="image/*" className="hidden" onChange={e => handleFileUpload(e, 'bgImage')} />
                                                                </label>
                                                                <button aria-label="مكتبة الصور" onClick={() => setPanelSubView('imageLib')} className="flex flex-col items-center justify-center gap-2 p-3 bg-black/40 border border-white/10 rounded-lg h-24 text-center group hover:border-purple-500/50 transition-colors">
                                                                    <div className="p-2 rounded-full bg-purple-500/20 text-purple-400 group-hover:scale-110 transition-transform"><LayoutGrid size={20} /></div>
                                                                    <span className="text-xs font-bold text-gray-300">معرض الصور</span>
                                                                </button>
                                                            </div>
                                                            <p className="text-[10px] text-gray-500 text-center flex items-center justify-center gap-2">
                                                                {bgImageSrc ? <><Check size={12} className="text-emerald-500" /> تم اختيار صورة</> : <><AlertCircle size={12} /> لم يتم اختيار صورة</>}
                                                            </p>
                                                        </div>
                                                    )}
                                                </div>
                                                <div className="bg-white/5 p-4 rounded-xl border border-white/5 space-y-3"><h3 className="text-xs font-bold text-gray-400 uppercase flex items-center gap-2"><Music size={14} /> ملف الصوت</h3>
                                                    <div className="grid grid-cols-2 gap-2">
                                                        <button aria-label="رفع صوت" onClick={() => setShowAudioChoice(true)} className="flex flex-col items-center justify-center gap-2 p-3 bg-black/40 border border-white/10 rounded-lg h-24 text-center"><div className="p-2 rounded-full bg-emerald-500/20 text-emerald-400"><Upload size={20} /></div><span className="text-xs font-bold">رفع من الجهاز</span></button>
                                                        <button aria-label="مكتبة الصوت" onClick={() => setPanelSubView('audioLib')} className="flex flex-col items-center justify-center gap-2 p-3 bg-black/40 border border-white/10 rounded-lg h-24 text-center"><div className="p-2 rounded-full bg-amber-500/20 text-amber-400"><ListMusic size={20} /></div><span className="text-xs font-bold">مكتبة الأصوات</span></button>
                                                    </div>
                                                    <p className="text-xs text-gray-500 text-center">{audioSrc ? 'تم اختيار صوت' : 'لم يتم اختيار صوت'}</p>
                                                </div>
                                            </div>
                                        ) : panelSubView === 'videoLib' ? (
                                            <div className="flex flex-col h-full animate-in fade-in min-h-0">
                                                <div className="flex items-center justify-between p-4 border-b border-white/5 bg-[#0f0f11] shrink-0">
                                                    <h3 className="text-lg font-bold flex items-center gap-2"><FolderOpen className="text-emerald-500" size={20} /> مكتبة الفيديو</h3>
                                                    <button aria-label="رجوع" onClick={() => setPanelSubView(null)} className="px-3 py-1 bg-white/5 hover:bg-white/10 rounded-lg text-xs flex items-center gap-1 transition-colors"><ArrowRight size={14} /> رجوع</button>
                                                </div>
                                                <div className="p-3 border-b border-white/5 bg-[#0a0a0c] shrink-0">
                                                    <div className="flex bg-black/40 rounded-lg p-1 border border-white/5 w-full max-w-[250px] mx-auto">
                                                        <button onClick={() => setShowFavoritesOnly(false)} className={`flex-1 py-1.5 text-xs rounded-md transition-all font-bold ${!showFavoritesOnly ? 'bg-emerald-500/20 text-emerald-400 shadow-sm' : 'text-gray-400 hover:text-white hover:bg-white/5'}`}>الكل</button>
                                                        <button onClick={() => setShowFavoritesOnly(true)} className={`flex-1 py-1.5 text-xs rounded-md transition-all flex items-center justify-center gap-1.5 font-bold ${showFavoritesOnly ? 'bg-red-500/20 text-red-400 shadow-sm' : 'text-gray-400 hover:text-white hover:bg-white/5'}`}><Heart size={12} className={showFavoritesOnly ? "fill-current" : ""} /> المفضلة</button>
                                                    </div>
                                                </div>
                                                <div className="flex-1 overflow-y-auto custom-scrollbar p-4" ref={videoLibScrollRef}>
                                                    {showFavoritesOnly && favorites.video?.length === 0 ? (
                                                        <div className="flex flex-col items-center justify-center h-40 text-gray-500 gap-2"><Heart size={24} className="opacity-50" /><span>لا توجد فيديوهات في المفضلة</span></div>
                                                    ) : (
                                                        <LazyGrid
                                                            items={showFavoritesOnly ? videoLibraryFiles.filter(f => favorites.video?.includes(f)) : videoLibraryFiles}
                                                            gridClassName="video-grid"
                                                            renderItem={(f) => <LibraryVideoItem key={f} filename={f} onSelect={handleLibrarySelect} isSelected={videoSrc === `video4all/${f}`} isFavorite={favorites.video?.includes(f)} onToggleFavorite={(e) => { e.stopPropagation(); toggleFavorite('video', f); }} />}
                                                        />
                                                    )}
                                                </div>
                                            </div>
                                        ) : panelSubView === 'imageLib' ? (
                                            <div className="flex flex-col h-full animate-in fade-in min-h-0">
                                                <div className="flex items-center justify-between p-4 border-b border-white/5 bg-[#0f0f11] shrink-0">
                                                    <h3 className="text-lg font-bold flex items-center gap-2"><ImageIcon className="text-purple-500" size={20} /> مكتبة الصور</h3>
                                                    <button aria-label="رجوع" onClick={() => setPanelSubView(null)} className="px-3 py-1 bg-white/5 hover:bg-white/10 rounded-lg text-xs flex items-center gap-1 transition-colors"><ArrowRight size={14} /> رجوع</button>
                                                </div>
                                                <div className="p-3 border-b border-white/5 bg-[#0a0a0c] shrink-0">
                                                    <div className="flex bg-black/40 rounded-lg p-1 border border-white/5 w-full max-w-[250px] mx-auto">
                                                        <button onClick={() => setShowFavoritesOnly(false)} className={`flex-1 py-1.5 text-xs rounded-md transition-all font-bold ${!showFavoritesOnly ? 'bg-purple-500/20 text-purple-400 shadow-sm' : 'text-gray-400 hover:text-white hover:bg-white/5'}`}>الكل</button>
                                                        <button onClick={() => setShowFavoritesOnly(true)} className={`flex-1 py-1.5 text-xs rounded-md transition-all flex items-center justify-center gap-1.5 font-bold ${showFavoritesOnly ? 'bg-red-500/20 text-red-400 shadow-sm' : 'text-gray-400 hover:text-white hover:bg-white/5'}`}><Heart size={12} className={showFavoritesOnly ? "fill-current" : ""} /> المفضلة</button>
                                                    </div>
                                                </div>
                                                <div className="flex-1 overflow-y-auto custom-scrollbar p-4" ref={imageLibScrollRef}>
                                                    {showFavoritesOnly && favorites.image?.length === 0 ? (
                                                        <div className="flex flex-col items-center justify-center h-40 text-gray-500 gap-2"><Heart size={24} className="opacity-50" /><span>لا توجد صور في المفضلة</span></div>
                                                    ) : (
                                                        <LazyGrid
                                                            items={showFavoritesOnly ? imageLibraryFiles.filter(f => favorites.image?.includes(f)) : imageLibraryFiles}
                                                            gridClassName="video-grid"
                                                            renderItem={(f) => {
                                                                const src = `image4all/${f}`;
                                                                const num = f.split('.')[0];
                                                                const isSelected = bgImageSrc === src;
                                                                const isFav = favorites.image?.includes(f);
                                                                return (
                                                                    <div key={f} className={`video-card group ${isSelected ? 'ring-2 ring-emerald-500 ring-offset-2 ring-offset-black' : ''}`} onClick={() => handleLibraryImageSelect(src)}>
                                                                        <span className="absolute top-2 left-2 z-20 bg-black/60 backdrop-blur-sm text-white text-[10px] px-2 py-0.5 rounded-md font-mono">#{num}</span>
                                                                        <button onClick={(e) => { e.stopPropagation(); toggleFavorite('image', f); }} className={`absolute bottom-2 left-2 z-30 p-1.5 rounded-full backdrop-blur-sm transition-all ${isFav ? 'bg-red-500/20 text-red-500' : 'bg-black/40 text-gray-400 opacity-0 group-hover:opacity-100 hover:text-white hover:bg-black/60'}`}>
                                                                            <Heart size={14} className={isFav ? "fill-current" : ""} />
                                                                        </button>
                                                                        {isSelected && <div className="absolute top-2 right-2 z-20 bg-emerald-500 text-black rounded-full p-1"><Check size={12} /></div>}
                                                                        <img src={src} className="w-full h-full object-cover" loading="lazy" />
                                                                        <div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition flex flex-col items-center justify-center gap-2"><Check size={32} className="text-white" /></div>
                                                                    </div>
                                                                );
                                                            }}
                                                        />
                                                    )}
                                                </div>
                                            </div>
                                        ) : (
                                            <div className="flex flex-col h-full animate-in fade-in min-h-0">
                                                <div className="flex items-center justify-between p-4 border-b border-white/5 bg-[#0f0f11] shrink-0">
                                                    <h3 className="text-lg font-bold flex items-center gap-2"><ListMusic className="text-amber-500" size={20} /> مكتبة الصوت</h3>
                                                    <button aria-label="رجوع" onClick={() => setPanelSubView(null)} className="px-3 py-1 bg-white/5 hover:bg-white/10 rounded-lg text-xs flex items-center gap-1 transition-colors"><ArrowRight size={14} /> رجوع</button>
                                                </div>
                                                <div className="p-3 border-b border-white/5 bg-[#0a0a0c] shrink-0">
                                                    <div className="flex bg-black/40 rounded-lg p-1 border border-white/5 w-full max-w-[250px] mx-auto">
                                                        <button onClick={() => setShowFavoritesOnly(false)} className={`flex-1 py-1.5 text-xs rounded-md transition-all font-bold ${!showFavoritesOnly ? 'bg-amber-500/20 text-amber-400 shadow-sm' : 'text-gray-400 hover:text-white hover:bg-white/5'}`}>الكل</button>
                                                        <button onClick={() => setShowFavoritesOnly(true)} className={`flex-1 py-1.5 text-xs rounded-md transition-all flex items-center justify-center gap-1.5 font-bold ${showFavoritesOnly ? 'bg-red-500/20 text-red-400 shadow-sm' : 'text-gray-400 hover:text-white hover:bg-white/5'}`}><Heart size={12} className={showFavoritesOnly ? "fill-current" : ""} /> المفضلة</button>
                                                    </div>
                                                </div>
                                                <div className="flex-1 overflow-y-auto custom-scrollbar p-4" ref={audioLibScrollRef}>
                                                    {showFavoritesOnly && favorites.audio?.length === 0 ? (
                                                        <div className="flex flex-col items-center justify-center h-40 text-gray-500 gap-2"><Heart size={24} className="opacity-50" /><span>لا توجد أصوات في المفضلة</span></div>
                                                    ) : (
                                                        <LazyGrid
                                                            items={showFavoritesOnly ? audioLibraryFiles.filter(f => favorites.audio?.includes(f)) : audioLibraryFiles}
                                                            gridClassName="audio-grid"
                                                            initialCount={15}
                                                            batchSize={15}
                                                            renderItem={(f) => <LibraryAudioItem key={f} filename={f} onSelect={handleAudioLibrarySelect} playingFile={playingAudioPreview} setPlayingFile={setPlayingAudioPreview} isSelected={selectedAudioName === `audio4all/${f}`} previewVolume={volume} isFavorite={favorites.audio?.includes(f)} onToggleFavorite={(e) => { e.stopPropagation(); toggleFavorite('audio', f); }} />}
                                                        />
                                                    )}
                                                </div>
                                            </div>
                                        )}
                                    </div>
                                )}
                                {activeTab === 'content' && (
                                    <div className="flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4 relative">
                                        {isAnalyzingAI ? <div className="text-center p-8"><Loader2 className="mx-auto text-indigo-400 animate-spin mb-2" /><p className="text-sm text-indigo-300 animate-pulse">{aiStatus}</p></div> : timelineData.length > 0 ? (
                                            <>
                                                {/* تحذير عند وجود آيات من سور مختلفة */}
                                                {[...new Set(timelineData.map(item => item.surah))].length > 1 && (
                                                    <div className="flex items-center gap-2 p-2 mb-4 bg-amber-500/10 border border-amber-500/20 rounded-lg text-amber-200/80 text-xs animate-in fade-in slide-in-from-top-1">
                                                        <AlertTriangle size={14} className="text-amber-500 shrink-0" />
                                                        <span>تنبيه: يوجد آيات من سور مختلفة ({[...new Set(timelineData.map(item => item.surah))].length} سور)</span>
                                                    </div>
                                                )}

                                                {timelineData.map((seg, idx) => (
                                                    <React.Fragment key={seg.id}>
                                                        {isDragging && dropTargetIndex === idx && (
                                                            <div className="drop-indicator-line"></div>
                                                        )}
                                                        <div
                                                            data-id={seg.id}
                                                            onContextMenu={(e) => handleContextMenu(e, seg.id)}
                                                            onTouchStart={(e) => startPress(e, seg.id)}
                                                            onTouchEnd={cancelPress}
                                                            onTouchMove={cancelPress}
                                                            className={`draggable-item group p-3 rounded-lg border text-right text-xs transition-colors duration-200 ${draggedId === seg.id ? 'is-placeholder' : (currentTime >= seg.start && currentTime < seg.end ? 'bg-emerald-900/30 border-emerald-500 ring-1 ring-emerald-500/50' : 'bg-white/5 border-white/5')}`}
                                                        >
                                                            {/* Dotted Handle for Dragging */}
                                                            <div
                                                                className="absolute left-2 top-1/2 -translate-y-1/2 p-2 cursor-grab active:cursor-grabbing text-gray-500 hover:text-emerald-400 rounded drag-handle z-10"
                                                                onMouseDown={(e) => handleDragStart(e, seg.id)}
                                                                onTouchStart={(e) => handleDragStart(e, seg.id)}
                                                                title="اسحب للترتيب"
                                                            >
                                                                <GripVertical size={18} style={{ strokeDasharray: "2 2" }} />
                                                            </div>

                                                            <div className="flex gap-2 mb-2 items-center justify-between pl-6" dir="ltr">
                                                                <div data-tour="time-markers" className="flex items-center gap-1"><button aria-label="تحديد البداية" onClick={() => handleSetCurrentTime(seg.id, 'start')} className="p-1.5 bg-emerald-500/20 text-emerald-500 rounded"><MapPin size={14} /></button><TimeInput time={seg.start} onChange={v => handleSegmentTimeChange(seg.id, 'start', v)} className="w-16 bg-black border border-gray-700 rounded px-1 py-1 text-center text-emerald-400 text-xs" /></div>
                                                                <span className="text-gray-500">-</span>
                                                                <div className="flex items-center gap-1"><TimeInput time={seg.end} onChange={v => handleSegmentTimeChange(seg.id, 'end', v)} className="w-16 bg-black border border-gray-700 rounded px-1 py-1 text-center text-emerald-400 text-xs" /><button aria-label="تحديد النهاية" onClick={() => handleSetCurrentTime(seg.id, 'end')} className="p-1.5 bg-red-500/20 text-red-500 rounded"><MapPin size={14} /></button></div>
                                                            </div>
                                                            <input
                                                                value={seg.text}
                                                                onChange={e => setTimelineData(p => p.map(x => x.id === seg.id ? { ...x, text: e.target.value } : x))}
                                                                className="w-full bg-transparent font-amiri text-lg text-white outline-none border-b border-transparent focus:border-emerald-500 transition-colors py-1 leading-loose px-1"
                                                            />
                                                        </div>
                                                    </React.Fragment>
                                                ))}
                                                {isDragging && dropTargetIndex === timelineData.length && (
                                                    <div className="drop-indicator-line"></div>
                                                )}
                                                <button aria-label="تصدير JSON" onClick={handleExportTimelineJSON} className="w-full py-3 bg-gray-800 text-gray-300 rounded-xl flex items-center justify-center gap-2 mt-4 text-xs font-bold"><FileJson size={16} /> تصدير (JSON)</button>
                                                {/* Add Ayah Button */}
                                                <button
                                                    aria-label="إضافة آية"
                                                    onClick={() => setShowQuranSelector(true)}
                                                    className="w-full py-3 bg-gradient-to-r from-emerald-600 to-teal-600 hover:from-emerald-500 hover:to-teal-500 text-white rounded-xl flex items-center justify-center gap-2 text-xs font-bold transition-all shadow-lg"
                                                >
                                                    <BookOpen size={16} /> إضافة آية من القرآن
                                                </button>
                                            </>
                                        ) : (
                                            <div className="text-center py-10 space-y-4">
                                                <div className="text-gray-500 text-sm">يمكنك البدء بإضافة الآيات يدويًا أو رفع ملف صوتي للتحليل الذكي</div>
                                                <button
                                                    aria-label="إضافة آية"
                                                    onClick={() => setShowQuranSelector(true)}
                                                    className="mx-auto px-6 py-3 bg-gradient-to-r from-emerald-600 to-teal-600 hover:from-emerald-500 hover:to-teal-500 text-white rounded-xl flex items-center justify-center gap-2 text-xs font-bold transition-all shadow-lg"
                                                >
                                                    <BookOpen size={16} /> إضافة آية من القرآن
                                                </button>
                                            </div>
                                        )}
                                    </div>
                                )}
                                {activeTab === 'style' && (
                                    <div className="flex-1 flex flex-col min-h-0">
                                        {panelSubView !== 'textureLibrary' ? (
                                            <div className="flex-1 overflow-y-auto custom-scrollbar p-6 space-y-6">
                                                {bgType === 'image' && bgImageSrc && (
                                                    <div className="bg-white/5 p-4 rounded-xl border border-white/5 space-y-3">
                                                        <h3 className="text-xs font-bold text-gray-400 uppercase flex items-center gap-2"><Maximize size={14} /> إعدادات الصورة</h3>
                                                        <button
                                                            onClick={() => setShowImageEditor(true)}
                                                            className="w-full py-2.5 bg-white/10 hover:bg-white/20 text-white rounded-lg font-bold flex items-center justify-center gap-2 text-sm transition-colors border border-white/5"
                                                        >
                                                            <Move size={16} />
                                                            تعديل وقص الصورة
                                                        </button>
                                                    </div>
                                                )}

                                                {/* Overlay Settings - Redesigned with separate Color and Image sections */}
                                                <div data-tour="overlay" className="bg-white/5 p-4 rounded-xl border border-white/5 space-y-4">
                                                    <h3 className="text-xs font-bold text-gray-400 uppercase">خلفية الفيديو (Overlay)</h3>

                                                    {/* === COLOR SECTION === */}
                                                    <div className="bg-black/20 p-3 rounded-lg border border-white/5 space-y-3">
                                                        <div className="flex items-center gap-2">
                                                            <Palette size={14} className="text-emerald-500" />
                                                            <span className="text-xs font-bold text-white">طبقة اللون</span>
                                                        </div>

                                                        {/* Color Picker */}
                                                        <ColorPicker label="اللون" value={overlaySettings.value || '#000000'} onChange={e => setOverlaySettings({ ...overlaySettings, value: e.target.value })} />

                                                        {/* Color Opacity */}
                                                        <div className="space-y-1">
                                                            <div className="flex justify-between items-center text-xs">
                                                                <span className="text-gray-400">الشفافية</span>
                                                                <span className="font-mono text-emerald-400">{Math.round((overlaySettings.colorOpacity !== undefined ? overlaySettings.colorOpacity : (overlaySettings.opacity || 0)) * 100)}%</span>
                                                            </div>
                                                            <RangeSlider value={overlaySettings.colorOpacity !== undefined ? overlaySettings.colorOpacity : (overlaySettings.opacity || 0)} onChange={e => setOverlaySettings({ ...overlaySettings, colorOpacity: parseFloat(e.target.value) })} />
                                                        </div>
                                                    </div>

                                                    {/* === SEPARATOR === */}
                                                    <div className="flex items-center gap-3 py-1">
                                                        <div className="flex-1 h-px bg-gradient-to-l from-white/20 to-transparent"></div>
                                                        <span className="text-[10px] text-gray-500 font-bold uppercase tracking-wider">+</span>
                                                        <div className="flex-1 h-px bg-gradient-to-r from-white/20 to-transparent"></div>
                                                    </div>

                                                    {/* === IMAGE SECTION === */}
                                                    <div className="bg-black/20 p-3 rounded-lg border border-white/5 space-y-3">
                                                        <div className="flex items-center gap-2">
                                                            <ImageIcon size={14} className="text-emerald-500" />
                                                            <span className="text-xs font-bold text-white">طبقة الصورة</span>
                                                            <span className="text-[9px] text-gray-500 mr-auto">(اختياري)</span>
                                                        </div>
                                                        <div className="grid grid-cols-2 gap-2">
                                                            {/* Upload from device */}
                                                            <label className="flex flex-col items-center justify-center gap-1 p-3 border border-dashed border-gray-600 rounded-lg text-xs cursor-pointer hover:border-emerald-500 hover:bg-emerald-500/5 transition-all">
                                                                <Upload size={18} className="text-gray-400" />
                                                                <span className="text-gray-400">رفع صورة</span>
                                                                <input type="file" accept="image/*" className="hidden" onChange={handleOverlayImageUpload} />
                                                            </label>

                                                            {/* Choose from library */}
                                                            <button onClick={() => setPanelSubView('textureLibrary')} className="flex flex-col items-center justify-center gap-1 p-3 border border-gray-600 rounded-lg text-xs transition-all text-gray-400 hover:border-emerald-500 hover:bg-emerald-500/5">
                                                                <FolderOpen size={18} />
                                                                <span>المكتبة</span>
                                                            </button>
                                                        </div>

                                                        {/* Current image preview with opacity control */}
                                                        {overlaySettings.imageSrc && (
                                                            <>
                                                                <div className="relative">
                                                                    <img src={overlaySettings.imageSrc} alt="overlay" className="w-full h-20 object-cover rounded-lg border border-white/10" />
                                                                    <button onClick={() => { setOverlaySettings({ ...overlaySettings, imageSrc: null }); overlayImageRef.current = null; }} className="absolute top-1 right-1 bg-red-500/80 hover:bg-red-500 text-white rounded-full p-1">
                                                                        <X size={12} />
                                                                    </button>
                                                                </div>

                                                                {/* Image Opacity */}
                                                                <div className="space-y-1">
                                                                    <div className="flex justify-between items-center text-xs">
                                                                        <span className="text-gray-400">شفافية الصورة</span>
                                                                        <span className="font-mono text-emerald-400">{Math.round((overlaySettings.imageOpacity !== undefined ? overlaySettings.imageOpacity : (overlaySettings.opacity || 0)) * 100)}%</span>
                                                                    </div>
                                                                    <RangeSlider value={overlaySettings.imageOpacity !== undefined ? overlaySettings.imageOpacity : (overlaySettings.opacity || 0)} onChange={e => setOverlaySettings({ ...overlaySettings, imageOpacity: parseFloat(e.target.value) })} />
                                                                </div>
                                                            </>
                                                        )}
                                                    </div>
                                                </div>
                                                <div className="bg-white/5 p-4 rounded-xl border border-white/5 space-y-3">
                                                    <h3 className="text-xs font-bold text-gray-400 uppercase flex items-center gap-2"><Type size={14} /> تنسيق الآيات</h3>
                                                    <ColorPicker label="اللون" value={ayahStyle.color} onChange={e => setAyahStyle({ ...ayahStyle, color: e.target.value })} />
                                                    <div className="space-y-1">
                                                        <div className="flex justify-between items-center text-xs"><span>الحجم</span><span className="font-mono text-emerald-400">{ayahStyle.size}px</span></div>
                                                        <RangeSlider min={30} max={120} step={1} value={ayahStyle.size} onChange={e => setAyahStyle({ ...ayahStyle, size: parseInt(e.target.value) })} />
                                                    </div>
                                                    <ColorPicker label="لون الظل" value={ayahStyle.shadowColor} onChange={e => setAyahStyle({ ...ayahStyle, shadowColor: e.target.value })} />
                                                    <div className="space-y-1">
                                                        <div className="flex justify-between items-center text-xs"><span>شفافية الظل</span><span className="font-mono text-emerald-400">{Math.round((ayahStyle.shadowOpacity !== undefined ? ayahStyle.shadowOpacity : 0.5) * 100)}%</span></div>
                                                        <RangeSlider min={0} max={1} step={0.05} value={ayahStyle.shadowOpacity !== undefined ? ayahStyle.shadowOpacity : 0.5} onChange={e => setAyahStyle({ ...ayahStyle, shadowOpacity: parseFloat(e.target.value) })} />
                                                    </div>
                                                    <Toggle label="خط عريض" checked={ayahStyle.fontWeight === 'bold'} onChange={e => setAyahStyle({ ...ayahStyle, fontWeight: e.target.checked ? 'bold' : 'normal' })} />
                                                    <div className="space-y-2 pt-2 border-t border-white/5">
                                                        <div className="text-xs text-gray-400">تأثير الظهور (Animation)</div>
                                                        <div className="grid grid-cols-2 gap-2">
                                                            {[{ id: 'fade', label: 'تلاشي (Fade)' },
                                                            { id: 'slide_up', label: 'انزلاق لأعلى' },
                                                            { id: 'scale', label: 'تكبير (Scale)' },
                                                            { id: 'typewriter', label: 'كتابة حرفية' },
                                                            { id: 'word_by_word', label: 'كلمة بكلمة' },
                                                            { id: 'calm_word', label: 'كلمة بكلمة (هادئ)' },
                                                            { id: 'pop', label: 'انبثاق (Pop)' },
                                                            { id: 'blur', label: 'سينمائي (Blur)' },
                                                            { id: 'karaoke', label: 'تلوين (Karaoke)' },
                                                            { id: 'float', label: 'طوفان (Float)' },
                                                            { id: 'glow_pulse', label: 'توهج نابض' },
                                                            { id: 'pan', label: 'بانوراما (Pan)' },
                                                            { id: 'reveal', label: 'مسح عمودي' },
                                                            { id: 'fold', label: 'طي 3D' },
                                                            { id: 'focus_pull', label: 'عزل وتكبير' }].map(anim => (
                                                                <button
                                                                    key={anim.id}
                                                                    onClick={() => setAyahStyle({ ...ayahStyle, animation: anim.id })}
                                                                    className={`py-2 px-2 text-xs rounded-lg transition-colors border ${(ayahStyle.animation || 'fade') === anim.id
                                                                        ? 'bg-emerald-500/20 border-emerald-500/50 text-emerald-400'
                                                                        : 'bg-black/30 border-gray-700/50 text-gray-400 hover:bg-white/5'
                                                                        }`}
                                                                >
                                                                    {anim.label}
                                                                </button>
                                                            ))}
                                                        </div>
                                                    </div>
                                                </div>
                                                <div data-tour="watermark" className="bg-white/5 p-4 rounded-xl border border-white/5 space-y-3">
                                                    <div className="flex justify-between items-center"><h3 className="text-xs font-bold text-gray-400 uppercase">الحقوق (Watermark)</h3><Toggle checked={watermark.visible} onChange={e => setWatermark({ ...watermark, visible: e.target.checked })} /></div>
                                                    <input type="text" dir="ltr" value={watermark.text} onChange={e => setWatermark({ ...watermark, text: e.target.value })} placeholder="@user" className="w-full bg-black/30 border border-gray-700 rounded p-2 text-xs text-white text-left font-mono" />
                                                    <ColorPicker label="اللون" value={watermark.color} onChange={e => setWatermark({ ...watermark, color: e.target.value })} />
                                                    <div className="space-y-1">
                                                        <div className="flex justify-between items-center text-xs"><span>الحجم</span><span className="font-mono text-emerald-400">{watermark.size}px</span></div>
                                                        <RangeSlider min={15} max={60} step={1} value={watermark.size} onChange={e => setWatermark({ ...watermark, size: parseInt(e.target.value) })} />
                                                    </div>
                                                    <div className="space-y-1">
                                                        <div className="flex justify-between items-center text-xs"><span>الشفافية</span><span className="font-mono text-emerald-400">{Math.round(watermark.opacity * 100)}%</span></div>
                                                        <RangeSlider value={watermark.opacity} onChange={e => setWatermark({ ...watermark, opacity: parseFloat(e.target.value) })} />
                                                    </div>
                                                </div>
                                            </div>
                                        ) : (
                                            <div className="flex flex-col h-full animate-in fade-in min-h-0">
                                                <div className="flex items-center justify-between p-4 border-b border-white/5 bg-[#0f0f11] shrink-0">
                                                    <h3 className="text-lg font-bold flex items-center gap-2"><ImageIcon className="text-emerald-500" size={20} /> مكتبة الصور</h3>
                                                    <button aria-label="رجوع" onClick={() => setPanelSubView(null)} className="px-3 py-1 bg-white/5 hover:bg-white/10 rounded-lg text-xs flex items-center gap-1 transition-colors"><ArrowRight size={14} /> رجوع</button>
                                                </div>
                                                <div className="p-3 border-b border-white/5 bg-[#0a0a0c] shrink-0">
                                                    <div className="flex bg-black/40 rounded-lg p-1 border border-white/5 w-full max-w-[250px] mx-auto">
                                                        <button onClick={() => setShowFavoritesOnly(false)} className={`flex-1 py-1.5 text-xs rounded-md transition-all font-bold ${!showFavoritesOnly ? 'bg-emerald-500/20 text-emerald-400 shadow-sm' : 'text-gray-400 hover:text-white hover:bg-white/5'}`}>الكل</button>
                                                        <button onClick={() => setShowFavoritesOnly(true)} className={`flex-1 py-1.5 text-xs rounded-md transition-all flex items-center justify-center gap-1.5 font-bold ${showFavoritesOnly ? 'bg-red-500/20 text-red-400 shadow-sm' : 'text-gray-400 hover:text-white hover:bg-white/5'}`}><Heart size={12} className={showFavoritesOnly ? "fill-current" : ""} /> المفضلة</button>
                                                    </div>
                                                </div>
                                                <div className="flex-1 overflow-y-auto custom-scrollbar p-4" ref={el => { if (el) el.scrollTop = 0 }}>
                                                    {showFavoritesOnly && favorites.texture?.length === 0 ? (
                                                        <div className="flex flex-col items-center justify-center h-40 text-gray-500 gap-2"><Heart size={24} className="opacity-50" /><span>لا توجد خامات في المفضلة</span></div>
                                                    ) : (
                                                        <LazyGrid
                                                            items={showFavoritesOnly ? Array.from({ length: 23 }, (_, i) => i + 1).filter(i => favorites.texture?.includes(i.toString())) : Array.from({ length: 23 }, (_, i) => i + 1)}
                                                            gridClassName="video-grid"
                                                            renderItem={(i) => {
                                                                const isSelected = overlaySettings.imageSrc === `texture/${i}.png`;
                                                                const isFav = favorites.texture?.includes(i.toString());
                                                                return (
                                                                    <button key={i} onClick={() => {
                                                                        const img = new Image();
                                                                        img.onload = () => { overlayImageRef.current = img; setOverlaySettings({ ...overlaySettings, imageSrc: `texture/${i}.png` }); };
                                                                        img.src = `texture/${i}.png`;
                                                                        setPanelSubView(null);
                                                                    }} className={`video-card group ${isSelected ? 'ring-2 ring-emerald-500 ring-offset-2 ring-offset-black' : ''}`}>
                                                                        <img src={`texture/${i}.png`} alt={`texture ${i}`} className="w-full h-full object-cover" onError={(e) => { e.target.style.display = 'none'; }} />
                                                                        <span className="absolute top-2 left-2 z-20 bg-black/60 backdrop-blur-sm text-white text-[10px] px-2 py-0.5 rounded-md font-mono">#{i}</span>
                                                                        <button onClick={(e) => { e.stopPropagation(); toggleFavorite('texture', i.toString()); }} className={`absolute bottom-2 left-2 z-30 p-1.5 rounded-full backdrop-blur-sm transition-all ${isFav ? 'bg-red-500/20 text-red-500' : 'bg-black/40 text-gray-400 opacity-0 group-hover:opacity-100 hover:text-white hover:bg-black/60'}`}>
                                                                            <Heart size={14} className={isFav ? "fill-current" : ""} />
                                                                        </button>
                                                                        {isSelected && <div className="absolute top-2 right-2 z-20 bg-emerald-500 text-black rounded-full p-1"><Check size={12} /></div>}
                                                                        <div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition flex flex-col items-center justify-center gap-2">
                                                                            <Check size={32} className="text-emerald-500" />
                                                                        </div>
                                                                    </button>
                                                                )
                                                            }}
                                                        />
                                                    )}

                                                </div>
                                            </div>
                                        )}
                                    </div>
                                )}
                                {activeTab === 'export' && (
                                    <div className="flex-1 overflow-y-auto custom-scrollbar p-6 space-y-6 flex flex-col">
                                        <div data-tour="branding" className="p-4 bg-emerald-500/10 border border-emerald-500/30 rounded-2xl relative overflow-hidden group hover:border-emerald-500/50 transition-colors shrink-0"><div className="flex justify-between items-start mb-2 relative z-10"><div><h3 className="font-bold text-white flex items-center gap-2"><Heart size={16} className="text-emerald-500 fill-emerald-500" /> ساهم في نشر الخير</h3><p className="text-[10px] text-gray-400 mt-1 max-w-[200px]">تفعيل ظهور اسم الموقع يساعد في النشر.</p></div><div onClick={() => setShowSiteBranding(!showSiteBranding)} className={`w-12 h-6 rounded-full cursor-pointer relative transition-colors duration-300 ${showSiteBranding ? 'bg-emerald-500' : 'bg-gray-700'}`}><div className={`w-4 h-4 bg-white rounded-full absolute top-1 transition-all duration-300 ${showSiteBranding ? 'left-1' : 'left-7'}`}></div></div></div><div className="text-[10px] text-emerald-200/70 font-amiri mt-2 relative z-10">قال رسول الله ﷺ: (الدال على الخير كفاعله)</div><div className="absolute -right-4 -bottom-4 text-emerald-500/5 opacity-50"><Heart size={100} fill="currentColor" /></div></div>

                                        {/* Professional Caption Section */}
                                        <div className="bg-gradient-to-br from-emerald-500/10 to-teal-500/10 border border-emerald-500/20 rounded-2xl p-4 space-y-3 shrink-0">
                                            <div className="flex items-center justify-between">
                                                <h3 className="font-bold text-white flex items-center gap-2 text-sm">
                                                    <Hash size={16} className="text-emerald-400" />
                                                    وصف جاهز للنشر
                                                </h3>
                                                <div className="flex gap-2">
                                                    <button
                                                        aria-label="تحديث الوصف"
                                                        onClick={() => {
                                                            let newIndex;
                                                            do {
                                                                newIndex = Math.floor(Math.random() * CAPTION_TEMPLATES.length);
                                                            } while (CAPTION_TEMPLATES[newIndex] === currentCaption && CAPTION_TEMPLATES.length > 1);
                                                            setCurrentCaption(CAPTION_TEMPLATES[newIndex]);
                                                            setCaptionCopied(false);
                                                        }}
                                                        className="p-2 bg-white/5 hover:bg-white/10 rounded-lg text-emerald-400 hover:text-emerald-300 transition-all hover:rotate-180 duration-300"
                                                        title="وصف آخر"
                                                    >
                                                        <RefreshCcw size={16} />
                                                    </button>
                                                    <button
                                                        aria-label="نسخ الوصف"
                                                        onClick={() => {
                                                            const fullCaption = `${currentCaption.text}\n.\n.\n.\n${currentCaption.hashtags}`;
                                                            navigator.clipboard.writeText(fullCaption).then(() => {
                                                                setCaptionCopied(true);
                                                                setTimeout(() => setCaptionCopied(false), 2000);
                                                            });
                                                        }}
                                                        className={`p-2 rounded-lg transition-all ${captionCopied ? 'bg-emerald-500 text-white' : 'bg-white/5 hover:bg-white/10 text-gray-400 hover:text-white'}`}
                                                        title="نسخ الوصف"
                                                    >
                                                        {captionCopied ? <Check size={16} /> : <Copy size={16} />}
                                                    </button>
                                                </div>
                                            </div>
                                            <div className="bg-black/30 rounded-xl p-3 border border-white/5">
                                                <p className="text-white text-sm leading-relaxed mb-3">{currentCaption.text}</p>
                                                <div className="flex items-center gap-1 text-[10px] text-gray-500 mb-2">
                                                    <span>.</span><span>.</span><span>.</span>
                                                </div>
                                                <p className="text-emerald-300/80 text-[11px] leading-relaxed break-words" dir="rtl">{currentCaption.hashtags}</p>
                                            </div>
                                            <p className="text-[10px] text-gray-500 text-center">انسخ الوصف والصقه عند نشر الفيديو على انستقرام أو تيكتوك</p>
                                        </div>

                                        <div className="pt-4 shrink-0 flex gap-2">
                                            <button aria-label="قص وتصدير" onClick={handleTrimAndSave} disabled={isExporting || !audioSrc || (bgType === 'video' && !videoSrc) || (bgType === 'image' && !bgImageSrc)} className={`w-16 py-4 font-bold rounded-xl flex items-center justify-center transition shadow-xl ${isExporting || !audioSrc || (bgType === 'video' && !videoSrc) || (bgType === 'image' && !bgImageSrc) ? 'bg-gray-600 text-gray-400 cursor-not-allowed opacity-50' : 'bg-[#1a1a1a] text-emerald-500 hover:bg-[#252525] border border-white/5'}`} title="قص جزء وحفظه"><Scissors size={20} /></button>
                                            <button aria-label="تصدير الفيديو" onClick={handleExportClick} disabled={isExporting || !audioSrc || (bgType === 'video' && !videoSrc) || (bgType === 'image' && !bgImageSrc)} className={`flex-1 py-4 font-bold rounded-xl flex items-center justify-center gap-2 transition shadow-xl ${isExporting || !audioSrc || (bgType === 'video' && !videoSrc) || (bgType === 'image' && !bgImageSrc) ? 'bg-gray-600 text-gray-400 cursor-not-allowed opacity-50' : 'bg-white text-black hover:bg-gray-200'}`}>{isExporting ? <Loader2 className="animate-spin" /> : <Download size={20} />} {isExporting ? 'جاري...' : 'تصدير الفيديو'}</button>
                                        </div>
                                        {exportRange && (exportRange.start > 0 || exportRange.end < (audioRange.end - audioRange.start)) && (
                                            <div className="text-center bg-emerald-500/10 border border-emerald-500/20 rounded-lg p-2 animate-in fade-in">
                                                <p className="text-[10px] text-emerald-400 font-mono">
                                                    ✂ تم قص الفيديو وسيتم حفظ الجزء المحدد فقط
                                                </p>
                                            </div>
                                        )}

                                        <div className="flex-1"></div>

                                        <div className="border-t border-white/10 pt-4 shrink-0">
                                            <button onClick={() => setIsSettingsCollapsed(!isSettingsCollapsed)} className="w-full flex items-center justify-between text-gray-400 hover:text-white mb-4 transition-colors">
                                                <span className="font-bold flex items-center gap-2 text-sm"><Settings size={16} /> إدارة الإعدادات المتقدمة</span>
                                                {isSettingsCollapsed ? <ChevronDown size={16} /> : <ChevronUp size={16} />}
                                            </button>

                                            {!isSettingsCollapsed && (
                                                <div data-tour="settings" className="bg-white/5 p-4 rounded-xl border border-white/5 space-y-3 animate-in slide-in-from-top-2 fade-in duration-200">
                                                    <h3 className="text-xs font-bold text-gray-400 uppercase flex items-center gap-2">إدارة الإعدادات</h3>
                                                    <div className="grid grid-cols-2 gap-2"><button aria-label="حفظ الإعدادات" onClick={handleExportSettings} className="flex items-center justify-center gap-2 py-2 bg-gray-800 rounded-lg text-xs hover:bg-gray-700 transition"><Save size={14} /> حفظ</button><button aria-label="تحميل إعدادات" onClick={() => fileInputRef.current.click()} className="flex items-center justify-center gap-2 py-2 bg-gray-800 rounded-lg text-xs hover:bg-gray-700 transition"><UploadCloud size={14} /> تحميل</button><input ref={fileInputRef} type="file" accept=".json" className="hidden" onChange={handleImportSettings} /></div><button aria-label="إعادة تعيين" onClick={() => setShowResetConfirm(true)} className="w-full flex items-center justify-center gap-2 py-2 bg-red-500/10 text-red-400 rounded-lg text-xs hover:bg-red-500/20 transition"><RefreshCcw size={14} /> إعادة تعيين</button>
                                                </div>
                                            )}
                                        </div>
                                    </div>
                                )}
                            </div>

                        </div>
                    </div>

                    {/* Preview Area */}
                    <div className={`w-full md:flex-1 ${isExporting ? 'h-[100dvh] absolute top-0 left-0 z-50' : 'flex-1 min-h-0 pt-header-safe'} md:pt-0 md:h-full md:static bg-[#050505] flex flex-col relative z-10`}>
                        <div className="flex-1 flex items-center justify-center p-4 relative overflow-hidden" onPointerUp={() => { setDragState(p => ({ ...p, isDragging: false })); setSnapState({ x: false, y: false }) }}>
                            {!videoSrc && !bgImageSrc && (<div className="absolute inset-0 flex items-center justify-center bg-gray-900/80 backdrop-blur-md z-40"><div className="flex flex-col gap-4 md:gap-6"><label className="flex flex-col items-center gap-2 md:gap-4 cursor-pointer group"><div className="w-14 h-14 md:w-20 md:h-20 bg-emerald-500/10 border-2 border-emerald-500/50 rounded-full flex items-center justify-center group-hover:scale-110 transition"><Upload className="w-6 h-6 md:w-8 md:h-8 text-emerald-500" /></div><div className="text-center"><h3 className="text-sm md:text-xl font-bold text-white mb-1">رفع فيديو</h3></div><input type="file" accept="video/*" className="hidden" onChange={e => handleFileUpload(e, 'video')} /></label><div className="flex items-center gap-4 text-gray-600 before:h-px before:flex-1 before:bg-gray-700 after:h-px after:flex-1 after:bg-gray-700 text-xs md:text-base">أو</div><button aria-label="مكتبة" onClick={() => setPanelSubView('videoLib')} className="flex flex-col items-center gap-2 md:gap-4 cursor-pointer group"><div className="w-14 h-14 md:w-20 md:h-20 bg-blue-500/10 border-2 border-blue-500/50 rounded-full flex items-center justify-center group-hover:scale-110 transition"><Grid className="w-6 h-6 md:w-8 md:h-8 text-blue-500" /></div><div className="text-center"><h3 className="text-sm md:text-xl font-bold text-white mb-1">مكتبة الفيديوهات</h3></div></button></div></div>)}
                            <div className="relative w-auto h-auto max-w-full max-h-full aspect-[9/16] shadow-2xl border border-white/10 rounded-2xl overflow-hidden bg-black select-none touch-none" onPointerDown={hPD} onPointerMove={hPM} onPointerUp={() => { setDragState(p => ({ ...p, isDragging: false })); setSnapState({ x: false, y: false }) }} onPointerLeave={() => { setDragState(p => ({ ...p, isDragging: false })); setSnapState({ x: false, y: false }) }}>
                                <canvas ref={canvasRef} width={CANVAS_WIDTH} height={CANVAS_HEIGHT} className="w-full h-full object-contain" />
                                {(snapState.x || snapState.y) && dragState.isDragging && !isExporting && (<div className="absolute top-4 right-4 bg-emerald-500 text-black text-xs font-bold px-3 py-1 rounded-full shadow-lg animate-pulse pointer-events-none">منتصف</div>)}
                                {isExporting && (
                                    <>
                                        <svg className="absolute inset-0 w-full h-full pointer-events-none z-40" preserveAspectRatio="none">
                                            <rect x="2" y="2" width="calc(100% - 4px)" height="calc(100% - 4px)" rx="14" ry="14" fill="none" stroke="#10b981" strokeWidth="6" pathLength="100" strokeDasharray="100" strokeDashoffset={100 - (totalDuration > 0 ? Math.min(100, Math.max(0, (currentProgress / totalDuration) * 100)) : 0)} className="transition-all duration-300 ease-linear drop-shadow-[0_0_15px_rgba(16,185,129,0.5)]" />
                                        </svg>
                                        <div className="absolute inset-0 z-50 flex items-center justify-center p-4">
                                            <div className="bg-[#111]/80 backdrop-blur-xl border border-emerald-500/20 rounded-2xl p-8 max-w-sm w-full text-center shadow-[0_0_50px_rgba(0,0,0,0.5)] transform transition-all animate-in fade-in zoom-in-95">
                                                <div className="flex flex-col items-center gap-4">
                                                    <div className="relative">
                                                        <div className="absolute inset-0 bg-emerald-500 blur-lg opacity-20 rounded-full animate-pulse"></div>
                                                        <Download size={40} className="text-emerald-500 relative z-10 animate-bounce" />
                                                    </div>
                                                    <div className="space-y-1">
                                                        <h3 className="text-2xl font-bold text-white">جاري التصدير...</h3>
                                                        <div className="h-1 w-24 bg-gray-800 rounded-full mx-auto overflow-hidden">
                                                            <div className="h-full bg-emerald-500 animate-pulse w-full"></div>
                                                        </div>
                                                    </div>
                                                    <div className="py-4 w-full border-y border-white/5 my-2">
                                                        <p className="text-emerald-300 font-amiri text-lg leading-relaxed animate-pulse">
                                                            {currentDua}
                                                        </p>
                                                    </div>
                                                    <p className="text-gray-400 text-[10px] flex items-center gap-2 bg-white/5 px-3 py-1.5 rounded-full border border-white/5">
                                                        <AlertTriangle size={12} className="text-amber-500" />
                                                        يرجى عدم إغلاق الصفحة حتى اكتمال التحميل
                                                    </p>
                                                </div>
                                            </div>
                                        </div>
                                    </>
                                )}
                            </div>
                        </div>
                        {(videoSrc || bgImageSrc) && !isExporting && (
                            <div className="w-full px-4 pb-10 md:px-6 md:pb-6 pt-0 md:pt-4 flex justify-center z-30">
                                <div className="w-full max-w-4xl h-14 md:h-20 bg-[#111]/90 backdrop-blur-md border border-white/10 rounded-2xl flex items-center px-4 md:px-6 gap-3 md:gap-4 shadow-2xl">
                                    <button aria-label={isPlaying ? "إيقاف" : "تشغيل"} onClick={togglePlay} disabled={!audioSrc || isAnalyzingAI || isProcessingAudio} className={`w-10 h-10 md:w-12 md:h-12 rounded-full flex items-center justify-center shadow-lg flex-shrink-0 transition-all ${!audioSrc || isAnalyzingAI || isProcessingAudio ? 'bg-gray-600 text-gray-400 cursor-not-allowed' : 'bg-white text-black hover:scale-105 hover:bg-emerald-400'}`}>{isAnalyzingAI ? <Loader2 size={20} className="animate-spin md:w-6 md:h-6" /> : (isPlaying ? <Pause size={20} className="md:w-6 md:h-6" fill="currentColor" /> : <Play size={20} className="md:w-6 md:h-6 ml-1" fill="currentColor" />)}</button>

                                    {/* Volume Control - Desktop Only */}
                                    <div className="hidden md:flex items-center justify-center group relative mx-1">
                                        {/* Button */}
                                        <button className="p-2 text-gray-400 hover:text-white transition-colors rounded-full hover:bg-white/5 relative z-20">
                                            {volume === 0 ? <VolumeX size={20} /> : volume < 0.5 ? <Volume1 size={20} /> : <Volume2 size={20} />}
                                        </button>

                                        {/* Hover Bridge (Invisible area to keep hover active) */}
                                        <div className="absolute bottom-full left-0 w-full h-6 bg-transparent z-10"></div>

                                        {/* Vertical Slider Container */}
                                        <div className="absolute bottom-[calc(100%+4px)] left-1/2 -translate-x-1/2 bg-[#151515] border border-white/10 p-3 pb-4 rounded-[2rem] shadow-[0_4px_20px_rgba(0,0,0,0.5)] flex flex-col items-center opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-300 transform origin-bottom translate-y-2 group-hover:translate-y-0 z-20">

                                            {/* Value Text */}
                                            <span className="text-[10px] font-mono text-emerald-400 mb-2 font-bold">{Math.round(volume * 100)}</span>

                                            {/* The Slider Track Wrapper */}
                                            <div className="relative w-1.5 h-24 rounded-full bg-gray-700/50">
                                                {/* The Green Fill */}
                                                <div
                                                    className="absolute bottom-0 left-0 w-full bg-emerald-500 rounded-full transition-all duration-100"
                                                    style={{ height: `${volume * 100}%` }}
                                                ></div>

                                                {/* The Thumb (Visual) */}
                                                <div
                                                    className="absolute left-1/2 -translate-x-1/2 w-3.5 h-3.5 bg-white rounded-full shadow-[0_0_10px_rgba(16,185,129,0.5)] pointer-events-none transition-all duration-100"
                                                    style={{ bottom: `calc(${volume * 100}% - 7px)` }}
                                                ></div>

                                                {/* The Actual Input (Invisible but interactive) */}
                                                <input
                                                    dir="ltr"
                                                    type="range"
                                                    min="0"
                                                    max="1"
                                                    step="0.01"
                                                    value={volume}
                                                    onChange={(e) => setVolume(parseFloat(e.target.value))}
                                                    className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[96px] h-6 opacity-0 cursor-pointer z-30"
                                                    style={{ transform: 'translate(-50%, -50%) rotate(-90deg)' }}
                                                />
                                            </div>
                                        </div>
                                    </div>

                                    <div className="flex-1 flex flex-col justify-center gap-1 md:gap-2"><div className="flex items-center gap-2 md:gap-3"><span className="text-[10px] md:text-xs font-mono text-emerald-400 text-right">{formatTime(currentProgress)}</span><WaveformSeeker currentTime={currentProgress} duration={totalDuration} onSeek={handleWaveformSeek} audioSrc={audioSrc} /><span className="text-[10px] md:text-xs font-mono text-gray-500">{formatTime(totalDuration)}</span></div></div>
                                </div>
                            </div>
                        )}
                    </div>
                    {showCompositionTrimmer && <CompositionTrimmerModal
                        duration={audioRange.end - audioRange.start}
                        initialRange={exportRange || { start: 0, end: audioRange.end - audioRange.start }}
                        currentTime={currentTime - audioRange.start}
                        canvasRef={canvasRef}
                        isPlaying={isPlaying}
                        onTogglePlayback={togglePlay}
                        setPreviewTime={(t) => handleWaveformSeek(t)}
                        onConfirm={handleCompositionTrimConfirm}
                        onClose={() => setShowCompositionTrimmer(false)}
                    />}
                    <VideoOfTheDayModal
                        isOpen={showTOD}
                        onClose={() => setShowTOD(false)}
                    />
                </div>
            );
        }
        class AppErrorBoundary extends React.Component {
            constructor(props) { super(props); this.state = { hasError: false }; }
            static getDerivedStateFromError() { return { hasError: true }; }
            componentDidCatch(error, info) {
                console.error('[React Error]', error, info);
            }
            render() {
                if (this.state.hasError) {
                    return (
                        <div style={{
                            display: 'flex', alignItems: 'center', justifyContent: 'center',
                            height: '100vh', background: '#0a0a0a', color: 'white',
                            fontFamily: 'Tajawal, sans-serif', textAlign: 'center', padding: '20px'
                        }}>
                            <div>
                                <div style={{ fontSize: '4rem', marginBottom: '1rem' }}>⚠️</div>
                                <h2 style={{ color: '#ef4444', marginBottom: '0.5rem' }}>حدث خطأ غير متوقع</h2>
                                <p style={{ color: '#888', marginBottom: '1.5rem' }}>نعتذر عن هذا الخطأ. يرجى إعادة تحميل التطبيق.</p>
                                <button onClick={() => window.location.reload()}
                                    style={{
                                        padding: '12px 32px', background: '#10b981', color: 'white',
                                        border: 'none', borderRadius: '12px', fontSize: '1rem',
                                        cursor: 'pointer', fontFamily: 'Tajawal, sans-serif'
                                    }}>🔄 إعادة التحميل</button>
                            </div>
                        </div>
                    );
                }
                return this.props.children;
            }
        }
        class AppLoaderManager extends React.Component {
            componentDidMount() {
                const loader = document.getElementById('quran-loader-overlay');
                if (loader) {
                    const elapsed = Date.now() - (window._quranLoaderStartTime || Date.now());
                    // Ensure loader shows for AT LEAST 1.5 seconds (1500ms)
                    const remainingDelay = Math.max(0, 1500 - elapsed);
                    setTimeout(() => {
                        loader.style.opacity = '0';
                        loader.style.visibility = 'hidden';
                        setTimeout(() => loader.remove(), 800); // Wait for fade transition
                    }, remainingDelay);
                }
            }
            render() { return null; }
        }

        createRoot(document.getElementById('root')).render(
            <AppErrorBoundary>
                <AppLoaderManager />
                <QuranFlowApp />
            </AppErrorBoundary>
        );
