<?php

namespace App\Livewire\Wizards;

use App\Domain\Facility\Enums\FacilityType;
use App\Domain\Facility\Models\Facility;
use App\Domain\Facility\Models\SpaceLayout;
use App\Domain\Facility\Models\SpaceSegment;
use App\Domain\Identity\Models\Branch;
use App\Domain\Identity\Models\Person;
use App\Domain\Identity\Models\Role;
use App\Domain\Participant\Models\Participant;
use App\Domain\Pricing\Models\BasePrice;
use App\Domain\Shared\Models\Academy;
use App\Domain\Shared\Services\SettingsService;
use App\Domain\Training\Enums\ActivityCategory;
use App\Domain\Training\Models\Activity;
use App\Domain\Training\Models\TrainingGroup;
use App\Domain\Training\Models\TrainingProgram;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Livewire\Attributes\Layout;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\RedirectResponse;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.wizard')]
#[Title('معالج الإعداد الأولي')]
class SetupWizard extends Component
{
    public int $currentStep = 1;
    public int $totalSteps = 11;

    // Step 1: Branches
    public array $branches = [];

    // Step 2: Activities
    public array $activities = [];

    // Step 3: Programs
    public array $programs = [];

    // Step 4: Facilities + Grid
    public array $facilities = [];

    // Step 5: Groups + Schedule
    public array $groups = [];

    // Step 6: Participants
    public array $participants = [];

    // Step 7: Staff & Users
    public array $users = [];

    // Step 8: Financial & Pricing
    public bool $taxEnabled = false;
    public float $taxPercentage = 14;
    public string $invoicePrefix = 'INV';
    public string $receiptPrefix = 'RCP';
    public int $paymentDueDays = 7;
    public bool $walletEnabled = true;
    public array $acceptedPaymentMethods = ['cash', 'card', 'wallet'];
    public int $maxDiscountPercent = 50;
    public bool $autoApplyFamilyDiscount = true;
    public int $familyDiscountStartChild = 2;
    public int $trialPeriodDays = 7;

    // Step 9: Rules & Policies
    public int $gracePeriodParticipant = 15;
    public int $gracePeriodTrainer = 10;
    public int $autoAbsentAfterHours = 2;
    public int $consecutiveAbsencesForSuspend = 5;
    public int $minAttendancePercent = 75;
    public bool $requireMedicalReport = false;
    public bool $requireGuardianForMinors = true;
    public int $minorAgeThreshold = 18;
    public bool $allowWaitlist = true;
    public int $freezeMaxDays = 30;
    public bool $emailEnabled = true;
    public bool $smsEnabled = false;

    // Step 10: General Settings
    public string $defaultCurrency = 'EGP';
    public string $timezone = 'Africa/Cairo';
    public string $weekStartsOn = '6';
    public string $dateFormat = 'Y-m-d';
    public string $timeFormat = 'H:i';
    public int $paginationSize = 25;

    // Internal
    public ?Academy $academy = null;

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

        $this->academy = app('current_academy');

        if (!$this->academy) {
            abort(403, __('لا توجد أكاديمية مرتبطة'));
        }

        // Check if setup already completed
        $settingsService = app(SettingsService::class);
        if ($settingsService->get('setup_completed', false)) {
            // Not $this->redirect(). Livewire swaps the container's `redirect`
            // binding for its own Redirector while a component is booted, and
            // on a full-page (non-Livewire) request SupportRedirects::dehydrate
            // then calls abort(redirect($to)) — handing abort() a Redirector
            // where it wants a status code. Every already-set-up academy got a
            // 500 on /setup instead of a bounce to the dashboard. Throwing the
            // response is the one form that works on both request kinds, and
            // building it directly sidesteps the swapped binding.
            throw new HttpResponseException(new RedirectResponse(route('dashboard')));
        }

