<?php
declare(strict_types=1);

namespace App\Modules\Tutorials\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Modules\Tutorials\TutorialRegistry;

class TutorialController extends Controller
{
    private const SA_TUTORIALS = [
        'setup-discipline' => [
            'title'    => 'إنشاء لعبة رياضية جديدة',
            'subtitle' => 'تعريف نشاط رياضي في النظام',
            'icon'     => 'activity',
            'color'    => '#8B5CF6',
            'category' => 'setup',
            'order'    => 1,
        ],
        'setup-facility' => [
            'title'    => 'إنشاء مرفق ووحداته',
            'subtitle' => 'تعريف ملعب أو حمام سباحة مع الوحدات',
            'icon'     => 'building',
            'color'    => '#3B82F6',
            'category' => 'setup',
            'order'    => 2,
        ],
        'setup-time-brackets' => [
            'title'    => 'إعداد شرائح الوقت',
            'subtitle' => 'تعريف أوقات الذروة والعادية',
            'icon'     => 'clock',
            'color'    => '#06B6D4',
            'category' => 'setup',
            'order'    => 3,
        ],
        'setup-pricing' => [
            'title'    => 'إعداد قواعد التسعير',
            'subtitle' => 'ربط المرفق × الشريحة × عدد الأفراد بالسعر',
            'icon'     => 'banknote',
            'color'    => '#059669',
            'category' => 'setup',
            'order'    => 4,
        ],
        'register-coach' => [
            'title'    => 'تسجيل مدرب جديد',
            'subtitle' => 'إضافة مدرب مع تخصصاته ونظام الدفع',
            'icon'     => 'user-check',
            'color'    => '#059669',
            'category' => 'registration',
            'order'    => 5,
        ],
        'register-player' => [
            'title'    => 'تسجيل لاعب جديد',
            'subtitle' => 'تسجيل لاعب ورفع الشهادة الطبية',
            'icon'     => 'user-plus',
            'color'    => '#F59E0B',
            'category' => 'registration',
            'order'    => 6,
        ],
        'medical-workflow' => [
            'title'    => 'دورة الموافقة الطبية',
            'subtitle' => 'من الرفع حتى الاعتماد من اللجنة الطبية',
            'icon'     => 'heart-pulse',
            'color'    => '#F97316',
            'category' => 'registration',
            'order'    => 7,
        ],
        'setup-academy' => [
            'title'    => 'إنشاء أكاديمية وعقدها',
            'subtitle' => 'تسجيل أكاديمية خارجية مع عقد PDF',
            'icon'     => 'school',
            'color'    => '#8B5CF6',
            'category' => 'academy',
            'order'    => 8,
        ],
        'create-program' => [
            'title'    => 'إنشاء برنامج تدريبي',
            'subtitle' => 'تعريف برنامج بمواصفات العمر والمستوى',
            'icon'     => 'book-open',
            'color'    => '#EC4899',
            'category' => 'academy',
            'order'    => 9,
        ],
        'create-group' => [
            'title'    => 'إنشاء مجموعة تدريبية',
            'subtitle' => 'مجموعة مع مدرب وجدول أسبوعي',
            'icon'     => 'layers',
            'color'    => '#EC4899',
            'category' => 'academy',
            'order'    => 10,
        ],
        'enroll-player' => [
            'title'    => 'تسجيل لاعب في مجموعة',
            'subtitle' => 'التحاق لاعب بمجموعة تدريبية مع طلب الدفع الإجباري',
            'icon'     => 'user-plus',
            'color'    => '#10B981',
            'category' => 'academy',
            'order'    => 11,
        ],
        'enrollment-payment' => [
            'title'    => 'الدفع الإجباري عند التسجيل',
            'subtitle' => 'لا يتم تفعيل التسجيل بدون دفع أول اشتراك من خزنة الأنشطة',
            'icon'     => 'shield-check',
            'color'    => '#059669',
            'category' => 'financial',
            'order'    => 12,
        ],
        'sports-payment-queue' => [
            'title'    => 'طابور دفع الأنشطة الرياضية',
            'subtitle' => 'عرض ومعالجة طلبات الدفع في خزنة الأنشطة الفرعية',
            'icon'     => 'list-ordered',
            'color'    => '#2563EB',
            'category' => 'financial',
            'order'    => 13,
        ],
        'generate-training-bookings' => [
            'title'    => 'توليد حجوزات التمارين',
            'subtitle' => 'إنشاء حجوزات تلقائية من جدول المجموعة',
            'icon'     => 'calendar-plus',
            'color'    => '#06B6D4',
            'category' => 'scheduling',
            'order'    => 12,
        ],
        'create-hourly-booking' => [
            'title'    => 'حجز ساعة ملعب',
            'subtitle' => 'حجز وحدة لوقت محدد (حجز بالساعة)',
            'icon'     => 'calendar-clock',
            'color'    => '#3B82F6',
            'category' => 'scheduling',
            'order'    => 13,
        ],
        'booking-shared-lane' => [
            'title'    => 'حجز حارة سباحة (مشترك)',
            'subtitle' => 'حجز أماكن في حارة مع آخرين',
            'icon'     => 'waves',
            'color'    => '#0EA5E9',
            'category' => 'scheduling',
            'order'    => 14,
        ],
        'conflict-detection' => [
            'title'    => 'كشف التعارضات',
            'subtitle' => 'كيف يمنع النظام الحجوزات المتعارضة',
            'icon'     => 'shield-alert',
            'color'    => '#DC2626',
            'category' => 'scheduling',
            'order'    => 15,
        ],
        'generate-subscriptions' => [
            'title'    => 'توليد الاشتراكات الشهرية',
            'subtitle' => 'إنشاء فواتير شهرية للاعبين المسجلين',
            'icon'     => 'receipt',
            'color'    => '#059669',
            'category' => 'financial',
            'order'    => 16,
        ],
        'collect-payment' => [
            'title'    => 'تحصيل اشتراك',
            'subtitle' => 'تسجيل دفع اشتراك لاعب',
            'icon'     => 'credit-card',
            'color'    => '#10B981',
            'category' => 'financial',
            'order'    => 17,
        ],
        'exempt-subscription' => [
            'title'    => 'إعفاء من اشتراك',
            'subtitle' => 'إعفاء لاعب من رسوم شهرية',
            'icon'     => 'badge-percent',
            'color'    => '#F59E0B',
            'category' => 'financial',
            'order'    => 18,
        ],
        'record-attendance' => [
            'title'    => 'تسجيل الحضور',
            'subtitle' => 'تسجيل حضور لاعبين في تمرين',
            'icon'     => 'clipboard-check',
            'color'    => '#059669',
            'category' => 'operations',
            'order'    => 19,
        ],
        'mirror-view' => [
            'title'    => 'شاشة المراية (المرافق)',
            'subtitle' => 'عرض حالة المرافق والحجوزات لحظياً',
            'icon'     => 'monitor',
            'color'    => '#6366F1',
            'category' => 'operations',
            'order'    => 20,
        ],
        'waitlist-management' => [
            'title'    => 'إدارة قائمة الانتظار',
            'subtitle' => 'إضافة لاعب لقائمة انتظار مجموعة ممتلئة',
            'icon'     => 'list-ordered',
            'color'    => '#F97316',
            'category' => 'operations',
            'order'    => 21,
        ],
        'blackout-dates' => [
            'title'    => 'حجب مواعيد (صيانة)',
            'subtitle' => 'إغلاق مرفق لفترة صيانة أو إجازة',
            'icon'     => 'calendar-x',
            'color'    => '#DC2626',
            'category' => 'operations',
            'order'    => 22,
        ],
        'full-swimming-workflow' => [
            'title'    => 'سيناريو كامل: حمام سباحة',
            'subtitle' => 'من الإعداد حتى التشغيل اليومي',
            'icon'     => 'waves',
            'color'    => '#0EA5E9',
            'category' => 'scenarios',
            'order'    => 23,
        ],
        'full-football-workflow' => [
            'title'    => 'سيناريو كامل: كرة قدم',
            'subtitle' => 'أكاديمية كرة قدم من الصفر للتشغيل',
            'icon'     => 'circle-dot',
            'color'    => '#10B981',
            'category' => 'scenarios',
            'order'    => 24,
        ],
        'full-tennis-workflow' => [
            'title'    => 'سيناريو كامل: تنس',
            'subtitle' => 'ملاعب تنس بحجز بالساعة وتمارين',
            'icon'     => 'target',
            'color'    => '#F59E0B',
            'category' => 'scenarios',
            'order'    => 25,
        ],
    ];

