<?php

namespace App\Livewire\Admin;

use App\Domain\Shared\Models\SystemSetting;
use App\Domain\Shared\Services\SettingsService;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('إعدادات النظام')]
class SystemSettings extends Component
{
    public string $activeTab = 'general';
    public array $settings = [];

    protected array $settingsSchema = [
        'general' => [
            'academy_name_ar' => ['type' => 'string', 'label' => 'اسم الأكاديمية (عربي)'],
            'academy_name_en' => ['type' => 'string', 'label' => 'اسم الأكاديمية (إنجليزي)'],
            'default_language' => ['type' => 'select', 'label' => 'اللغة الافتراضية', 'options' => ['ar' => 'العربية', 'en' => 'English']],
            'date_format' => ['type' => 'select', 'label' => 'صيغة التاريخ', 'options' => ['Y-m-d' => 'Y-m-d', 'd/m/Y' => 'd/m/Y']],
            'time_format' => ['type' => 'select', 'label' => 'صيغة الوقت', 'options' => ['H:i' => '24 ساعة', 'h:i A' => '12 ساعة']],
            'week_starts_on' => ['type' => 'select', 'label' => 'أول يوم في الأسبوع', 'options' => ['6' => 'السبت', '0' => 'الأحد', '1' => 'الإثنين']],
            'pagination_size' => ['type' => 'number', 'label' => 'عدد العناصر في كل صفحة', 'step' => '1', 'min' => 10, 'max' => 100],
            'session_timeout_minutes' => ['type' => 'number', 'label' => 'مهلة انتهاء الجلسة (دقيقة)', 'step' => '1', 'min' => 15],
        ],
        'financial' => [
            'currency_code' => ['type' => 'select', 'label' => 'رمز العملة', 'options' => ['EGP' => 'جنيه مصري (EGP)', 'SAR' => 'ريال سعودي (SAR)', 'AED' => 'درهم إماراتي (AED)', 'USD' => 'دولار أمريكي (USD)']],
            'currency_symbol' => ['type' => 'string', 'label' => 'رمز العملة للعرض'],
            'tax_enabled' => ['type' => 'boolean', 'label' => 'تفعيل الضريبة'],
            'tax_percentage' => ['type' => 'number', 'label' => 'نسبة الضريبة (%)', 'step' => '0.01', 'min' => 0, 'max' => 100],
            'tax_registration_number' => ['type' => 'string', 'label' => 'رقم التسجيل الضريبي'],
            'invoice_prefix' => ['type' => 'string', 'label' => 'بادئة رقم الفاتورة'],
            'receipt_prefix' => ['type' => 'string', 'label' => 'بادئة رقم الإيصال'],
            'payment_due_days' => ['type' => 'number', 'label' => 'أيام استحقاق الدفع', 'step' => '1', 'min' => 1],
            'max_discount_percent' => ['type' => 'number', 'label' => 'الحد الأقصى للخصم (%)', 'step' => '1', 'min' => 0, 'max' => 100],
            'wallet_enabled' => ['type' => 'boolean', 'label' => 'تفعيل المحفظة'],
            'platform_fee_customer_pays' => ['type' => 'boolean', 'label' => 'رسوم المنصة يدفعها العميل', 'hint' => 'مفعّل: العميل يدفع الرسوم (تُضاف للإجمالي) — معطّل: الأكاديمية تتحمل الرسوم (تُخصم من الإيراد)'],
            'refund_requires_approval' => ['type' => 'boolean', 'label' => 'الاسترداد يتطلب موافقة'],
            'refund_approval_threshold' => ['type' => 'number', 'label' => 'حد مبلغ الاسترداد للموافقة (قروش)', 'step' => '1', 'min' => 0],
            'installment_late_fee' => ['type' => 'number', 'label' => 'غرامة تأخير القسط (قروش)', 'step' => '1', 'min' => 0],
            'auto_overdue_after_days' => ['type' => 'number', 'label' => 'أيام لتحويل الفاتورة لمتأخرة', 'step' => '1', 'min' => 1],
            'installment_enabled' => ['type' => 'boolean', 'label' => 'تفعيل نظام التقسيط'],
            'installment_min_down_payment_percent' => ['type' => 'number', 'label' => 'الحد الأدنى للمقدم (%)', 'step' => '1', 'min' => 0, 'max' => 100],
            'installment_max_down_payment_percent' => ['type' => 'number', 'label' => 'الحد الأقصى للمقدم (%)', 'step' => '1', 'min' => 0, 'max' => 100],
            'installment_max_months' => ['type' => 'number', 'label' => 'الحد الأقصى لعدد أشهر التقسيط', 'step' => '1', 'min' => 1, 'max' => 36],
            'installment_min_amount' => ['type' => 'number', 'label' => 'الحد الأدنى لمبلغ الفاتورة للتقسيط (قروش)', 'step' => '1', 'min' => 0],
            'installment_allowed_frequencies' => ['type' => 'select', 'label' => 'دورية الأقساط الافتراضية', 'options' => ['weekly' => 'أسبوعي', 'biweekly' => 'نصف شهري', 'monthly' => 'شهري', 'quarterly' => 'ربع سنوي']],
            'installment_grace_days' => ['type' => 'number', 'label' => 'أيام السماح قبل احتساب التأخير', 'step' => '1', 'min' => 0],
        ],
        'attendance' => [
            'participant_grace_period_minutes' => ['type' => 'number', 'label' => 'فترة السماح للمشتركين (دقيقة)', 'step' => '1', 'min' => 0],
            'trainer_grace_period_minutes' => ['type' => 'number', 'label' => 'فترة السماح للمدربين (دقيقة)', 'step' => '1', 'min' => 0],
            'auto_absent_after_hours' => ['type' => 'number', 'label' => 'تأخير الغياب التلقائي (ساعة)', 'step' => '1', 'min' => 1],
            'consecutive_absences_for_suspend' => ['type' => 'number', 'label' => 'حد الغياب المتتالي للإيقاف', 'step' => '1', 'min' => 1],
            'min_attendance_percent' => ['type' => 'number', 'label' => 'الحد الأدنى لنسبة الحضور (%)', 'step' => '1', 'min' => 0, 'max' => 100],
            'notify_guardian_on_absence' => ['type' => 'boolean', 'label' => 'إشعار ولي الأمر عند الغياب'],
            'allow_excuse_after_hours' => ['type' => 'number', 'label' => 'صلاحية تقديم عذر (ساعة)', 'step' => '1', 'min' => 1],
            'qr_check_in_enabled' => ['type' => 'boolean', 'label' => 'تسجيل حضور بـ QR Code'],
        ],
        'notifications' => [
            'email_enabled' => ['type' => 'boolean', 'label' => 'تفعيل البريد الإلكتروني'],
            'sms_enabled' => ['type' => 'boolean', 'label' => 'تفعيل الرسائل القصيرة'],
            'sms_provider' => ['type' => 'select', 'label' => 'مزود SMS', 'options' => ['log' => 'سجل فقط', 'twilio' => 'Twilio', 'vonage' => 'Vonage']],
            'sms_rate_limit_per_hour' => ['type' => 'number', 'label' => 'حد الرسائل القصيرة (بالساعة)', 'step' => '1', 'min' => 1],
            'digest_mode_enabled' => ['type' => 'boolean', 'label' => 'تفعيل وضع الملخص اليومي'],
            'digest_send_time' => ['type' => 'time', 'label' => 'وقت الملخص اليومي'],
            'notify_admin_on_payment' => ['type' => 'boolean', 'label' => 'إشعار المدير عند الدفع'],
            'notify_guardian_on_enrollment' => ['type' => 'boolean', 'label' => 'إشعار ولي الأمر عند التسجيل'],
            'payment_reminder_days_before' => ['type' => 'number', 'label' => 'أيام تذكير قبل الاستحقاق', 'step' => '1', 'min' => 1],
        ],
        'pricing' => [
            'global_max_discount' => ['type' => 'number', 'label' => 'الحد الأقصى للخصم الكلي (%)', 'step' => '1', 'min' => 0, 'max' => 100],
            'allow_price_override' => ['type' => 'boolean', 'label' => 'السماح بتجاوز السعر يدوياً'],
            'auto_apply_family_discount' => ['type' => 'boolean', 'label' => 'تطبيق خصم العائلة تلقائياً'],
            'family_discount_start_child' => ['type' => 'number', 'label' => 'رقم الطفل لبدء خصم العائلة', 'step' => '1', 'min' => 2],
            'trial_period_days' => ['type' => 'number', 'label' => 'مدة الفترة التجريبية (أيام)', 'step' => '1', 'min' => 0],
            'early_enrollment_days' => ['type' => 'number', 'label' => 'أيام التسجيل المبكر (للخصم)', 'step' => '1', 'min' => 0],
            'coupon_max_uses_default' => ['type' => 'number', 'label' => 'الحد الافتراضي لاستخدام الكوبون', 'step' => '1', 'min' => 1],
        ],
        'enrollment' => [
            'allow_proration' => ['type' => 'boolean', 'label' => 'تفعيل الدفع النسبي (باقي الشهر فقط)', 'hint' => 'عند التفعيل: اللاعب يدفع فقط الأيام المتبقية من الشهر حتى يوم التجديد'],
            'renewal_day' => ['type' => 'number', 'label' => 'يوم التجديد الشهري', 'step' => '1', 'min' => 1, 'max' => 28, 'hint' => 'اليوم الذي يتجدد فيه الاشتراك كل شهر (مثال: 1 = أول الشهر)'],
            'allow_waitlist' => ['type' => 'boolean', 'label' => 'تفعيل قائمة الانتظار'],
            'auto_promote_waitlist' => ['type' => 'boolean', 'label' => 'ترقية تلقائية من قائمة الانتظار'],
            'require_medical_report' => ['type' => 'boolean', 'label' => 'إلزام تقرير طبي'],
            'require_guardian_for_minors' => ['type' => 'boolean', 'label' => 'إلزام ولي أمر للقاصرين'],
            'minor_age_threshold' => ['type' => 'number', 'label' => 'سن التسجيل بدون ولي أمر', 'step' => '1', 'min' => 1],
            'max_groups_per_participant' => ['type' => 'number', 'label' => 'الحد الأقصى للمجموعات لكل مشترك', 'step' => '1', 'min' => 1],
            'allow_transfer_between_groups' => ['type' => 'boolean', 'label' => 'السماح بنقل بين المجموعات'],
            'freeze_max_days' => ['type' => 'number', 'label' => 'أقصى مدة تجميد (أيام)', 'step' => '1', 'min' => 1],
            'freeze_max_times' => ['type' => 'number', 'label' => 'أقصى عدد مرات التجميد', 'step' => '1', 'min' => 1],
            'enrollment_expiry_days' => ['type' => 'number', 'label' => 'مدة صلاحية الاشتراك (أيام)', 'step' => '1', 'min' => 1],
            'require_documents_upload' => ['type' => 'boolean', 'label' => 'تفعيل نظام رفع المستندات'],
            'require_medical_certificate' => ['type' => 'boolean', 'label' => 'إلزام رفع شهادة طبية سارية'],
            'medical_certificate_expiry_required' => ['type' => 'boolean', 'label' => 'إلزام تاريخ انتهاء الشهادة عند الموافقة'],
            'medical_certificate_max_age_months' => ['type' => 'number', 'label' => 'أقصى مدة صلاحية الشهادة الطبية (شهور)', 'step' => '1', 'min' => 1, 'max' => 60],
            'block_attendance_without_medical' => ['type' => 'boolean', 'label' => 'منع الحضور بدون شهادة طبية سارية'],
            // 150 = the platform ceiling in config/uploads.php (max_kb / 1024).
            // A literal because a property initialiser cannot call config().
            'max_document_size_mb' => ['type' => 'number', 'label' => 'الحد الأقصى لحجم الملف (ميجابايت)', 'step' => '1', 'min' => 1, 'max' => 150],
        ],
    ];

