<?php

namespace App\Livewire\Receptionist;

use App\Domain\Financial\Models\Invoice;
use App\Domain\Financial\Services\InvoiceService;
use App\Domain\Financial\Services\PaymentService;
use App\Domain\Identity\Models\Branch;
use App\Domain\Identity\Models\Guardian;
use App\Domain\Identity\Models\Person;
use App\Domain\Identity\Models\Role;
use App\Domain\Identity\Services\EgyptianNidDecoder;
use App\Domain\Identity\Services\PersonService;
use App\Domain\Inventory\Models\Kit;
use App\Domain\Inventory\Models\Product;
use App\Domain\Participant\Models\Participant;
use App\Domain\Participant\Services\DuplicateDetectionService;
use App\Domain\Participant\Services\ParticipantService;
use App\Domain\Pricing\Models\BasePrice;
use App\Domain\Shared\DTOs\ProrationResult;
use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Shared\Services\PlatformFeeService;
use App\Domain\Shared\Services\ProrationService;
use App\Domain\Shared\Traits\UsesBranchScope;
use App\Domain\Training\Models\Activity;
use App\Domain\Training\Models\TrainingProgram;
use App\Domain\Training\Services\EnrollmentService;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('تسجيل جديد')]
class NewRegistrationWizard extends Component
{
    use UsesBranchScope;

    public ?int $branchId = null;

    public int $currentStep = 1;
    public int $totalSteps = 7;

    // Step 1: Participant (the actual player/child) — FIRST now
    public string $participant_name_ar = '';
    public string $participant_name = '';
    public ?string $participant_date_of_birth = null;
    public string $participant_gender = 'male';
    public string $participant_phone = '';
    public string $participant_national_id = '';
    public string $participant_medical_notes = '';
    public string $membership_type = 'non_member';
    public string $membership_id = '';
    public string $participant_governorate = '';
    public bool $participant_is_foreign = false;
    public bool $participant_nid_decoded = false;

    // Step 2: Guardian info
    public string $guardian_name_ar = '';
    public string $guardian_name = '';
    public string $guardian_phone = '';
    public string $guardian_relation = 'father';

    // Step 3: Parent Account
    public bool $createParentAccount = true;
    public string $parentEmail = '';
    public string $parentPassword = '';
    public bool $sendParentCredentials = true;

    // Step 4: Program selection
    public ?int $selected_activity_id = null;
    public ?int $selected_program_id = null;

    // Step 6: Payment
    public bool $pay_now = false;
    public string $payment_method = 'cash';

    // Super-admin price override
    public bool $priceOverrideEnabled = false;
    public string $priceOverrideInput = '';
    public string $priceOverrideReason = '';

    // Guardian search (existing parent)
    public bool $searchExistingGuardian = false;
    public string $guardianSearchQuery = '';
    public array $guardianSearchResults = [];
    public bool $guardianSelected = false;

    // Duplicate detection
    public array $potentialDuplicates = [];
    public bool $duplicateCheckDone = false;
    public ?int $useExistingPersonId = null;

    // Result
    public bool $completed = false;
    public ?string $participant_number = null;
    public ?string $participant_uuid = null;
    public ?string $enrollment_summary = null;
    public ?int $invoice_amount = null;
    public ?string $invoice_number = null;
    public ?int $invoiceId = null;
    public ?string $invoice_uuid = null;
    public bool $payment_recorded = false;

    // Hot-buy items (optional products/kits sold alongside registration)
    public string $hotbuy_search = '';
    public array $hotbuyCart = [];

    // Pre-flight errors — blocks wizard from starting
    public array $systemErrors = [];

    public function mount(): void
    {
        $this->authorize('participants.create');
        $this->branchId = $this->getActiveBranchId() ?? Branch::where('is_active', true)->first()?->id;
        $this->runPreflightChecks();
    }