    private const CATEGORIES = [
        'setup'        => ['label' => 'الإعداد الأساسي',    'icon' => 'settings',       'color' => '#8B5CF6'],
        'registration' => ['label' => 'التسجيل',            'icon' => 'user-plus',      'color' => '#F59E0B'],
        'academy'      => ['label' => 'الأكاديميات والبرامج', 'icon' => 'school',        'color' => '#EC4899'],
        'scheduling'   => ['label' => 'الجدولة والحجوزات',   'icon' => 'calendar',       'color' => '#3B82F6'],
        'financial'    => ['label' => 'المالي والاشتراكات',  'icon' => 'banknote',       'color' => '#059669'],
        'operations'   => ['label' => 'التشغيل اليومي',     'icon' => 'monitor',        'color' => '#06B6D4'],
        'scenarios'    => ['label' => 'سيناريوهات كاملة',   'icon' => 'play-circle',    'color' => '#6366F1'],
    ];

    private const TREASURY_TUTORIALS = [
        'open-session' => ['title' => 'فتح وردية', 'subtitle' => 'بدء وردية جديدة في الخزنة الفرعية', 'icon' => 'play', 'color' => '#059669', 'category' => 'operations', 'order' => 1],
        'collect-payment' => ['title' => 'تحصيل دفعة', 'subtitle' => 'تحصيل اشتراك نشاط رياضي من الطابور', 'icon' => 'credit-card', 'color' => '#3B82F6', 'category' => 'operations', 'order' => 2],
        'close-session' => ['title' => 'إغلاق وردية', 'subtitle' => 'إغلاق الوردية وعرض الإجمالي', 'icon' => 'square', 'color' => '#F59E0B', 'category' => 'operations', 'order' => 3],
        'initiate-settlement' => ['title' => 'تسوية مع الرئيسية', 'subtitle' => 'تحويل كامل المحصل للخزنة الرئيسية', 'icon' => 'arrow-up-right', 'color' => '#8B5CF6', 'category' => 'settlement', 'order' => 4],
        'receive-settlement' => ['title' => 'استلام تسوية', 'subtitle' => 'تأكيد استلام التسوية في الخزنة الرئيسية', 'icon' => 'arrow-down-left', 'color' => '#EC4899', 'category' => 'settlement', 'order' => 5],
        'bank-deposit' => ['title' => 'إيداع في البنك', 'subtitle' => 'إيداع النقدية ورفع إيصال البنك', 'icon' => 'building-2', 'color' => '#06B6D4', 'category' => 'deposit', 'order' => 6],
        'confirm-deposit' => ['title' => 'تأكيد الإيداع', 'subtitle' => 'تأكيد مدير الحسابات وإخلاء العهدة', 'icon' => 'check-circle', 'color' => '#059669', 'category' => 'deposit', 'order' => 7],
        'custody-tracking' => ['title' => 'متابعة العهدة', 'subtitle' => 'فهم رصيد العهدة وسجل الحركات', 'icon' => 'eye', 'color' => '#F97316', 'category' => 'custody', 'order' => 8],
        'full-cycle' => ['title' => 'دورة التحصيلات الكاملة', 'subtitle' => 'من التحصيل حتى إخلاء العهدة', 'icon' => 'play-circle', 'color' => '#6366F1', 'category' => 'scenarios', 'order' => 9],
    ];

