<?php

namespace App\Livewire\Wizards;

use App\Domain\Facility\Enums\FacilityType;
use App\Domain\Identity\Models\Branch;
use App\Domain\Identity\Models\Role;
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\TrainingProgram;
use App\Domain\Facility\Models\Facility;
use App\Domain\Pricing\Models\BasePrice;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

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

    // Step 1: Welcome
    public string $academyName = '';
    public string $academyNameAr = '';

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

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

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

    // Step 5: Facilities
    public array $facilities = [];

    // Step 6: Users
    public array $users = [];

    // Step 7: Settings
    public string $defaultCurrency = 'EGP';
    public string $timezone = 'Africa/Cairo';
    public int $gracePeriodParticipant = 15;
    public int $gracePeriodTrainer = 10;
    public int $maxDiscountPercent = 50;

    // 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)) {
            $this->redirect(route('dashboard'));
            return;
        }

        // Pre-fill academy info
        $this->academyName = $this->academy->name ?? '';
        $this->academyNameAr = $this->academy->name_ar ?? '';

        // 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,
        ];
    }

    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' => '',
        ];
    }

    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' => '',
        ];
    }

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

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

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

    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->validate([
                'academyNameAr' => 'required|string|min:3|max:255',
                'academyName' => 'nullable|string|max:255',
            ], [
                'academyNameAr.required' => __('اسم الأكاديمية بالعربية مطلوب'),
                'academyNameAr.min' => __('اسم الأكاديمية يجب أن يكون 3 أحرف على الأقل'),
            ]),
            2 => $this->validateBranches(),
            3 => $this->validateActivities(),
            4 => $this->validatePrograms(),
            5 => $this->validateFacilities(),
            6 => $this->validateUsers(),
            7 => $this->validate([
                'defaultCurrency' => 'required|string|in:EGP,SAR,AED,USD',
                'timezone' => 'required|string|timezone',
                'gracePeriodParticipant' => 'required|integer|min:0|max:60',
                'gracePeriodTrainer' => 'required|integer|min:0|max:60',
                'maxDiscountPercent' => 'required|integer|min:0|max:100',
            ], [
                'gracePeriodParticipant.required' => __('فترة السماح للمشتركين مطلوبة'),
                'gracePeriodTrainer.required' => __('فترة السماح للمدربين مطلوبة'),
                'maxDiscountPercent.required' => __('الحد الأقصى للخصم مطلوب'),
            ]),
            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.*.name_ar.required' => __('اسم الفرع بالعربية مطلوب'),
            'branches.*.name_ar.min' => __('اسم الفرع يجب أن يكون حرفين على الأقل'),
        ]);
    }

    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.*.name_ar.required' => __('اسم البرنامج بالعربية مطلوب'),
            'programs.*.duration_months.required' => __('مدة البرنامج مطلوبة'),
            'programs.*.max_participants.required' => __('الحد الأقصى للمشتركين مطلوب'),
            'programs.*.monthly_fee.required' => __('الرسوم الشهرية مطلوبة'),
            'programs.*.monthly_fee.min' => __('يجب تحديد سعر البرنامج (لا يمكن أن يكون صفر)'),
        ]);
    }

    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.*.name_ar.required' => __('اسم المنشأة بالعربية مطلوب'),
            'facilities.*.type.required' => __('نوع المنشأة مطلوب'),
            'facilities.*.monthly_cost.required' => __('الإيجار الشهري مطلوب (أدخل 0 إذا كانت ملك)'),
        ]);
    }

    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',
            'users.*.branch_index' => 'required|integer|min:0',
        ], [
            'users.*.name.required' => __('اسم المستخدم مطلوب'),
            'users.*.email.required' => __('البريد الإلكتروني مطلوب'),
            'users.*.email.email' => __('البريد الإلكتروني غير صالح'),
            'users.*.role.required' => __('الدور مطلوب'),
        ]);
    }

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

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

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

            // Update academy name
            $this->academy->update([
                'name' => $this->academyName ?: $this->academyNameAr,
                'name_ar' => $this->academyNameAr,
            ]);

            // 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,
                    'is_main' => $branchData['is_main'] ?? false,
                    'is_active' => true,
                    'code' => Str::upper(Str::limit(Str::slug($branchData['name_ar'], ''), 10, '')),
                ]);
            }

            // 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
            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);

                    $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'],
                        'status' => 'active',
                        'registration_open' => true,
                        'created_by' => $actor->id,
                        'metadata' => ['monthly_fee_piasters' => $monthlyFeePiasters],
                    ]);

                    BasePrice::create([
                        'academy_id' => $academyId,
                        'priceable_type' => TrainingProgram::class,
                        'priceable_id' => $program->id,
                        'branch_id' => null,
                        '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,
                    ]);
                }
            }

            // Create facilities
            foreach ($this->facilities as $facilityData) {
                Facility::create([
                    'academy_id' => $academyId,
                    'branch_id' => $createdBranches[0]->id ?? null,
                    '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,
                ]);
            }

            // 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();

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

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

            // Save system settings
            $settingsService = app(SettingsService::class);
            $settingsService->set('default_currency', $this->defaultCurrency, 'general', 'string');
            $settingsService->set('timezone', $this->timezone, 'general', 'string');
            $settingsService->set('grace_period_participant', (string) $this->gracePeriodParticipant, 'attendance', 'integer');
            $settingsService->set('grace_period_trainer', (string) $this->gracePeriodTrainer, 'attendance', 'integer');
            $settingsService->set('max_discount_percent', (string) $this->maxDiscountPercent, 'pricing', '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 ─────────────────────────────────────────────────

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

    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' => __('محاسب'),
        ];
    }

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