    private function runPreflightChecks(): void
    {
        $errors = [];

        if (!app('current_academy')) {
            $errors[] = 'لا توجد أكاديمية مفعّلة — تواصل مع المسؤول';
        }

        if (!$this->branchId) {
            $errors[] = 'لا يوجد فرع محدد — اختر فرعاً من الإعدادات';
        }

        $hasActivities = Activity::where('is_active', true)->exists();
        if (!$hasActivities) {
            $errors[] = 'لا توجد أنشطة مفعّلة — يجب إنشاء نشاط واحد على الأقل';
        }

        $hasPrograms = TrainingProgram::where('status', 'active')
            ->whereHas('groups', fn ($q) => $q->where(function ($sub) {
                $sub->where('branch_id', $this->branchId)->orWhereNull('branch_id');
            })->whereIn('status', ['active', 'forming']))
            ->exists();
        if (!$hasPrograms) {
            $errors[] = 'لا توجد برامج متاحة بها مجموعات نشطة في هذا الفرع';
        }

        $hasPrices = BasePrice::where('is_active', true)
            ->where('priceable_type', TrainingProgram::class)
            ->where('effective_from', '<=', now())
            ->where(fn ($q) => $q->whereNull('effective_to')->orWhere('effective_to', '>=', now()))
            ->exists();
        if (!$hasPrices) {
            $errors[] = 'لا توجد أسعار محددة لأي برنامج — يجب تحديد سعر أساسي أولاً';
        }

        $this->systemErrors = $errors;
    }

    // --- NID decode hooks ---

    public function updatedParticipantNationalId(): void
    {
        if ($this->participant_is_foreign) {
            return;
        }

        $nid = trim($this->participant_national_id);
        if (strlen($nid) !== 14) {
            $this->participant_nid_decoded = false;
            return;
        }

        $result = app(EgyptianNidDecoder::class)->decode($nid);

        if (!$result['valid']) {
            $this->participant_nid_decoded = false;
            return;
        }

        $this->participant_date_of_birth = $result['birth_date'];
        $this->participant_gender = $result['gender'];
        $this->participant_governorate = $result['governorate_ar'] ?? '';
        $this->participant_nid_decoded = true;
    }

    public function updatedParticipantIsForeign(): void
    {
        if ($this->participant_is_foreign) {
            // Unlock fields when switching to foreign
            $this->participant_nid_decoded = false;
        } else {
            // Re-decode if NID already filled
            $this->updatedParticipantNationalId();
        }
    }

    // --- Guardian name auto-fill from player name ---

    public function updatedParticipantNameAr(): void
    {
        $this->autoFillGuardianName();
    }

    private function autoFillGuardianName(): void
    {
        if (empty($this->participant_name_ar) || $this->guardianSelected) {
            return;
        }

        $parts = array_values(array_filter(explode(' ', trim($this->participant_name_ar))));

        // Father name = words[1] + words[2] (the two words after the player's first name)
        if (count($parts) >= 3) {
            $this->guardian_name_ar = implode(' ', array_slice($parts, 1, 2));
        } elseif (count($parts) === 2) {
            $this->guardian_name_ar = $parts[1];
        }
    }

    // --- Step navigation ---

    public function nextStep(): void
    {
        $rules = $this->rulesForStep($this->currentStep);

        if (!empty($rules)) {
            $this->validate($rules, $this->messages());
        }

        // Duplicate check on step 2 (guardian) — if duplicates found, stay on step 2
        if ($this->currentStep === 2 && !$this->duplicateCheckDone) {
            $this->checkDuplicates();
            return;
        }

        // Pre-fill parent email from guardian person data when moving to step 3
        if ($this->currentStep === 2 && $this->duplicateCheckDone && empty($this->parentEmail)) {
            if ($this->useExistingPersonId) {
                $existingPerson = Person::find($this->useExistingPersonId);
                if ($existingPerson && $existingPerson->email) {
                    $this->parentEmail = $existingPerson->email;
                }
            }
        }

        // Price guard on step 4 — block if no base price for selected program
        if ($this->currentStep === 4 && $this->selected_program_id) {
            $program = TrainingProgram::find($this->selected_program_id);
            if ($program && $this->resolveProgramFee($program) === 0) {
                $this->addError('selected_program_id', 'لا يوجد سعر محدد لهذا البرنامج — تواصل مع المسؤول');
                return;
            }
        }

        $this->currentStep = min($this->currentStep + 1, $this->totalSteps);
    }