    private const TREASURY_CATEGORIES = [
        'operations' => ['label' => 'العمليات اليومية', 'icon' => 'monitor', 'color' => '#059669'],
        'settlement' => ['label' => 'التسويات', 'icon' => 'arrow-right-left', 'color' => '#8B5CF6'],
        'deposit'    => ['label' => 'الإيداعات البنكية', 'icon' => 'building-2', 'color' => '#06B6D4'],
        'custody'    => ['label' => 'العهدة', 'icon' => 'eye', 'color' => '#F97316'],
        'scenarios'  => ['label' => 'سيناريوهات كاملة', 'icon' => 'play-circle', 'color' => '#6366F1'],
    ];

    private const MEMBERSHIP_TUTORIALS = [
        'new-member-registration' => ['title' => 'تسجيل عضو جديد', 'subtitle' => 'إنشاء استمارة عضوية من الصفر', 'icon' => 'user-plus', 'color' => '#8B5CF6', 'category' => 'registration', 'order' => 1],
        'pay-form-fee' => ['title' => 'دفع رسوم الاستمارة', 'subtitle' => 'إرسال طلب دفع 505 ج.م للخزينة', 'icon' => 'receipt', 'color' => '#059669', 'category' => 'registration', 'order' => 2],
        'fill-form' => ['title' => 'ملء استمارة العضوية', 'subtitle' => 'إكمال البيانات الشخصية والمهنية', 'icon' => 'file-text', 'color' => '#3B82F6', 'category' => 'registration', 'order' => 3],
        'membership-pricing' => ['title' => 'تسعير العضوية', 'subtitle' => 'حساب قيمة العضوية حسب المؤهل', 'icon' => 'calculator', 'color' => '#F59E0B', 'category' => 'registration', 'order' => 4],
        'pay-membership-cash' => ['title' => 'دفع العضوية كاش', 'subtitle' => 'سداد قيمة العضوية دفعة واحدة', 'icon' => 'banknote', 'color' => '#10B981', 'category' => 'financial', 'order' => 5],
        'pay-membership-installments' => ['title' => 'دفع العضوية بالتقسيط', 'subtitle' => 'مقدم 25% وتقسيط حتى 30 شهر', 'icon' => 'calendar-range', 'color' => '#06B6D4', 'category' => 'financial', 'order' => 6],
        'collective-payment' => ['title' => 'الفاتورة المجمعة وتفعيل التابعين', 'subtitle' => 'دفع العضوية يفعّل العضو وجميع تابعيه', 'icon' => 'receipt', 'color' => '#059669', 'category' => 'financial', 'order' => 7],
        'payment-queue-management' => ['title' => 'إدارة طابور الدفع', 'subtitle' => 'إلغاء طلبات وإعادتها للطابور', 'icon' => 'list-ordered', 'color' => '#D97706', 'category' => 'financial', 'order' => 8],
        'special-discounts' => ['title' => 'الخصومات الخاصة', 'subtitle' => 'تطبيق خصم خاص أو عرض مجلس الإدارة', 'icon' => 'badge-percent', 'color' => '#EC4899', 'category' => 'financial', 'order' => 9],
        'add-spouse' => ['title' => 'إضافة زوج/زوجة', 'subtitle' => 'إضافة زوجة للعضوية مع حساب الرسوم', 'icon' => 'heart', 'color' => '#F97316', 'category' => 'family', 'order' => 10],
        'add-child' => ['title' => 'إضافة أبناء', 'subtitle' => 'إضافة أبناء مع التصنيف التلقائي', 'icon' => 'baby', 'color' => '#F59E0B', 'category' => 'family', 'order' => 11],
        'add-temporary-member' => ['title' => 'إضافة عضو مؤقت', 'subtitle' => 'والدين أو أشقاء أو مربية', 'icon' => 'user-cog', 'color' => '#6366F1', 'category' => 'family', 'order' => 12],
        'children-aging' => ['title' => 'تقادم أعمار الأبناء', 'subtitle' => 'التجميد التلقائي والفصل عند بلوغ 25', 'icon' => 'clock', 'color' => '#DC2626', 'category' => 'family', 'order' => 13],
        'interview-process' => ['title' => 'المقابلات', 'subtitle' => 'جدولة وإجراء مقابلة العضوية', 'icon' => 'message-square', 'color' => '#0EA5E9', 'category' => 'procedures', 'order' => 14],
        'change-status' => ['title' => 'تغيير حالة العضوية', 'subtitle' => 'دورة الحالات من محتمل حتى فعال', 'icon' => 'refresh-cw', 'color' => '#8B5CF6', 'category' => 'procedures', 'order' => 15],
        'annual-subscription' => ['title' => 'الاشتراك السنوي', 'subtitle' => 'توليد وتحصيل الاشتراكات السنوية', 'icon' => 'calendar-check', 'color' => '#059669', 'category' => 'financial', 'order' => 16],
        'fines-violations' => ['title' => 'المخالفات والغرامات', 'subtitle' => 'فرض غرامة وتصعيد العقوبات', 'icon' => 'alert-triangle', 'color' => '#DC2626', 'category' => 'procedures', 'order' => 17],
        'carnet-issuance' => ['title' => 'إصدار الكارنيه', 'subtitle' => 'شروط وإجراءات طباعة الكارنيه', 'icon' => 'id-card', 'color' => '#3B82F6', 'category' => 'procedures', 'order' => 18],
        'transfer-separation' => ['title' => 'فصل الأبناء', 'subtitle' => 'فصل ابن/ابنة لعضوية مستقلة', 'icon' => 'git-branch', 'color' => '#F97316', 'category' => 'transfers', 'order' => 19],
        'divorce-transfer' => ['title' => 'تحويل عند الطلاق', 'subtitle' => 'نقل العضوية بعد الطلاق', 'icon' => 'split', 'color' => '#DC2626', 'category' => 'transfers', 'order' => 20],
        'death-transfer' => ['title' => 'تحويل عند الوفاة', 'subtitle' => 'نقل العضوية للزوج/الزوجة', 'icon' => 'heart-off', 'color' => '#6B7280', 'category' => 'transfers', 'order' => 21],
        'waiver-process' => ['title' => 'التنازل عن العضوية', 'subtitle' => 'تنازل لشخص آخر مع رسوم 30%', 'icon' => 'arrow-right-left', 'color' => '#8B5CF6', 'category' => 'transfers', 'order' => 22],
        'membership-freeze-drop' => ['title' => 'التجميد والإسقاط', 'subtitle' => 'تجميد العضوية أو إسقاطها', 'icon' => 'snowflake', 'color' => '#06B6D4', 'category' => 'transfers', 'order' => 23],
        'honorary-membership' => ['title' => 'العضوية الشرفية', 'subtitle' => 'عضوية بدون رسوم بقرار مجلس', 'icon' => 'award', 'color' => '#F59E0B', 'category' => 'types', 'order' => 24],
        'foreign-membership' => ['title' => 'العضوية الأجنبية', 'subtitle' => 'عضوية لغير المصريين بـ 10,000$', 'icon' => 'globe', 'color' => '#10B981', 'category' => 'types', 'order' => 25],
        'athletic-conversion' => ['title' => 'تحويل لاعب لعضو', 'subtitle' => 'تحويل عضوية رياضية لعاملة', 'icon' => 'trophy', 'color' => '#EC4899', 'category' => 'types', 'order' => 26],
        'full-new-member-scenario' => ['title' => 'سيناريو كامل: عضو جديد', 'subtitle' => 'من التسجيل حتى استلام الكارنيه', 'icon' => 'play-circle', 'color' => '#6366F1', 'category' => 'scenarios', 'order' => 27],
    ];