        // Initialize with one empty branch
        $this->addBranch();
    }

    // ─── Navigation ──────────────────────────────────────────────

    public function nextStep(): void
    {
        $this->validateCurrentStep();
        if ($this->currentStep < $this->totalSteps) {
            $this->currentStep++;
        }
    }

    public function previousStep(): void
    {
        if ($this->currentStep > 1) {
            $this->currentStep--;
        }
    }

    public function goToStep(int $step): void
    {
        if ($step <= $this->currentStep) {
            $this->currentStep = $step;
        }
    }

    // ─── Branch Management ───────────────────────────────────────

    public function addBranch(): void
    {
        $this->branches[] = [
            'name_ar' => '',
            'name' => '',
            'address' => '',
            'phone' => '',
            'is_main' => count($this->branches) === 0,
            'working_days' => [0, 1, 2, 3, 4],
            'email' => '',
            'city' => '',
            'manager_name' => '',
        ];
    }

    public function removeBranch(int $index): void
    {
        if (count($this->branches) <= 1) {
            return;
        }

        $wasMain = $this->branches[$index]['is_main'] ?? false;
        unset($this->branches[$index]);
        $this->branches = array_values($this->branches);

        // Reassign main if removed
        if ($wasMain && count($this->branches) > 0) {
            $this->branches[0]['is_main'] = true;
        }
    }

    // ─── Activity Management ─────────────────────────────────────

    public function addActivity(): void
    {
        $this->activities[] = [
            'name_ar' => '',
            'name' => '',
            'category' => 'sport',
            'description' => '',
        ];
    }

    public function removeActivity(int $index): void
    {
        unset($this->activities[$index]);
        $this->activities = array_values($this->activities);
    }

    // ─── Program Management ──────────────────────────────────────

    public function addProgram(): void
    {
        $this->programs[] = [
            'name_ar' => '',
            'activity_index' => 0,
            'duration_months' => 1,
            'max_participants' => 20,
            'monthly_fee' => '',
            'min_age' => null,
            'max_age' => null,
            'sessions_per_week' => 3,
            'registration_fee' => null,
            'payment_frequency' => 'monthly',
        ];
    }

    public function removeProgram(int $index): void
    {
        unset($this->programs[$index]);
        $this->programs = array_values($this->programs);
    }

    // ─── Facility Management ─────────────────────────────────────

    public function addFacility(): void
    {
        $this->facilities[] = [
            'name_ar' => '',
            'type' => 'field',
            'capacity' => '',
            'monthly_cost' => '',
            'operating_start' => '08:00',
            'operating_end' => '22:00',
            'address' => '',
            'grid_rows' => 3,
            'grid_cols' => 3,
            'branch_index' => 0,
        ];
    }

    public function removeFacility(int $index): void
    {
        unset($this->facilities[$index]);
        $this->facilities = array_values($this->facilities);
    }

    // ─── Group Management ────────────────────────────────────────

    public function addGroup(): void
    {
        $this->groups[] = [
            'name_ar' => '',
            'program_index' => 0,
            'facility_index' => 0,
            'assigned_segments' => [],
            'head_trainer_name' => '',
            'max_capacity' => 20,
            'schedule_days' => [],
        ];
    }

    public function removeGroup(int $index): void
    {
        unset($this->groups[$index]);
        $this->groups = array_values($this->groups);
    }

    public function addGroupScheduleSlot(int $groupIndex): void
    {
        if (!isset($this->groups[$groupIndex])) {
            return;
        }

        $this->groups[$groupIndex]['schedule_days'][] = [
            'day' => 0,
            'start_time' => '16:00',
            'end_time' => '17:30',
        ];
    }

    public function removeGroupScheduleSlot(int $groupIndex, int $slotIndex): void
    {
        if (!isset($this->groups[$groupIndex]['schedule_days'][$slotIndex])) {
            return;
        }

        unset($this->groups[$groupIndex]['schedule_days'][$slotIndex]);
        $this->groups[$groupIndex]['schedule_days'] = array_values($this->groups[$groupIndex]['schedule_days']);
    }

    // ─── Participant Management ──────────────────────────────────

    public function addParticipant(): void
    {
        $this->participants[] = [
            'name_ar' => '',
            'name' => '',
            'phone' => '',
            'date_of_birth' => '',
            'gender' => 'male',
            'guardian_name' => '',
            'guardian_phone' => '',
            'activity_index' => 0,
            'group_index' => null,
            'national_id' => '',
            'classification' => 'regular',
            'medical_notes' => '',
            'skill_level' => null,
        ];
    }

    public function removeParticipant(int $index): void
    {
        unset($this->participants[$index]);
        $this->participants = array_values($this->participants);
    }

    // ─── User Management ─────────────────────────────────────────

    public function addUser(): void
    {
        $this->users[] = [
            'name' => '',
            'email' => '',
            'role' => 'trainer',
            'branch_index' => 0,
            'phone' => '',
            'specialization' => '',
        ];
    }

    public function removeUser(int $index): void
    {
        unset($this->users[$index]);
        $this->users = array_values($this->users);
    }

    // ─── Validation ──────────────────────────────────────────────

    protected function validateCurrentStep(): void
    {
        match ($this->currentStep) {
            1 => $this->validateBranches(),
            2 => $this->validateActivities(),
            3 => $this->validatePrograms(),
            4 => $this->validateFacilities(),
            5 => $this->validateGroups(),
            6 => $this->validateParticipants(),
            7 => $this->validateUsers(),
            8 => $this->validate([
                'taxEnabled' => 'boolean',
                'taxPercentage' => 'required|numeric|min:0|max:100',
                'invoicePrefix' => 'required|string|max:10',
                'receiptPrefix' => 'required|string|max:10',
                'paymentDueDays' => 'required|integer|min:1|max:365',
                'walletEnabled' => 'boolean',
                'acceptedPaymentMethods' => 'required|array|min:1',
                'acceptedPaymentMethods.*' => 'string|in:cash,card,bank_transfer,wallet,online',
                'maxDiscountPercent' => 'required|integer|min:0|max:100',
                'autoApplyFamilyDiscount' => 'boolean',
                'familyDiscountStartChild' => 'required|integer|min:2|max:10',
                'trialPeriodDays' => 'required|integer|min:0|max:90',
            ], [
                'taxPercentage.required' => __('نسبة الضريبة مطلوبة'),
                'taxPercentage.min' => __('نسبة الضريبة لا يمكن أن تكون سالبة'),
                'taxPercentage.max' => __('نسبة الضريبة لا يمكن أن تتجاوز 100%'),
                'invoicePrefix.required' => __('بادئة الفاتورة مطلوبة'),
                'receiptPrefix.required' => __('بادئة الإيصال مطلوبة'),
                'paymentDueDays.required' => __('مهلة السداد مطلوبة'),
                'paymentDueDays.min' => __('مهلة السداد يجب أن تكون يوم واحد على الأقل'),
                'acceptedPaymentMethods.required' => __('يجب اختيار طريقة دفع واحدة على الأقل'),
                'acceptedPaymentMethods.min' => __('يجب اختيار طريقة دفع واحدة على الأقل'),
                'maxDiscountPercent.required' => __('الحد الأقصى للخصم مطلوب'),
                'maxDiscountPercent.min' => __('الحد الأقصى للخصم لا يمكن أن يكون سالباً'),
                'maxDiscountPercent.max' => __('الحد الأقصى للخصم لا يمكن أن يتجاوز 100%'),
                'familyDiscountStartChild.required' => __('ترتيب الطفل لبدء خصم العائلة مطلوب'),
                'trialPeriodDays.required' => __('فترة التجربة مطلوبة'),
            ]),
            9 => $this->validate([
                'gracePeriodParticipant' => 'required|integer|min:0|max:60',
                'gracePeriodTrainer' => 'required|integer|min:0|max:60',
                'autoAbsentAfterHours' => 'required|integer|min:1|max:24',
                'consecutiveAbsencesForSuspend' => 'required|integer|min:1|max:30',
                'minAttendancePercent' => 'required|integer|min:0|max:100',
                'requireMedicalReport' => 'boolean',
                'requireGuardianForMinors' => 'boolean',
                'minorAgeThreshold' => 'required|integer|min:12|max:21',
                'allowWaitlist' => 'boolean',
                'freezeMaxDays' => 'required|integer|min:1|max:365',
                'emailEnabled' => 'boolean',
                'smsEnabled' => 'boolean',
            ], [
                'gracePeriodParticipant.required' => __('فترة السماح للمشتركين مطلوبة'),
                'gracePeriodParticipant.max' => __('فترة السماح لا يمكن أن تتجاوز 60 دقيقة'),
                'gracePeriodTrainer.required' => __('فترة السماح للمدربين مطلوبة'),
                'gracePeriodTrainer.max' => __('فترة السماح لا يمكن أن تتجاوز 60 دقيقة'),
                'autoAbsentAfterHours.required' => __('وقت التغيب التلقائي مطلوب'),
                'consecutiveAbsencesForSuspend.required' => __('عدد مرات الغياب المتتالي للإيقاف مطلوب'),
                'minAttendancePercent.required' => __('نسبة الحضور الأدنى مطلوبة'),
                'minorAgeThreshold.required' => __('حد سن القاصر مطلوب'),
                'minorAgeThreshold.min' => __('حد سن القاصر يجب أن يكون 12 على الأقل'),
                'minorAgeThreshold.max' => __('حد سن القاصر لا يمكن أن يتجاوز 21'),
                'freezeMaxDays.required' => __('الحد الأقصى لأيام التجميد مطلوب'),
                'freezeMaxDays.min' => __('الحد الأقصى لأيام التجميد يجب أن يكون يوم واحد على الأقل'),
            ]),
            10 => $this->validate([
                'defaultCurrency' => 'required|string|in:EGP,SAR,AED,USD',
                'timezone' => 'required|string|timezone',
                'weekStartsOn' => 'required|string|in:0,1,6',
                'dateFormat' => 'required|string|in:Y-m-d,d/m/Y',
                'timeFormat' => 'required|string|in:H:i,h:i A',
                'paginationSize' => 'required|integer|min:10|max:100',
            ], [
                'defaultCurrency.required' => __('العملة الافتراضية مطلوبة'),
                'defaultCurrency.in' => __('العملة غير مدعومة'),
                'timezone.required' => __('المنطقة الزمنية مطلوبة'),
                'timezone.timezone' => __('المنطقة الزمنية غير صالحة'),
                'weekStartsOn.required' => __('بداية الأسبوع مطلوبة'),
                'weekStartsOn.in' => __('قيمة بداية الأسبوع غير صالحة'),
                'dateFormat.required' => __('صيغة التاريخ مطلوبة'),
                'timeFormat.required' => __('صيغة الوقت مطلوبة'),
                'paginationSize.required' => __('عدد العناصر في الصفحة مطلوب'),
                'paginationSize.min' => __('عدد العناصر في الصفحة يجب أن يكون 10 على الأقل'),
                'paginationSize.max' => __('عدد العناصر في الصفحة لا يمكن أن يتجاوز 100'),
            ]),
            default => null,
        };
    }

    protected function validateBranches(): void
    {
        if (empty($this->branches)) {
            $this->addError('branches', __('يجب إضافة فرع واحد على الأقل'));
            throw \Illuminate\Validation\ValidationException::withMessages([
                'branches' => __('يجب إضافة فرع واحد على الأقل'),
            ]);
        }

        $this->validate([
            'branches.*.name_ar' => 'required|string|min:2|max:255',
            'branches.*.name' => 'nullable|string|max:255',
            'branches.*.address' => 'nullable|string|max:500',
            'branches.*.phone' => 'nullable|string|max:20',
            'branches.*.working_days' => 'required|array|min:1',
            'branches.*.working_days.*' => 'integer|min:0|max:6',
            'branches.*.email' => 'nullable|email|max:255',
            'branches.*.city' => 'nullable|string|max:100',
            'branches.*.manager_name' => 'nullable|string|max:255',
        ], [
            'branches.*.name_ar.required' => __('اسم الفرع بالعربية مطلوب'),
            'branches.*.name_ar.min' => __('اسم الفرع يجب أن يكون حرفين على الأقل'),
            'branches.*.working_days.required' => __('يجب تحديد أيام العمل'),
            'branches.*.working_days.min' => __('يجب اختيار يوم عمل واحد على الأقل'),
            'branches.*.email.email' => __('البريد الإلكتروني للفرع غير صالح'),
        ]);
    }

    protected function validateActivities(): void
    {
        if (empty($this->activities)) {
            throw \Illuminate\Validation\ValidationException::withMessages([
                'activities' => __('يجب إضافة نشاط واحد على الأقل حتى يعمل النظام'),
            ]);
        }

        $validCategories = implode(',', array_column(ActivityCategory::cases(), 'value'));

        $this->validate([
            'activities.*.name_ar' => 'required|string|min:2|max:255',
            'activities.*.name' => 'nullable|string|max:255',
            'activities.*.category' => "required|string|in:{$validCategories}",
            'activities.*.description' => 'nullable|string|max:1000',
        ], [
            'activities.*.name_ar.required' => __('اسم النشاط بالعربية مطلوب'),
            'activities.*.category.required' => __('نوع النشاط مطلوب'),
        ]);
    }

    protected function validatePrograms(): void
    {
        if (empty($this->programs)) {
            throw \Illuminate\Validation\ValidationException::withMessages([
                'programs' => __('يجب إضافة برنامج واحد على الأقل مع تحديد السعر'),
            ]);
        }

        $this->validate([
            'programs.*.name_ar' => 'required|string|min:2|max:255',
            'programs.*.activity_index' => 'required|integer|min:0',
            'programs.*.duration_months' => 'required|integer|min:1|max:24',
            'programs.*.max_participants' => 'required|integer|min:1|max:500',
            'programs.*.monthly_fee' => 'required|numeric|min:1',
            'programs.*.min_age' => 'nullable|integer|min:3|max:80',
            'programs.*.max_age' => 'nullable|integer|min:3|max:80',
            'programs.*.sessions_per_week' => 'required|integer|min:1|max:7',
            'programs.*.registration_fee' => 'nullable|numeric|min:0',
            'programs.*.payment_frequency' => 'required|string|in:monthly,quarterly,semester,annual',
        ], [
            'programs.*.name_ar.required' => __('اسم البرنامج بالعربية مطلوب'),
            'programs.*.duration_months.required' => __('مدة البرنامج مطلوبة'),
            'programs.*.max_participants.required' => __('الحد الأقصى للمشتركين مطلوب'),
            'programs.*.monthly_fee.required' => __('الرسوم الشهرية مطلوبة'),
            'programs.*.monthly_fee.min' => __('يجب تحديد سعر البرنامج (لا يمكن أن يكون صفر)'),
            'programs.*.min_age.min' => __('الحد الأدنى للعمر يجب أن يكون 3 سنوات على الأقل'),
            'programs.*.max_age.max' => __('الحد الأقصى للعمر لا يمكن أن يتجاوز 80 سنة'),
            'programs.*.sessions_per_week.required' => __('عدد الحصص في الأسبوع مطلوب'),
            'programs.*.sessions_per_week.min' => __('عدد الحصص يجب أن يكون حصة واحدة على الأقل'),
            'programs.*.sessions_per_week.max' => __('عدد الحصص لا يمكن أن يتجاوز 7 حصص'),
            'programs.*.payment_frequency.required' => __('دورة الدفع مطلوبة'),
            'programs.*.payment_frequency.in' => __('دورة الدفع غير صالحة'),
        ]);
    }

    protected function validateFacilities(): void
    {
        if (empty($this->facilities)) {
            throw \Illuminate\Validation\ValidationException::withMessages([
                'facilities' => __('يجب إضافة منشأة واحدة على الأقل (ملعب، قاعة، حمام سباحة...)'),
            ]);
        }

        $validTypes = implode(',', array_column(FacilityType::cases(), 'value'));

        $this->validate([
            'facilities.*.name_ar' => 'required|string|min:2|max:255',
            'facilities.*.type' => "required|string|in:{$validTypes}",
            'facilities.*.capacity' => 'nullable|integer|min:1|max:10000',
            'facilities.*.monthly_cost' => 'required|numeric|min:0',
            'facilities.*.operating_start' => 'nullable|date_format:H:i',
            'facilities.*.operating_end' => 'nullable|date_format:H:i',
            'facilities.*.address' => 'nullable|string|max:500',
            'facilities.*.grid_rows' => 'required|integer|min:1|max:10',
            'facilities.*.grid_cols' => 'required|integer|min:1|max:10',
            'facilities.*.branch_index' => 'required|integer|min:0',
        ], [
            'facilities.*.name_ar.required' => __('اسم المنشأة بالعربية مطلوب'),
            'facilities.*.type.required' => __('نوع المنشأة مطلوب'),
            'facilities.*.monthly_cost.required' => __('الإيجار الشهري مطلوب (أدخل 0 إذا كانت ملك)'),
            'facilities.*.grid_rows.required' => __('عدد الصفوف مطلوب'),
            'facilities.*.grid_cols.required' => __('عدد الأعمدة مطلوب'),
            'facilities.*.branch_index.required' => __('يجب اختيار الفرع'),
        ]);
    }

    protected function validateGroups(): void
    {
        // Groups are optional — skip if empty
        if (empty($this->groups)) {
            return;
        }

        $this->validate([
            'groups.*.name_ar' => 'required|string|min:2|max:255',
            'groups.*.program_index' => 'required|integer|min:0',
            'groups.*.facility_index' => 'required|integer|min:0',
            'groups.*.max_capacity' => 'required|integer|min:1|max:500',
            'groups.*.head_trainer_name' => 'nullable|string|max:255',
            'groups.*.schedule_days' => 'nullable|array',
            'groups.*.schedule_days.*.day' => 'required|integer|min:0|max:6',
            'groups.*.schedule_days.*.start_time' => 'required|date_format:H:i',
            'groups.*.schedule_days.*.end_time' => 'required|date_format:H:i',
        ], [
            'groups.*.name_ar.required' => __('اسم المجموعة بالعربية مطلوب'),
            'groups.*.name_ar.min' => __('اسم المجموعة يجب أن يكون حرفين على الأقل'),
            'groups.*.program_index.required' => __('يجب اختيار البرنامج'),
            'groups.*.facility_index.required' => __('يجب اختيار المنشأة'),
            'groups.*.max_capacity.required' => __('الحد الأقصى للسعة مطلوب'),
            'groups.*.schedule_days.*.day.required' => __('يجب تحديد اليوم'),
            'groups.*.schedule_days.*.start_time.required' => __('وقت البدء مطلوب'),
            'groups.*.schedule_days.*.start_time.date_format' => __('صيغة وقت البدء غير صالحة'),
            'groups.*.schedule_days.*.end_time.required' => __('وقت الانتهاء مطلوب'),
            'groups.*.schedule_days.*.end_time.date_format' => __('صيغة وقت الانتهاء غير صالحة'),
        ]);
    }

    protected function validateParticipants(): void
    {
        // Participants are optional — skip if empty
        if (empty($this->participants)) {
            return;
        }

        $this->validate([
            'participants.*.name_ar' => 'required|string|min:2|max:255',
            'participants.*.name' => 'nullable|string|max:255',
            'participants.*.phone' => 'nullable|string|max:20',
            'participants.*.date_of_birth' => 'nullable|date',
            'participants.*.gender' => 'required|in:male,female',
            'participants.*.guardian_name' => 'nullable|string|max:255',
            'participants.*.guardian_phone' => 'nullable|string|max:20',
            'participants.*.activity_index' => 'nullable|integer|min:0',
            'participants.*.national_id' => 'nullable|string|max:20',
            'participants.*.classification' => 'required|string|in:regular,vip,scholarship,staff_child,trial',
            'participants.*.medical_notes' => 'nullable|string|max:1000',
            'participants.*.skill_level' => 'nullable|string|in:beginner,intermediate,advanced,professional',
        ], [
            'participants.*.name_ar.required' => __('اسم المشترك بالعربية مطلوب'),
            'participants.*.name_ar.min' => __('اسم المشترك يجب أن يكون حرفين على الأقل'),
            'participants.*.gender.required' => __('الجنس مطلوب'),
            'participants.*.gender.in' => __('الجنس يجب أن يكون ذكر أو أنثى'),
            'participants.*.classification.required' => __('تصنيف المشترك مطلوب'),
            'participants.*.classification.in' => __('تصنيف المشترك غير صالح'),
            'participants.*.medical_notes.max' => __('الملاحظات الطبية لا يمكن أن تتجاوز 1000 حرف'),
            'participants.*.skill_level.in' => __('مستوى المهارة غير صالح'),
        ]);
    }

    protected function validateUsers(): void
    {
        if (empty($this->users)) {
            return;
        }

        $this->validate([
            'users.*.name' => 'required|string|min:2|max:255',
            'users.*.email' => 'required|email|max:255',
            'users.*.role' => 'required|string|in:branch_manager,head_trainer,trainer,receptionist,accountant,data_entry',
            'users.*.branch_index' => 'required|integer|min:0',
            'users.*.phone' => 'nullable|string|max:20',
            'users.*.specialization' => 'nullable|string|max:255',
        ], [
            'users.*.name.required' => __('اسم المستخدم مطلوب'),
            'users.*.name.min' => __('اسم المستخدم يجب أن يكون حرفين على الأقل'),
            'users.*.email.required' => __('البريد الإلكتروني مطلوب'),
            'users.*.email.email' => __('البريد الإلكتروني غير صالح'),
            'users.*.role.required' => __('الدور مطلوب'),
            'users.*.role.in' => __('الدور غير صالح'),
            'users.*.phone.max' => __('رقم الهاتف لا يمكن أن يتجاوز 20 حرفاً'),
        ]);
    }

    // ─── Complete Setup ──────────────────────────────────────────

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

        DB::transaction(function () {
            $academyId = $this->academy->id;
            $actor = auth()->user();

            // Update academy currency/timezone from wizard settings
            $this->academy->update([
                'currency' => $this->defaultCurrency,
                'timezone' => $this->timezone,
            ]);

            $settingsService = app(SettingsService::class);

            // Create branches
            $createdBranches = [];
            foreach ($this->branches as $branchData) {
                $createdBranches[] = Branch::create([
                    'academy_id' => $academyId,
                    'name_ar' => $branchData['name_ar'],
                    'name' => $branchData['name'] ?: $branchData['name_ar'],
                    'address' => $branchData['address'] ?? null,
                    'phone' => $branchData['phone'] ?? null,
                    'email' => $branchData['email'] ?? null,
                    'city' => $branchData['city'] ?? null,
                    'is_main' => $branchData['is_main'] ?? false,
                    'is_active' => true,
                    'code' => Str::upper(Str::limit(Str::slug($branchData['name_ar'], ''), 10, '')),
                    'operating_hours' => [
                        'working_days' => $branchData['working_days'] ?? [0, 1, 2, 3, 4],
                        'manager_name' => $branchData['manager_name'] ?? null,
                    ],
                ]);
            }

            // Create activities
            $createdActivities = [];
            foreach ($this->activities as $activityData) {
                $createdActivities[] = Activity::create([
                    'academy_id' => $academyId,
                    'name_ar' => $activityData['name_ar'],
                    'name' => $activityData['name'] ?: $activityData['name_ar'],
                    'slug' => Str::limit(Str::slug($activityData['name_ar']), 90, ''),
                    'category' => $activityData['category'],
                    'description' => $activityData['description'] ?? null,
                    'is_active' => true,
                    'sort_order' => 0,
                ]);
            }

            // Create programs + base prices
            $createdPrograms = [];
            foreach ($this->programs as $programData) {
                $activityIndex = (int) $programData['activity_index'];
                $activity = $createdActivities[$activityIndex] ?? null;

                if ($activity) {
                    $durationMonths = (int) $programData['duration_months'];
                    $monthlyFeePiasters = (int) round((float) $programData['monthly_fee'] * 100);
                    $registrationFeePiasters = !empty($programData['registration_fee'])
                        ? (int) round((float) $programData['registration_fee'] * 100)
                        : null;

                    $program = TrainingProgram::create([
                        'academy_id' => $academyId,
                        'activity_id' => $activity->id,
                        'name_ar' => $programData['name_ar'],
                        'name' => $programData['name_ar'],
                        'slug' => Str::limit(Str::slug($programData['name_ar']), 90, ''),
                        'program_duration_weeks' => $durationMonths * 4,
                        'max_participants' => (int) $programData['max_participants'],
                        'age_min' => !empty($programData['min_age']) ? (int) $programData['min_age'] : null,
                        'age_max' => !empty($programData['max_age']) ? (int) $programData['max_age'] : null,
                        'sessions_per_week' => (int) ($programData['sessions_per_week'] ?? 3),
                        'status' => 'active',
                        'registration_open' => true,
                        'created_by' => $actor->id,
                        'metadata' => [
                            'monthly_fee_piasters' => $monthlyFeePiasters,
                            'payment_frequency' => $programData['payment_frequency'] ?? 'monthly',
                        ],
                    ]);

                    $createdPrograms[] = $program;

                    // Monthly subscription base price
                    BasePrice::create([
                        'academy_id' => $academyId,
                        'priceable_type' => TrainingProgram::class,
                        'priceable_id' => $program->id,
                        // The price is filed where the programme is. A null here
                        // used to mean "every branch"; base_prices is strictly
                        // scoped now, so it would mean "no branch at all" and the
                        // academy would finish its own setup wizard unable to sell.
                        'branch_id' => $program->branch_id,
                        'name_ar' => 'الاشتراك الشهري — ' . $programData['name_ar'],
                        'name' => 'Monthly — ' . $programData['name_ar'],
                        'amount' => $monthlyFeePiasters,
                        'currency' => 'EGP',
                        'effective_from' => now()->toDateString(),
                        'effective_to' => null,
                        'is_active' => true,
                        'priority' => 1,
                        'created_by' => $actor->id,
                    ]);

                    // Registration fee base price (if provided)
                    if ($registrationFeePiasters && $registrationFeePiasters > 0) {
                        BasePrice::create([
                            'academy_id' => $academyId,
                            'priceable_type' => TrainingProgram::class,
                            'priceable_id' => $program->id,
                            'branch_id' => $program->branch_id,
                            'name_ar' => 'رسوم التسجيل — ' . $programData['name_ar'],
                            'name' => 'Registration Fee — ' . $programData['name_ar'],
                            'amount' => $registrationFeePiasters,
                            'currency' => 'EGP',
                            'effective_from' => now()->toDateString(),
                            'effective_to' => null,
                            'is_active' => true,
                            'priority' => 0,
                            'created_by' => $actor->id,
                        ]);
                    }
                }
            }

            // Create facilities + space layouts + segments
            $createdFacilities = [];
            $facilityLayouts = [];
            foreach ($this->facilities as $facilityData) {
                $branchIndex = (int) ($facilityData['branch_index'] ?? 0);
                $linkedBranch = $createdBranches[$branchIndex] ?? $createdBranches[0] ?? null;

                $facility = Facility::create([
                    'academy_id' => $academyId,
                    'branch_id' => $linkedBranch?->id,
                    'name_ar' => $facilityData['name_ar'],
                    'name' => $facilityData['name_ar'],
                    'type' => $facilityData['type'],
                    'capacity' => !empty($facilityData['capacity']) ? (int) $facilityData['capacity'] : null,
                    'monthly_rental_cost' => !empty($facilityData['monthly_cost']) ? (int) round((float) $facilityData['monthly_cost'] * 100) : 0,
                    'operating_start' => $facilityData['operating_start'] ?? null,
                    'operating_end' => $facilityData['operating_end'] ?? null,
                    'address' => $facilityData['address'] ?? null,
                    'status' => 'active',
                    'created_by' => $actor->id,
                ]);

                $createdFacilities[] = $facility;

                // Create space layout for this facility
                $rows = (int) ($facilityData['grid_rows'] ?? 3);
                $cols = (int) ($facilityData['grid_cols'] ?? 3);

                $layout = SpaceLayout::create([
                    'academy_id' => $academyId,
                    'facility_id' => $facility->id,
                    'name' => 'التقسيم الافتراضي',
                    'name_ar' => 'التقسيم الافتراضي',
                    'layout_type' => 'grid',
                    'layout_config' => ['rows' => $rows, 'columns' => $cols],
                    'is_recurring' => true,
                    'effective_day_of_week' => null,
                    'start_time' => $facilityData['operating_start'] ?? '08:00',
                    'end_time' => $facilityData['operating_end'] ?? '22:00',
                    'is_active' => true,
                    'sort_order' => 0,
                    'metadata' => [],
                    'created_by' => $actor->id,
                ]);

                $facilityLayouts[] = $layout;

                // Generate segments for the grid
                for ($r = 1; $r <= $rows; $r++) {
                    for ($c = 1; $c <= $cols; $c++) {
                        SpaceSegment::create([
                            'space_layout_id' => $layout->id,
                            'code' => "R{$r}C{$c}",
                            'name' => "Row {$r} Col {$c}",
                            'name_ar' => "صف {$r} عمود {$c}",
                            'row_index' => $r,
                            'col_index' => $c,
                            'is_available' => true,
                            'sort_order' => ($r - 1) * $cols + $c,
                            'metadata' => [],
                        ]);
                    }
                }
            }

            // Create training groups
            $createdGroups = [];
            foreach ($this->groups as $groupData) {
                $programIndex = (int) ($groupData['program_index'] ?? 0);
                $linkedProgram = $createdPrograms[$programIndex] ?? null;

                if ($linkedProgram) {
                    $group = TrainingGroup::create([
                        'academy_id' => $academyId,
                        'training_program_id' => $linkedProgram->id,
                        'branch_id' => $createdBranches[0]->id,
                        'name' => $groupData['name_ar'],
                        'name_ar' => $groupData['name_ar'],
                        'code' => Str::upper(Str::limit(Str::slug($groupData['name_ar'], ''), 8, '')),
                        'max_capacity' => (int) ($groupData['max_capacity'] ?? 20),
                        'current_count' => 0,
                        'waitlist_count' => 0,
                        'head_trainer_id' => null,
                        'status' => 'forming',
                        'metadata' => [
                            'head_trainer_name' => $groupData['head_trainer_name'] ?? '',
                            'schedule_days' => $groupData['schedule_days'] ?? [],
                            'assigned_segments' => $groupData['assigned_segments'] ?? [],
                            'assigned_facility_index' => (int) ($groupData['facility_index'] ?? 0),
                        ],
                        'created_by' => $actor->id,
                    ]);

                    $createdGroups[] = $group;
                }
            }

            // Create participants (Person + Participant)
            foreach ($this->participants as $idx => $pData) {
                $person = Person::create([
                    'academy_id' => $academyId,
                    'name_ar' => $pData['name_ar'],
                    'name' => !empty($pData['name']) ? $pData['name'] : $pData['name_ar'],
                    'phone' => !empty($pData['phone']) ? $pData['phone'] : null,
                    'date_of_birth' => !empty($pData['date_of_birth']) ? $pData['date_of_birth'] : null,
                    'gender' => $pData['gender'] ?? null,
                    'national_id' => !empty($pData['national_id']) ? $pData['national_id'] : null,
                    'classification' => $pData['classification'] ?? 'regular',
                    'medical_notes' => !empty($pData['medical_notes']) ? $pData['medical_notes'] : null,
                    'emergency_contact_name' => !empty($pData['guardian_name']) ? $pData['guardian_name'] : null,
                    'emergency_contact_phone' => !empty($pData['guardian_phone']) ? $pData['guardian_phone'] : null,
                    'created_by' => $actor->id,
                ]);

                $activityIndex = isset($pData['activity_index']) ? (int) $pData['activity_index'] : null;
                $linkedActivity = ($activityIndex !== null) ? ($createdActivities[$activityIndex] ?? null) : null;

                $participant = Participant::create([
                    'academy_id' => $academyId,
                    'person_id' => $person->id,
                    'participant_number' => $this->generateParticipantNumber($academyId, $idx),
                    'registration_date' => now()->toDateString(),
                    'registration_source' => 'walk_in',
                    'primary_activity_id' => $linkedActivity?->id,
                    'skill_level' => !empty($pData['skill_level']) ? $pData['skill_level'] : null,
                    'status' => 'registered',
                    'created_by' => $actor->id,
                ]);

                // Store group assignment in metadata if specified
                if (!empty($pData['group_index']) && isset($createdGroups[(int) $pData['group_index']])) {
                    $assignedGroup = $createdGroups[(int) $pData['group_index']];
                    $participant->update([
                        'metadata' => array_merge($participant->metadata ?? [], [
                            'pending_group_id' => $assignedGroup->id,
                            'pending_group_name' => $assignedGroup->name_ar,
                        ]),
                    ]);
                }
            }

            // Create users
            foreach ($this->users as $userData) {
                $branchIndex = (int) $userData['branch_index'];
                $branch = $createdBranches[$branchIndex] ?? $createdBranches[0] ?? null;

                $role = Role::where('academy_id', $academyId)
                    ->where('slug', $userData['role'])
                    ->first();

                $userAttributes = [
                    'academy_id' => $academyId,
                    'name' => $userData['name'],
                    'email' => $userData['email'],
                    'password' => Hash::make('password'),
                    'status' => 'active',
                    'role_id' => $role?->id,
                    'force_password_change' => true,
                ];

                if (!empty($userData['phone'])) {
                    $userAttributes['phone'] = $userData['phone'];
                }

                $user = User::create($userAttributes);

                if ($role && $branch) {
                    $user->roles()->attach($role->id, [
                        'branch_id' => $branch->id,
                        'assigned_by' => $actor->id,
                    ]);
                }

                // Store specialization as a note in linked person record
                if (!empty($userData['specialization']) && in_array($userData['role'], ['trainer', 'head_trainer'])) {
                    $trainerPerson = Person::create([
                        'academy_id' => $academyId,
                        'user_id' => $user->id,
                        'name' => $userData['name'],
                        'name_ar' => $userData['name'],
                        'notes' => $userData['specialization'],
                        'created_by' => $actor->id,
                    ]);
                    $user->update(['person_id' => $trainerPerson->id]);
                }
            }

            // ─── Save ALL system settings ────────────────────────────

            // Step 9: Financial & Pricing
            $settingsService->set('currency_code', $this->defaultCurrency, 'financial', 'string');
            $settingsService->set('tax_enabled', $this->taxEnabled ? '1' : '0', 'financial', 'boolean');
            $settingsService->set('tax_percentage', (string) $this->taxPercentage, 'financial', 'integer');
            $settingsService->set('invoice_prefix', $this->invoicePrefix, 'financial', 'string');
            $settingsService->set('receipt_prefix', $this->receiptPrefix, 'financial', 'string');
            $settingsService->set('payment_due_days', (string) $this->paymentDueDays, 'financial', 'integer');
            $settingsService->set('wallet_enabled', $this->walletEnabled ? '1' : '0', 'financial', 'boolean');
            $settingsService->set('accepted_payment_methods', json_encode($this->acceptedPaymentMethods), 'financial', 'json');
            $settingsService->set('max_discount_percent', (string) $this->maxDiscountPercent, 'financial', 'integer');
            $settingsService->set('global_max_discount', (string) $this->maxDiscountPercent, 'pricing', 'integer');
            $settingsService->set('auto_apply_family_discount', $this->autoApplyFamilyDiscount ? '1' : '0', 'pricing', 'boolean');
            $settingsService->set('family_discount_start_child', (string) $this->familyDiscountStartChild, 'pricing', 'integer');
            $settingsService->set('trial_period_days', (string) $this->trialPeriodDays, 'pricing', 'integer');

            // Step 10: Rules & Policies
            $settingsService->set('participant_grace_period_minutes', (string) $this->gracePeriodParticipant, 'attendance', 'integer');
            $settingsService->set('trainer_grace_period_minutes', (string) $this->gracePeriodTrainer, 'attendance', 'integer');
            $settingsService->set('auto_absent_after_hours', (string) $this->autoAbsentAfterHours, 'attendance', 'integer');
            $settingsService->set('consecutive_absences_for_suspend', (string) $this->consecutiveAbsencesForSuspend, 'attendance', 'integer');
            $settingsService->set('min_attendance_percent', (string) $this->minAttendancePercent, 'attendance', 'integer');
            $settingsService->set('require_medical_report', $this->requireMedicalReport ? '1' : '0', 'enrollment', 'boolean');
            $settingsService->set('require_guardian_for_minors', $this->requireGuardianForMinors ? '1' : '0', 'enrollment', 'boolean');
            $settingsService->set('minor_age_threshold', (string) $this->minorAgeThreshold, 'enrollment', 'integer');
            $settingsService->set('allow_waitlist', $this->allowWaitlist ? '1' : '0', 'enrollment', 'boolean');
            $settingsService->set('freeze_max_days', (string) $this->freezeMaxDays, 'enrollment', 'integer');
            $settingsService->set('auto_create_groups_enabled', '1', 'enrollment', 'boolean');
            $settingsService->set('email_enabled', $this->emailEnabled ? '1' : '0', 'notifications', 'boolean');
            $settingsService->set('sms_enabled', $this->smsEnabled ? '1' : '0', 'notifications', 'boolean');

            // Step 11: General Settings
            $settingsService->set('default_currency', $this->defaultCurrency, 'general', 'string');
            $settingsService->set('timezone', $this->timezone, 'general', 'string');
            $settingsService->set('week_starts_on', $this->weekStartsOn, 'general', 'string');
            $settingsService->set('date_format', $this->dateFormat, 'general', 'string');
            $settingsService->set('time_format', $this->timeFormat, 'general', 'string');
            $settingsService->set('pagination_size', (string) $this->paginationSize, 'general', 'integer');

            // Create default receipt template
            $receiptService = app(\App\Domain\POS\Services\ReceiptService::class);
            $receiptService->createDefaultTemplate($academyId);

            // Mark setup as complete
            $settingsService->set('setup_completed', 'true', 'general', 'boolean');
        });

        session()->flash('success', __('تم إعداد النظام بنجاح! مرحباً بك في الكابتن'));
        $this->redirect(route('dashboard'));
    }

    // ─── Helpers ─────────────────────────────────────────────────

    private function generateParticipantNumber(int $academyId, int $index): string
    {
        $prefix = 'P';
        $year = now()->format('y');
        $seq = str_pad($index + 1, 4, '0', STR_PAD_LEFT);
        return "{$prefix}{$year}{$seq}";
    }

    public function getStepLabels(): array
    {
        return [
            1 => __('الفروع'),
            2 => __('الأنشطة'),
            3 => __('البرامج'),
            4 => __('المنشآت'),
            5 => __('المجموعات'),
            6 => __('المشتركين'),
            7 => __('الطاقم'),
            8 => __('المالية'),
            9 => __('السياسات'),
            10 => __('الإعدادات'),
            11 => __('تم!'),
        ];
    }

    public function getDayNames(): array
    {
        return [
            0 => __('الأحد'),
            1 => __('الإثنين'),
            2 => __('الثلاثاء'),
            3 => __('الأربعاء'),
            4 => __('الخميس'),
            5 => __('الجمعة'),
            6 => __('السبت'),
        ];
    }

    public function getPaymentFrequencies(): array
    {
        return [
            'monthly' => __('شهري'),
            'quarterly' => __('ربع سنوي'),
            'semester' => __('نصف سنوي'),
            'annual' => __('سنوي'),
        ];
    }

    public function getClassifications(): array
    {
        return [
            'regular' => __('عادي'),
            'vip' => __('مميز'),
            'scholarship' => __('منحة'),
            'staff_child' => __('ابن موظف'),
            'trial' => __('تجريبي'),
        ];
    }

    public function getSkillLevels(): array
    {
        return [
            'beginner' => __('مبتدئ'),
            'intermediate' => __('متوسط'),
            'advanced' => __('متقدم'),
            'professional' => __('محترف'),
        ];
    }

    public function getActivityCategories(): array
    {
        return [
            'sport' => __('رياضة'),
            'art' => __('فنون'),
            'academic' => __('أكاديمي'),
            'fitness' => __('لياقة بدنية'),
            'other' => __('أخرى'),
        ];
    }

    public function getFacilityTypes(): array
    {
        return [
            'field' => __('ملعب'),
            'court' => __('كورت'),
            'pool' => __('حمام سباحة'),
            'gym' => __('صالة رياضية'),
            'track' => __('مضمار'),
            'hall' => __('قاعة'),
            'room' => __('غرفة'),
            'outdoor' => __('مساحة خارجية'),
            'other' => __('أخرى'),
        ];
    }

    public function getUserRoles(): array
    {
        return [
            'branch_manager' => __('مدير فرع'),
            'head_trainer' => __('رئيس مدربين'),
            'trainer' => __('مدرب'),
            'receptionist' => __('موظف استقبال'),
            'accountant' => __('محاسب'),
            'data_entry' => __('مدخل بيانات'),
        ];
    }

    public function render()
    {
        return view('livewire.wizards.setup-wizard');
    }
}