    private function rulesForStep(int $step): array
    {
        return match ($step) {
            1 => [
                'participant_name_ar' => 'required|string|max:255',
                'participant_date_of_birth' => 'required|date|before:today',
                'participant_gender' => 'required|in:male,female',
                'participant_phone' => 'nullable|string|max:20',
                'participant_national_id' => 'nullable|string|max:' . ($this->participant_is_foreign ? '30' : '14'),
                'participant_medical_notes' => 'nullable|string|max:1000',
                'membership_type' => 'required|in:member,non_member',
                'membership_id' => 'required_if:membership_type,member|nullable|string|max:50',
            ],
            2 => [
                'guardian_name_ar' => 'required|string|max:255',
                'guardian_phone' => 'required|string|max:20',
                'guardian_relation' => 'required|in:father,mother,brother,sister,uncle,aunt,grandfather,grandmother,guardian,other',
            ],
            3 => $this->createParentAccount ? [
                'parentEmail' => 'required|email|max:255|unique:users,email',
                'parentPassword' => 'required|string|min:6|max:100',
            ] : [],
            4 => [
                'selected_activity_id' => 'required|exists:activities,id',
                'selected_program_id' => 'required|exists:training_programs,id',
            ],
            6 => [
                'payment_method' => 'required_if:pay_now,true|in:cash,card,wallet',
            ],
            default => [],
        };
    }

    public function messages(): array
    {
        return [
            'participant_name_ar.required' => 'اسم المشترك مطلوب',
            'participant_date_of_birth.required' => 'تاريخ الميلاد مطلوب',
            'participant_date_of_birth.before' => 'تاريخ الميلاد يجب أن يكون في الماضي',
            'participant_gender.required' => 'الجنس مطلوب',
            'participant_gender.in' => 'الجنس غير صالح',
            'membership_type.required' => 'نوع العضوية مطلوب',
            'membership_type.in' => 'نوع العضوية غير صالح',
            'membership_id.required_if' => 'رقم عضوية النادي مطلوب للأعضاء',
            'guardian_name_ar.required' => 'اسم ولي الأمر مطلوب',
            'guardian_phone.required' => 'رقم الهاتف مطلوب',
            'guardian_relation.required' => 'صلة القرابة مطلوبة',
            'guardian_relation.in' => 'صلة القرابة غير صالحة',
            'parentEmail.required' => 'البريد الإلكتروني مطلوب لإنشاء الحساب',
            'parentEmail.email' => 'صيغة البريد الإلكتروني غير صالحة',
            'parentEmail.unique' => 'البريد الإلكتروني مستخدم بالفعل',
            'parentPassword.required' => 'كلمة المرور مطلوبة',
            'parentPassword.min' => 'كلمة المرور يجب أن تكون 6 أحرف على الأقل',
            'selected_activity_id.required' => 'يرجى اختيار النشاط',
            'selected_activity_id.exists' => 'النشاط المختار غير موجود',
            'selected_program_id.required' => 'يرجى اختيار البرنامج',
            'selected_program_id.exists' => 'البرنامج المختار غير موجود',
            'payment_method.required_if' => 'يرجى اختيار طريقة الدفع',
            'payment_method.in' => 'طريقة الدفع غير صالحة',
        ];
    }