    private const MEMBERSHIP_CATEGORIES = [
        'registration' => ['label' => 'التسجيل والاستمارة', 'icon' => 'user-plus', 'color' => '#8B5CF6'],
        'financial'    => ['label' => 'المالي والرسوم',     'icon' => 'banknote',  'color' => '#059669'],
        'family'       => ['label' => 'التابعين والعائلة',  'icon' => 'users',     'color' => '#F59E0B'],
        'procedures'   => ['label' => 'الإجراءات',          'icon' => 'clipboard', 'color' => '#3B82F6'],
        'transfers'    => ['label' => 'التحويل والفصل',     'icon' => 'git-branch','color' => '#F97316'],
        'types'        => ['label' => 'أنواع العضوية',      'icon' => 'crown',     'color' => '#EC4899'],
        'scenarios'    => ['label' => 'سيناريوهات كاملة',   'icon' => 'play-circle','color' => '#6366F1'],
    ];

    private const SIDEBAR_GROUPS = [
        'العمليات' => [
            'membership'     => ['title' => 'شئون العضوية',        'subtitle' => 'التسجيل والرسوم والتحويلات والكارنيهات',      'icon' => 'users',         'color' => '#3B82F6'],
            'sports-activity'=> ['title' => 'الأنشطة الرياضية',    'subtitle' => 'المرافق والأكاديميات والمدربين واللاعبين',     'icon' => 'activity',      'color' => '#8B5CF6'],
            'reservations'   => ['title' => 'الحجوزات',            'subtitle' => 'إنشاء الحجز والتقويم والإلغاء',               'icon' => 'calendar',      'color' => '#3B82F6'],
            'tournaments'    => ['title' => 'البطولات',            'subtitle' => 'إنشاء بطولات وتسجيل وقرعة ونتائج',           'icon' => 'trophy',        'color' => '#CA8A04'],
            'carnets'        => ['title' => 'الكارنيهات والدعوات', 'subtitle' => 'الإصدار والطباعة ودخول الضيوف',               'icon' => 'id-card',       'color' => '#0284C7'],
            'parents'        => ['title' => 'أولياء الأمور',       'subtitle' => 'إدارة حسابات أولياء الأمور والربط باللاعبين', 'icon' => 'users',         'color' => '#7C3AED'],
        ],
        'المالية' => [
            'cashier'        => ['title' => 'خزنة العضويات',       'subtitle' => 'طابور الدفع والورديات والتسويات',             'icon' => 'credit-card',   'color' => '#059669'],
            'treasury'       => ['title' => 'الخزنة الفرعية',      'subtitle' => 'التحصيل والورديات والتسوية مع الرئيسية',     'icon' => 'safe',          'color' => '#10B981'],
            'payments'       => ['title' => 'الخزينة والمدفوعات',  'subtitle' => 'أنواع الدفع والإيصالات وسير الإلغاء',         'icon' => 'wallet',        'color' => '#2563EB'],
            'accounting'     => ['title' => 'المحاسبة والدفتر العام','subtitle' => 'شجرة الحسابات والقيود والتقارير المالية',    'icon' => 'calculator',    'color' => '#059669'],
        ],
        'سلسلة التوريد' => [
            'inventory'      => ['title' => 'إدارة المخازن',       'subtitle' => 'الأصناف والمخازن وحركات المخزون',             'icon' => 'warehouse',     'color' => '#0891B2'],
            'procurement'    => ['title' => 'المشتريات',           'subtitle' => 'طلبات الشراء والموردين والمدفوعات',           'icon' => 'shopping-cart',  'color' => '#D97706'],
            'sales'          => ['title' => 'المبيعات',            'subtitle' => 'نقاط البيع والباقات والعمولات',               'icon' => 'shopping-bag',  'color' => '#DC2626'],
        ],
        'الشئون الإدارية' => [
            'hr'             => ['title' => 'الموارد البشرية',     'subtitle' => 'الموظفين والحضور والرواتب',                   'icon' => 'briefcase',     'color' => '#7C3AED'],
            'medical-board'  => ['title' => 'اللجنة الطبية',       'subtitle' => 'الموافقات الطبية والفحوصات',                  'icon' => 'heart-pulse',   'color' => '#DC2626'],
        ],
        'التقارير والنظام' => [
            'reports'        => ['title' => 'التقارير',            'subtitle' => 'أنواع التقارير والفلاتر والتصدير',            'icon' => 'bar-chart-3',   'color' => '#8B5CF6'],
            'roles'          => ['title' => 'المستخدمون والصلاحيات','subtitle' => 'الأدوار والصلاحيات وحسابات الموظفين',         'icon' => 'shield',        'color' => '#7C3AED'],
            'access-matrix'  => ['title' => 'مصفوفة الصلاحيات',    'subtitle' => 'عرض ومقارنة صلاحيات الأدوار',                 'icon' => 'grid-3x3',      'color' => '#6366F1'],
            'rules'          => ['title' => 'القواعد والتسعير',    'subtitle' => 'محرك القواعد وسياسات التسعير',                'icon' => 'sliders',       'color' => '#64748B'],
        ],
    ];