    protected array $defaults = [
        // general
        'academy_name_ar' => '',
        'academy_name_en' => '',
        'default_language' => 'ar',
        'date_format' => 'Y-m-d',
        'time_format' => 'H:i',
        'week_starts_on' => '6',
        'pagination_size' => '25',
        'session_timeout_minutes' => '120',
        // financial
        'currency_code' => 'EGP',
        'currency_symbol' => 'ج.م',
        'tax_enabled' => '0',
        'tax_percentage' => '14',
        'tax_registration_number' => '',
        'invoice_prefix' => 'INV',
        'receipt_prefix' => 'RCP',
        'payment_due_days' => '7',
        'max_discount_percent' => '50',
        'wallet_enabled' => '1',
        'platform_fee_customer_pays' => '0',
        'refund_requires_approval' => '1',
        'refund_approval_threshold' => '50000',
        'installment_late_fee' => '500',
        'auto_overdue_after_days' => '3',
        'installment_enabled' => '1',
        'installment_min_down_payment_percent' => '20',
        'installment_max_down_payment_percent' => '70',
        'installment_max_months' => '12',
        'installment_min_amount' => '10000',
        'installment_allowed_frequencies' => 'monthly',
        'installment_grace_days' => '7',
        // attendance
        'participant_grace_period_minutes' => '15',
        'trainer_grace_period_minutes' => '10',
        'auto_absent_after_hours' => '2',
        'consecutive_absences_for_suspend' => '5',
        'min_attendance_percent' => '75',
        'notify_guardian_on_absence' => '1',
        'allow_excuse_after_hours' => '48',
        'qr_check_in_enabled' => '0',
        // notifications
        'email_enabled' => '1',
        'sms_enabled' => '0',
        'sms_provider' => 'log',
        'sms_rate_limit_per_hour' => '100',
        'digest_mode_enabled' => '0',
        'digest_send_time' => '08:00',
        'notify_admin_on_payment' => '1',
        'notify_guardian_on_enrollment' => '1',
        'payment_reminder_days_before' => '3',
        // pricing
        'global_max_discount' => '50',
        'allow_price_override' => '0',
        'auto_apply_family_discount' => '1',
        'family_discount_start_child' => '2',
        'trial_period_days' => '7',
        'early_enrollment_days' => '14',
        'coupon_max_uses_default' => '100',
        // enrollment
        'allow_proration' => '0',
        'renewal_day' => '1',
        'allow_waitlist' => '1',
        'auto_promote_waitlist' => '1',
        'require_medical_report' => '0',
        'require_guardian_for_minors' => '1',
        'minor_age_threshold' => '18',
        'max_groups_per_participant' => '5',
        'allow_transfer_between_groups' => '1',
        'freeze_max_days' => '30',
        'freeze_max_times' => '2',
        'enrollment_expiry_days' => '30',
        // documents
        'require_documents_upload' => '0',
        'require_medical_certificate' => '0',
        'medical_certificate_expiry_required' => '1',
        'medical_certificate_max_age_months' => '12',
        'block_attendance_without_medical' => '0',
        'max_document_size_mb' => '10',
    ];