    public function checkDuplicates(): void
    {
        $service = app(DuplicateDetectionService::class);

        $matches = $service->findPotentialDuplicates(
            name: $this->guardian_name_ar,
            phone: $this->guardian_phone ?: null,
        );

        $highConfidence = $matches->filter(fn ($m) => $m['confidence'] >= 80);

        $this->potentialDuplicates = $highConfidence->map(fn ($m) => [
            'person_id' => $m['person']->id,
            'name' => $m['person']->name_ar ?: $m['person']->name,
            'phone' => $m['person']->phone,
            'confidence' => $m['confidence'],
            'match_reason' => $m['match_reason'],
            'has_participant' => $m['person']->participant !== null,
            'participant_number' => $m['person']->participant?->participant_number,
        ])->toArray();

        $this->duplicateCheckDone = true;

        if (empty($this->potentialDuplicates)) {
            $this->currentStep = min($this->currentStep + 1, $this->totalSteps);
        }
    }

    public function proceedDespiteDuplicates(): void
    {
        $this->potentialDuplicates = [];
        $this->currentStep = min($this->currentStep + 1, $this->totalSteps);
    }

    public function useExistingPerson(int $personId): void
    {
        $this->useExistingPersonId = $personId;
        $this->potentialDuplicates = [];
        $this->currentStep = min($this->currentStep + 1, $this->totalSteps);
    }

    public function updatedGuardianSearchQuery(): void
    {
        if (strlen($this->guardianSearchQuery) < 2) {
            $this->guardianSearchResults = [];
            return;
        }

        $search = $this->guardianSearchQuery;
        $this->guardianSearchResults = Guardian::with('person')
            ->whereHas('person', function ($q) use ($search) {
                $q->where('name_ar', 'ilike', "%{$search}%")
                  ->orWhere('phone', 'like', "%{$search}%");
            })
            ->limit(10)
            ->get()
            ->map(fn ($g) => [
                'id' => $g->id,
                'person_id' => $g->person_id,
                'name' => $g->person?->name_ar ?? $g->person?->name,
                'phone' => $g->person?->phone,
                'relation' => $g->relation_type,
                'children_count' => $g->participants()->count(),
            ])
            ->toArray();
    }

    public function selectExistingGuardian(int $guardianId): void
    {
        $guardian = Guardian::with('person')->find($guardianId);
        if (!$guardian) {
            return;
        }

        $this->useExistingPersonId = $guardian->person_id;
        $this->guardian_name_ar = $guardian->person->name_ar ?? '';
        $this->guardian_name = $guardian->person->name ?? '';
        $this->guardian_phone = $guardian->person->phone ?? '';
        $this->guardian_relation = $guardian->relation_type ?? 'father';
        $this->guardianSelected = true;
        $this->guardianSearchResults = [];
    }

    public function clearSelectedGuardian(): void
    {
        $this->useExistingPersonId = null;
        $this->guardian_name_ar = '';
        $this->guardian_name = '';
        $this->guardian_phone = '';
        $this->guardian_relation = 'father';
        $this->guardianSelected = false;
        $this->searchExistingGuardian = false;
        $this->guardianSearchQuery = '';
    }

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

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

    public function updatedGuardianNameAr(): void
    {
        $this->resetDuplicateCheck();
    }

    public function updatedGuardianPhone(): void
    {
        $this->resetDuplicateCheck();
    }

    private function resetDuplicateCheck(): void
    {
        $this->duplicateCheckDone = false;
        $this->potentialDuplicates = [];
        $this->useExistingPersonId = null;
    }

    public function generateParentPassword(): void
    {
        $this->parentPassword = Str::random(8);
    }

    public function updatedSelectedActivityId(): void
    {
        $this->selected_program_id = null;
    }

    // --- Price override (super admin only) ---

    public function updatedPriceOverrideEnabled(): void
    {
        if (!$this->priceOverrideEnabled) {
            $this->priceOverrideInput = '';
            $this->priceOverrideReason = '';
        }
    }