    public function index(Request $request): Response
    {
        $groups = [];
        foreach (self::SIDEBAR_GROUPS as $groupLabel => $items) {
            $groupModules = [];
            foreach ($items as $key => $meta) {
                $count = match ($key) {
                    'membership' => count(self::MEMBERSHIP_TUTORIALS),
                    'sports-activity' => count(self::SA_TUTORIALS),
                    'treasury' => count(self::TREASURY_TUTORIALS),
                    default => count(TutorialRegistry::getTutorials($key)),
                };
                $groupModules[$key] = array_merge($meta, ['count' => $count]);
            }
            $groups[$groupLabel] = $groupModules;
        }

        return $this->view('Tutorials.Views.index', ['groups' => $groups]);
    }

    public function treasury(Request $request): Response
    {
        $grouped = [];
        foreach (self::TREASURY_TUTORIALS as $slug => $tutorial) {
            $cat = $tutorial['category'];
            if (!isset($grouped[$cat])) {
                $grouped[$cat] = self::TREASURY_CATEGORIES[$cat];
                $grouped[$cat]['tutorials'] = [];
            }
            $grouped[$cat]['tutorials'][$slug] = $tutorial;
        }

        return $this->view('Tutorials.Views.treasury.index', [
            'categories' => $grouped,
            'totalCount' => count(self::TREASURY_TUTORIALS),
        ]);
    }