    public function mount(): void
    {
        $this->authorize('settings.manage');
        $this->loadAllSettings();
    }

    public function loadAllSettings(): void
    {
        $academyId = app('current_academy')?->id;
        if (!$academyId) {
            return;
        }

        $records = SystemSetting::withoutGlobalScope('academy')
            ->where('academy_id', $academyId)
            ->get()
            ->mapWithKeys(function ($s) {
                // Strip group prefix so UI can use bare keys (e.g. "enrollment.allow_proration" → "allow_proration")
                $bareKey = str_contains($s->key, '.') ? substr($s->key, strpos($s->key, '.') + 1) : $s->key;
                return [$bareKey => $s->value];
            })
            ->toArray();

        // Merge defaults with stored values
        $this->settings = array_merge($this->defaults, $records);
    }

    public function save(SettingsService $service): void
    {
        $group = $this->activeTab;
        $schema = $this->settingsSchema[$group] ?? [];

        foreach ($schema as $key => $config) {
            $value = $this->settings[$key] ?? $this->defaults[$key] ?? '';

            // Normalize boolean values
            if ($config['type'] === 'boolean') {
                $value = $value ? '1' : '0';
            }

            $type = match ($config['type']) {
                'boolean' => 'boolean',
                'number' => str_contains($config['step'] ?? '1', '.') ? 'float' : 'integer',
                default => 'string',
            };

            // Always store as dotted key so services can read "group.key"
            $service->set("{$group}.{$key}", $value, $group, $type);
        }

        session()->flash('success', __('تم حفظ الإعدادات بنجاح'));
    }

    #[Computed]
    public function activeSchema(): array
    {
        return $this->settingsSchema[$this->activeTab] ?? [];
    }

    public function render()
    {
        $tabs = [
            'general' => __('عام'),
            'financial' => __('مالي'),
            'attendance' => __('الحضور'),
            'notifications' => __('الإشعارات'),
            'pricing' => __('التسعير'),
            'enrollment' => __('التسجيل'),
        ];

        return view('livewire.admin.system-settings', [
            'tabs' => $tabs,
            'schema' => $this->settingsSchema[$this->activeTab] ?? [],
        ]);
    }
}