    // Returns the effective total in piasters, respecting override
    #[Computed]
    public function effectiveTotal(): int
    {
        if ($this->priceOverrideEnabled && $this->priceOverrideInput !== '') {
            $overridePiasters = (int) round((float) $this->priceOverrideInput * 100);
            return max(0, $overridePiasters);
        }
        return $this->totalWithFee;
    }

    // --- Hot-buy methods ---

    #[Computed]
    public function hotbuyResults(): array
    {
        if (strlen($this->hotbuy_search) < 2) {
            return [];
        }

        $search = $this->hotbuy_search;

        $products = Product::where('is_active', true)
            ->where(fn ($q) => $q->where('name_ar', 'ilike', "%{$search}%")
                ->orWhere('name', 'ilike', "%{$search}%")
                ->orWhere('sku', 'ilike', "%{$search}%")
                ->orWhere('barcode', $search))
            ->limit(5)
            ->get()
            ->map(fn ($p) => [
                'id' => $p->id,
                'type' => 'product',
                'name_ar' => $p->name_ar,
                'name' => $p->name,
                'sku' => $p->sku,
                'price' => $p->selling_price,
            ])->toArray();

        $kits = Kit::where('is_active', true)
            ->where(fn ($q) => $q->where('name_ar', 'ilike', "%{$search}%")
                ->orWhere('name', 'ilike', "%{$search}%")
                ->orWhere('sku', 'ilike', "%{$search}%"))
            ->limit(5)
            ->get()
            ->map(fn ($k) => [
                'id' => $k->id,
                'type' => 'kit',
                'name_ar' => $k->name_ar,
                'name' => $k->name,
                'sku' => $k->sku,
                'price' => $k->selling_price,
            ])->toArray();

        return array_merge($products, $kits);
    }

    public function addHotbuyItem(int $id, string $type): void
    {
        $key = "{$type}_{$id}";

        if (isset($this->hotbuyCart[$key])) {
            $this->hotbuyCart[$key]['quantity']++;
        } else {
            $item = $type === 'product'
                ? Product::find($id)
                : Kit::find($id);

            if (!$item) {
                return;
            }

            $this->hotbuyCart[$key] = [
                'id' => $item->id,
                'type' => $type,
                'name_ar' => $item->name_ar,
                'price' => $item->selling_price,
                'quantity' => 1,
            ];
        }

        $this->hotbuy_search = '';
    }

    public function removeHotbuyItem(string $key): void
    {
        unset($this->hotbuyCart[$key]);
    }

    public function updateHotbuyQuantity(string $key, int $quantity): void
    {
        if ($quantity <= 0) {
            unset($this->hotbuyCart[$key]);
            return;
        }
        if (isset($this->hotbuyCart[$key])) {
            $this->hotbuyCart[$key]['quantity'] = $quantity;
        }
    }

    #[Computed]
    public function hotbuyTotal(): int
    {
        return collect($this->hotbuyCart)->sum(fn ($item) => $item['price'] * $item['quantity']);
    }

    // --- Proration ---

    #[Computed]
    public function proratedProgramFee(): ProrationResult
    {
        $baseFee = $this->selectedProgramFee;
        $service = app(ProrationService::class);
        if (!$service->isEnabled() || $baseFee === 0) {
            return new ProrationResult(
                applied: false,
                originalAmount: $baseFee,
                proratedAmount: $baseFee,
                remainingDays: 30,
                renewalDay: $service->renewalDay(),
                description: '',
            );
        }
        return $service->calculate($baseFee);
    }

    #[Computed]
    public function selectedProgram(): ?TrainingProgram
    {
        if (!$this->selected_program_id) {
            return null;
        }
        return TrainingProgram::with('activity')->find($this->selected_program_id);
    }

    #[Computed]
    public function selectedProgramFee(): int
    {
        if (!$this->selected_program_id) {
            return 0;
        }
        $program = TrainingProgram::find($this->selected_program_id);
        return $program ? $this->resolveProgramFee($program) : 0;
    }