    public function showTreasury(Request $request, string $slug): Response
    {
        if (!isset(self::TREASURY_TUTORIALS[$slug])) {
            return $this->redirect('/tutorials/treasury')->withError('الشرح غير موجود');
        }

        $tutorial = self::TREASURY_TUTORIALS[$slug];
        $viewFile = 'Tutorials.Views.treasury.' . str_replace('-', '_', $slug);

        $keys = array_keys(self::TREASURY_TUTORIALS);
        $currentIdx = array_search($slug, $keys);
        $prev = $currentIdx > 0 ? $keys[$currentIdx - 1] : null;
        $next = $currentIdx < count($keys) - 1 ? $keys[$currentIdx + 1] : null;

        return $this->view($viewFile, [
            'tutorial'     => $tutorial,
            'slug'         => $slug,
            'prevSlug'     => $prev,
            'nextSlug'     => $next,
            'prevTitle'    => $prev ? self::TREASURY_TUTORIALS[$prev]['title'] : null,
            'nextTitle'    => $next ? self::TREASURY_TUTORIALS[$next]['title'] : null,
            'categories'   => self::TREASURY_CATEGORIES,
        ]);
    }

    public function membership(Request $request): Response
    {
        $grouped = [];
        foreach (self::MEMBERSHIP_TUTORIALS as $slug => $tutorial) {
            $cat = $tutorial['category'];
            if (!isset($grouped[$cat])) {
                $grouped[$cat] = self::MEMBERSHIP_CATEGORIES[$cat];
                $grouped[$cat]['tutorials'] = [];
            }
            $grouped[$cat]['tutorials'][$slug] = $tutorial;
        }

        return $this->view('Tutorials.Views.membership.index', [
            'categories' => $grouped,
            'totalCount' => count(self::MEMBERSHIP_TUTORIALS),
        ]);
    }

    public function showMembership(Request $request, string $slug): Response
    {
        if (!isset(self::MEMBERSHIP_TUTORIALS[$slug])) {
            return $this->redirect('/tutorials/membership')->withError('الشرح غير موجود');
        }

        $tutorial = self::MEMBERSHIP_TUTORIALS[$slug];
        $viewFile = 'Tutorials.Views.membership.' . str_replace('-', '_', $slug);

        $keys = array_keys(self::MEMBERSHIP_TUTORIALS);
        $currentIdx = array_search($slug, $keys);
        $prev = $currentIdx > 0 ? $keys[$currentIdx - 1] : null;
        $next = $currentIdx < count($keys) - 1 ? $keys[$currentIdx + 1] : null;

        return $this->view($viewFile, [
            'tutorial'     => $tutorial,
            'slug'         => $slug,
            'prevSlug'     => $prev,
            'nextSlug'     => $next,
            'prevTitle'    => $prev ? self::MEMBERSHIP_TUTORIALS[$prev]['title'] : null,
            'nextTitle'    => $next ? self::MEMBERSHIP_TUTORIALS[$next]['title'] : null,
        ]);
    }

    public function sportsActivity(Request $request): Response
    {
        $grouped = [];
        foreach (self::SA_TUTORIALS as $slug => $tutorial) {
            $cat = $tutorial['category'];
            if (!isset($grouped[$cat])) {
                $grouped[$cat] = self::CATEGORIES[$cat];
                $grouped[$cat]['tutorials'] = [];
            }
            $grouped[$cat]['tutorials'][$slug] = $tutorial;
        }

        return $this->view('Tutorials.Views.sports_activity.index', [
            'categories' => $grouped,
            'totalCount' => count(self::SA_TUTORIALS),
        ]);
    }

    public function show(Request $request, string $slug): Response
    {
        if (!isset(self::SA_TUTORIALS[$slug])) {
            return $this->redirect('/tutorials/sports-activity')->withError('الشرح غير موجود');
        }

        $tutorial = self::SA_TUTORIALS[$slug];
        $viewFile = 'Tutorials.Views.sports_activity.' . str_replace('-', '_', $slug);

        $keys = array_keys(self::SA_TUTORIALS);
        $currentIdx = array_search($slug, $keys);
        $prev = $currentIdx > 0 ? $keys[$currentIdx - 1] : null;
        $next = $currentIdx < count($keys) - 1 ? $keys[$currentIdx + 1] : null;

        return $this->view($viewFile, [
            'tutorial'     => $tutorial,
            'slug'         => $slug,
            'prevSlug'     => $prev,
            'nextSlug'     => $next,
            'prevTitle'    => $prev ? self::SA_TUTORIALS[$prev]['title'] : null,
            'nextTitle'    => $next ? self::SA_TUTORIALS[$next]['title'] : null,
            'categories'   => self::CATEGORIES,
        ]);
    }

    public function section(Request $request, string $section): Response
    {
        $sections = TutorialRegistry::getSections();
        if (!isset($sections[$section])) {
            return $this->redirect('/tutorials')->withError('القسم غير موجود');
        }

        $tutorials = TutorialRegistry::getTutorials($section);
        $categories = TutorialRegistry::getCategories($section);

        $grouped = [];
        foreach ($tutorials as $slug => $tutorial) {
            $cat = $tutorial['category'];
            if (!isset($grouped[$cat])) {
                $grouped[$cat] = $categories[$cat] ?? ['label' => $cat, 'icon' => 'folder', 'color' => '#6B7280'];
                $grouped[$cat]['tutorials'] = [];
            }
            $grouped[$cat]['tutorials'][$slug] = $tutorial;
        }

        return $this->view('Tutorials.Views.section_index', [
            'section'    => $sections[$section],
            'sectionKey' => $section,
            'categories' => $grouped,
            'totalCount' => count($tutorials),
        ]);
    }

    public function showSection(Request $request, string $section, string $slug): Response
    {
        $sections = TutorialRegistry::getSections();
        if (!isset($sections[$section])) {
            return $this->redirect('/tutorials')->withError('القسم غير موجود');
        }

        $tutorials = TutorialRegistry::getTutorials($section);
        if (!isset($tutorials[$slug])) {
            return $this->redirect("/tutorials/{$section}")->withError('الشرح غير موجود');
        }

        $tutorial = $tutorials[$slug];

        $keys = array_keys($tutorials);
        $currentIdx = array_search($slug, $keys);
        $prev = $currentIdx > 0 ? $keys[$currentIdx - 1] : null;
        $next = $currentIdx < count($keys) - 1 ? $keys[$currentIdx + 1] : null;

        $steps = TutorialRegistry::getSteps($section, $slug);

        return $this->view('Tutorials.Views.section_show', [
            'tutorial'     => $tutorial,
            'section'      => $sections[$section],
            'sectionKey'   => $section,
            'slug'         => $slug,
            'steps'        => $steps,
            'prevSlug'     => $prev,
            'nextSlug'     => $next,
            'prevTitle'    => $prev ? $tutorials[$prev]['title'] : null,
            'nextTitle'    => $next ? $tutorials[$next]['title'] : null,
        ]);
    }

    public function bookPage(Request $request): Response
    {
        $sections = TutorialRegistry::getSections();
        $totalTutorials = 0;
        foreach (array_keys($sections) as $key) {
            $totalTutorials += count(TutorialRegistry::getTutorials($key));
        }
        $totalTutorials += count(self::MEMBERSHIP_TUTORIALS) + count(self::SA_TUTORIALS) + count(self::TREASURY_TUTORIALS);

        return $this->view('Tutorials.Views.book', [
            'totalSections' => count($sections) + 3,
            'totalTutorials' => $totalTutorials,
        ]);
    }

    public function exportPdf(Request $request): Response
    {
        $screenshotsPath = realpath(__DIR__ . '/../../../../public/assets/tutorials/screenshots');
        $viewsPath = realpath(__DIR__ . '/../Views');

        $bookData = $this->collectBookData($screenshotsPath, $viewsPath);

        ob_start();
        $data = $bookData;
        include __DIR__ . '/../Views/export_pdf.php';
        $html = ob_get_clean();

        $printBar = '<div id="printBar" style="position:fixed;top:0;left:0;right:0;z-index:99999;background:#1E40AF;color:#fff;padding:12px 24px;display:flex;align-items:center;justify-content:space-between;font-family:sans-serif;box-shadow:0 2px 8px rgba(0,0,0,.2);">'
            . '<span style="font-size:14px;">لحفظ الكتاب كـ PDF: اضغط <b>Ctrl+P</b> (أو <b>⌘+P</b>) ثم اختر "حفظ كـ PDF"</span>'
            . '<button onclick="document.getElementById(\'printBar\').remove();window.print();" style="background:#fff;color:#1E40AF;border:none;padding:8px 20px;border-radius:6px;font-size:14px;font-weight:700;cursor:pointer;">طباعة / حفظ PDF</button>'
            . '</div><div style="height:52px;"></div>';
        $html = str_replace('<body>', '<body>' . $printBar, $html);

        $printCss = '<style>@media print { #printBar, #printBar + div { display:none !important; } }</style>';
        $html = str_replace('</head>', $printCss . '</head>', $html);

        $response = new Response();
        return $response->html($html);
    }