    #[Computed]
    public function platformFee(): int
    {
        $service = app(PlatformFeeService::class);
        if (!$service->customerPays()) {
            return 0;
        }
        $subtotal = $this->proratedProgramFee->proratedAmount + $this->hotbuyTotal;
        return $service->calculate($subtotal);
    }

    #[Computed]
    public function totalWithFee(): int
    {
        return $this->proratedProgramFee->proratedAmount + $this->hotbuyTotal + $this->platformFee;
    }

    #[Computed]
    public function invoiceForPrint(): ?Invoice
    {
        if (!$this->invoiceId) {
            return null;
        }
        return Invoice::with('items')->find($this->invoiceId);
    }

    public function confirm(): void
    {
        try {
            DB::transaction(function () {
                $actor = auth()->user();
                $personService = app(PersonService::class);
                $participantService = app(ParticipantService::class);
                $enrollmentService = app(EnrollmentService::class);
                $invoiceService = app(InvoiceService::class);
                $paymentService = app(PaymentService::class);

                // 1. Create or reuse guardian's Person record
                if ($this->useExistingPersonId) {
                    $guardianPerson = Person::findOrFail($this->useExistingPersonId);
                } else {
                    $guardianPerson = Person::where('phone', $this->guardian_phone)->first();
                    if (!$guardianPerson) {
                        $guardianPerson = $personService->create([
                            'name_ar' => $this->guardian_name_ar,
                            'name' => $this->guardian_name ?: $this->guardian_name_ar,
                            'phone' => $this->guardian_phone,
                        ], $actor);
                    }
                }

                // 2. Create or find the Guardian record
                $guardian = Guardian::firstOrCreate(
                    ['person_id' => $guardianPerson->id],
                    [
                        'academy_id' => app('current_academy')->id,
                        'relationship_type' => $this->guardian_relation,
                        'is_emergency_contact' => true,
                        'is_financial_responsible' => true,
                        'can_pickup' => true,
                    ]
                );

                // 2b. Create parent User account if requested
                if ($this->createParentAccount && $this->parentEmail) {
                    $parentRole = Role::where('slug', 'parent')
                        ->where('academy_id', app('current_academy')->id)
                        ->first();

                    if (!$guardian->user_id) {
                        $parentUser = User::create([
                            'academy_id' => app('current_academy')->id,
                            'name' => $guardianPerson->name ?: $guardianPerson->name_ar,
                            'name_ar' => $guardianPerson->name_ar,
                            'email' => $this->parentEmail,
                            'phone' => $guardianPerson->phone,
                            'password' => Hash::make($this->parentPassword),
                            'person_id' => $guardianPerson->id,
                            'role_id' => $parentRole?->id,
                            'status' => 'active',
                        ]);

                        $guardian->update(['user_id' => $parentUser->id]);
                        $guardianPerson->update(['user_id' => $parentUser->id]);

                        if ($parentRole) {
                            $parentUser->roles()->attach($parentRole->id, [
                                'assigned_by' => $actor->id,
                                'created_at' => now(),
                            ]);
                        }
                    }
                }

                // 3. Create participant's Person record
                $participantPerson = $personService->create([
                    'name_ar' => $this->participant_name_ar,
                    'name' => $this->participant_name ?: $this->participant_name_ar,
                    'date_of_birth' => $this->participant_date_of_birth,
                    'gender' => $this->participant_gender,
                    'phone' => $this->participant_phone ?: null,
                    'national_id' => $this->participant_national_id ?: null,
                    'governorate' => $this->participant_governorate ?: null,
                    'medical_notes' => $this->participant_medical_notes ?: null,
                ], $actor);

                // 4. Create Participant record via service
                $participant = $participantService->register([
                    'person_id' => $participantPerson->id,
                    'branch_id' => $this->branchId,
                    'registration_source' => 'walk_in',
                    'primary_guardian_id' => $guardian->id,
                    'primary_activity_id' => $this->selected_activity_id,
                    'membership_type' => $this->membership_type,
                    'membership_id' => $this->membership_type === 'member' ? $this->membership_id : null,
                ], $actor);

                // 5. Link guardian to participant via pivot
                $participant->guardians()->attach($guardian->id, [
                    'relationship_type' => $this->guardian_relation,
                    'is_primary' => true,
                    'is_emergency_contact' => true,
                    'can_pickup' => true,
                    'receives_notifications' => true,
                    'can_authorize_payment' => true,
                ]);

                // 6. Enroll in program
                $program = TrainingProgram::findOrFail($this->selected_program_id);
                $enrollment = $enrollmentService->enrollInProgram(
                    $participant,
                    $program,
                    $actor
                );

                // 7. Resolve program fee with optional proration, hot-buy, platform fee
                $prorationResult = $this->proratedProgramFee;
                $programFee = $prorationResult->proratedAmount;
                $hotbuyTotal = $this->hotbuyTotal;
                $subtotal = $programFee + $hotbuyTotal;

                $platformFeeService = app(PlatformFeeService::class);
                $customerPays = $platformFeeService->customerPays();
                $serviceFee = $customerPays ? $platformFeeService->calculate($subtotal) : 0;
                $computedTotal = $subtotal + $serviceFee;

                // Super-admin override
                $finalTotal = $computedTotal;
                if ($this->priceOverrideEnabled && $this->priceOverrideInput !== '' && $actor->is_super_admin) {
                    $overrideAmount = (int) round((float) $this->priceOverrideInput * 100);
                    $finalTotal = max(0, $overrideAmount);

                    // Audit the override
                    \Log::channel('audit')->info('super_admin_price_override', [
                        'actor_id' => $actor->id,
                        'actor_name' => $actor->name,
                        'participant_name' => $this->participant_name_ar,
                        'program' => $program->name_ar,
                        'original_piasters' => $computedTotal,
                        'override_piasters' => $finalTotal,
                        'reason' => $this->priceOverrideReason,
                    ]);
                }

                // 8. Create invoice if there's a fee or hot-buy items
                $invoice = null;
                if ($subtotal > 0 || $finalTotal !== $computedTotal) {
                    $invoiceItems = [];

                    if ($programFee > 0) {
                        $description = $program->name_ar;
                        if ($prorationResult->applied) {
                            $description .= ' (' . $prorationResult->description . ')';
                        }
                        $invoiceItems[] = [
                            'description' => $description,
                            'quantity' => 1,
                            'unit_price' => $programFee,
                            'discount_amount' => 0,
                            'tax_amount' => 0,
                        ];
                    }

                    foreach ($this->hotbuyCart as $cartItem) {
                        $invoiceItems[] = [
                            'description' => $cartItem['name_ar'],
                            'quantity' => $cartItem['quantity'],
                            'unit_price' => $cartItem['price'],
                            'discount_amount' => 0,
                            'tax_amount' => 0,
                        ];
                    }

                    // If override changed total, reflect as a discount line
                    $discountAmount = 0;
                    if ($this->priceOverrideEnabled && $actor->is_super_admin && $finalTotal < $computedTotal) {
                        $discountAmount = $computedTotal - $finalTotal;
                    }

                    $invoice = $invoiceService->create([
                        'academy_id' => app('current_academy')->id,
                        'number' => $invoiceService->generateNumber(app('current_academy')->id),
                        'type' => 'standard',
                        'billable_type' => Participant::class,
                        'billable_id' => $participant->id,
                        'contact_name' => $this->guardian_name_ar,
                        'contact_phone' => $this->guardian_phone,
                        'subtotal_amount' => $subtotal,
                        'discount_amount' => $discountAmount,
                        'tax_amount' => 0,
                        'service_fee_amount' => $serviceFee,
                        'total_amount' => $finalTotal,
                        'currency' => 'EGP',
                        'issue_date' => now()->toDateString(),
                        'due_date' => now()->addDays(7)->toDateString(),
                        'notes' => 'اشتراك: ' . $program->name_ar,
                    ], $invoiceItems, $actor);

                    $invoice->update(['status' => 'sent']);
                    $enrollment->update(['invoice_id' => $invoice->id]);

                    $this->invoice_amount = $invoice->total_amount;
                    $this->invoice_number = $invoice->number;
                    $this->invoiceId = $invoice->id;

                    // 9. Record payment if paying now
                    if ($this->pay_now) {
                        $paymentService->recordPayment([
                            'academy_id' => app('current_academy')->id,
                            'branch_id' => $this->branchId,
                            'invoice_id' => $invoice->id,
                            'reference' => 'PAY-' . now()->format('YmdHis') . '-' . $participant->id,
                            'direction' => 'inbound',
                            'method' => $this->payment_method,
                            'payer_type' => Participant::class,
                            'payer_id' => $participant->id,
                            'amount' => $invoice->total_amount,
                            'currency' => 'EGP',
                            'payment_date' => now()->toDateString(),
                            'notes' => 'دفع اشتراك: ' . $program->name_ar,
                        ], $actor);

                        $this->payment_recorded = true;
                        $enrollment->update(['payment_status' => 'paid']);
                    }
                }

                $this->completed = true;
                $this->participant_number = $participant->participant_number;
                $this->participant_uuid = $participant->uuid;
                $this->enrollment_summary = $program->name_ar . ' — ' . ($enrollment->group?->name_ar ?? '');
                if ($invoice) {
                    $this->invoice_uuid = $invoice->uuid;
                }
                $this->currentStep = 7;
            });

            session()->flash('success', __('تم التسجيل بنجاح'));
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        } catch (\Throwable $e) {
            session()->flash('error', 'حدث خطأ: ' . $e->getMessage());
        }
    }