    public function collectBookData(string $screenshotsPath, string $viewsPath): array
    {
        $book = [
            'generatedAt' => date('Y-m-d H:i'),
            'sections' => [],
        ];

        $detailedSections = [
            'membership' => [
                'title' => 'شئون العضوية',
                'tutorials' => self::MEMBERSHIP_TUTORIALS,
                'categories' => self::MEMBERSHIP_CATEGORIES,
                'viewDir' => $viewsPath . '/membership',
            ],
            'sports-activity' => [
                'title' => 'الأنشطة الرياضية',
                'tutorials' => self::SA_TUTORIALS,
                'categories' => self::CATEGORIES,
                'viewDir' => $viewsPath . '/sports_activity',
            ],
            'treasury' => [
                'title' => 'الخزنة الفرعية',
                'tutorials' => self::TREASURY_TUTORIALS,
                'categories' => self::TREASURY_CATEGORIES,
                'viewDir' => $viewsPath . '/treasury',
            ],
        ];

        foreach ($detailedSections as $key => $section) {
            $tutorials = [];
            foreach ($section['tutorials'] as $slug => $tutorial) {
                $viewFile = $section['viewDir'] . '/' . str_replace('-', '_', $slug) . '.php';
                $extracted = ['steps' => [], 'images' => []];
                if (file_exists($viewFile)) {
                    $raw = file_get_contents($viewFile);
                    $extracted = $this->extractTutorialSteps($raw);
                }
                if (empty($extracted['steps'])) {
                    $extracted['steps'] = TutorialRegistry::getSteps($key, $slug);
                }
                $tutorials[$slug] = array_merge($tutorial, [
                    'steps' => $extracted['steps'],
                    'images' => $extracted['images'],
                ]);
            }
            $book['sections'][$key] = [
                'title' => $section['title'],
                'tutorials' => $tutorials,
                'categories' => $section['categories'],
            ];
        }

        $registrySections = TutorialRegistry::getSections();
        foreach ($registrySections as $sectionKey => $sectionMeta) {
            if (isset($book['sections'][$sectionKey])) {
                continue;
            }
            $tutorials = TutorialRegistry::getTutorials($sectionKey);
            $categories = TutorialRegistry::getCategories($sectionKey);
            $screenshot = null;
            if ($screenshotsPath) {
                $possibleFiles = [
                    $screenshotsPath . '/' . $sectionKey . '.png',
                    $screenshotsPath . '/' . str_replace('-', '_', $sectionKey) . '.png',
                ];
                foreach ($possibleFiles as $f) {
                    if (file_exists($f)) {
                        $screenshot = $f;
                        break;
                    }
                }
            }
            foreach ($tutorials as $slug => &$tutorial) {
                $tutorial['steps'] = TutorialRegistry::getSteps($sectionKey, $slug);
            }
            unset($tutorial);
            $book['sections'][$sectionKey] = [
                'title' => $sectionMeta['title'],
                'subtitle' => $sectionMeta['subtitle'] ?? '',
                'tutorials' => $tutorials,
                'categories' => $categories,
                'screenshot' => $screenshot,
            ];
        }

        return $book;
    }

    private function extractTutorialSteps(string $raw): array
    {
        $steps = [];

        $start = strpos($raw, '<div class="tut-page">');
        if ($start === false) {
            $start = strpos($raw, '<div class="tut-header">');
        }
        if ($start === false) {
            return $steps;
        }

        $content = substr($raw, $start);

        $navPos = strpos($content, '<div class="tut-nav">');
        if ($navPos !== false) {
            $content = substr($content, 0, $navPos);
        }

        preg_match_all(
            '/<div class="tut-step">(.*?)<\/div>\s*<\/div>/s',
            $content,
            $stepMatches
        );

        if (empty($stepMatches[1])) {
            preg_match_all(
                '/<div class="tut-step">(.+?)(?=<div class="tut-step">|<div class="tut-nav">|$)/s',
                $content,
                $stepMatches
            );
        }

        foreach ($stepMatches[0] as $stepHtml) {
            $title = '';
            if (preg_match('/<h3 class="tut-step-title">(.*?)<\/h3>/s', $stepHtml, $m)) {
                $title = strip_tags($m[1]);
            }

            $body = '';
            if (preg_match('/<div class="tut-step-body">(.*)/s', $stepHtml, $m)) {
                $body = $m[1];
                $body = preg_replace('/<\/div>\s*$/', '', $body);
                $body = preg_replace('/<i\s+data-lucide="[^"]*"[^>]*><\/i>/', '', $body);
                $body = str_replace('loading="lazy"', '', $body);
            }

            if ($title || $body) {
                $steps[] = ['title' => $title, 'body' => $body];
            }
        }

        $images = [];
        if (preg_match_all('/<img[^>]+src="([^"]+)"[^>]*>/i', $content, $imgMatches)) {
            $images = $imgMatches[1];
        }

        return ['steps' => $steps, 'images' => $images];
    }
}