    private function resolveProgramFee(TrainingProgram $program): int
    {
        $query = BasePrice::where('priceable_type', TrainingProgram::class)
            ->where('priceable_id', $program->id)
            ->where('is_active', true)
            ->where('effective_from', '<=', now())
            ->where(fn ($q) => $q->whereNull('effective_to')->orWhere('effective_to', '>=', now()))
            ->forBranch($this->branchId);

        $specificPrice = (clone $query)
            ->whereJsonContains('metadata->membership_type', $this->membership_type)
            ->orderByDesc('priority')
            ->first();

        if ($specificPrice) {
            return $specificPrice->amount;
        }

        $genericPrice = $query
            ->where(fn ($q) => $q
                ->whereNull('metadata->membership_type')
                ->orWhereRaw("metadata->>'membership_type' = ''")
                ->orWhereRaw("metadata = '{}'::jsonb")
            )
            ->orderByDesc('priority')
            ->first();

        return $genericPrice?->amount ?? 0;
    }

    public function render()
    {
        $activities = Activity::where('is_active', true)->orderBy('name_ar')->get();
        $programs = collect();

        if ($this->selected_activity_id) {
            $programs = TrainingProgram::where('activity_id', $this->selected_activity_id)
                ->where('status', 'active')
                ->whereHas('groups', fn ($q) => $q->where(function ($sub) {
                    $sub->where('branch_id', $this->branchId)->orWhereNull('branch_id');
                })->whereIn('status', ['active', 'forming']))
                ->orderBy('name_ar')
                ->get();
        }

        return view('livewire.receptionist.new-registration-wizard', [
            'activities' => $activities,
            'programs' => $programs,
            'isSuperAdmin' => auth()->user()?->is_super_admin ?? false,
            'relationOptions' => [
                'father' => 'أب',
                'mother' => 'أم',
                'brother' => 'أخ',
                'sister' => 'أخت',
                'uncle' => 'عم/خال',
                'aunt' => 'عمة/خالة',
                'grandfather' => 'جد',
                'grandmother' => 'جدة',
                'guardian' => 'وصي',
                'other' => 'أخرى',
            ],
        ]);
    }
}
