<?php

namespace App\Livewire\HR;

use App\Domain\HR\Enums\AvailabilityType;
use App\Domain\HR\Enums\CompensationModel;
use App\Domain\HR\Enums\EmploymentType;
use App\Domain\HR\Services\EmployeeService;
use App\Domain\HR\Services\TrainerService;
use App\Domain\Identity\Models\Branch;
use App\Domain\Identity\Models\Person;
use App\Domain\Shared\Exceptions\DomainException;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('إضافة مدرب جديد')]
class CreateTrainerWizard extends Component
{
    public int $currentStep = 1;
    public int $totalSteps = 6;
    public bool $completed = false;

    // Step 1: Person
    public ?int $personId = null;
    public string $personSearch = '';
    public bool $createNewPerson = false;
    public string $personNameAr = '';
    public string $personName = '';
    public string $personPhone = '';
    public string $personNationalId = '';
    public string $personDateOfBirth = '';
    public string $personGender = '';

    // Step 2: Employment
    public string $department = '';
    public string $position = '';
    public string $employmentType = '';
    public string $startDate = '';
    public ?int $branchId = null;

    // Step 3: Compensation
    public string $compensationModel = '';
    public string $hourlyRate = '';
    public string $sessionRate = '';
    public string $groupRate = '';
    public string $playerRate = '';
    public string $revenueSharePercent = '';

    // Step 4: Availability
    public array $availabilities = [];

    // Step 5: Qualifications
    public array $qualifications = [];

    public function mount(): void
    {
        $this->authorize('trainers.create');
        $this->startDate = now()->toDateString();
        $this->position = 'مدرب';
        $this->department = 'التدريب';

        // Initialize 7 days availability
        $days = ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'];
        foreach ($days as $index => $day) {
            $this->availabilities[$index] = [
                'day_of_week' => $index,
                'day_name' => $day,
                'enabled' => false,
                'start_time' => '08:00',
                'end_time' => '17:00',
                'type' => 'available',
            ];
        }

        // Initialize empty qualification
        $this->qualifications = [
            ['name' => '', 'issuer' => '', 'issue_date' => '', 'expiry_date' => ''],
        ];
    }

    public function getStepLabels(): array
    {
        return [
            1 => 'بيانات الشخص',
            2 => 'بيانات التوظيف',
            3 => 'التعويض',
            4 => 'التوفر',
            5 => 'المؤهلات',
            6 => 'مراجعة',
        ];
    }

    public function getPersonResultsProperty(): \Illuminate\Support\Collection
    {
        if (strlen($this->personSearch) < 2) {
            return collect();
        }

        return Person::where(function ($q) {
            $q->where('name_ar', 'ilike', "%{$this->personSearch}%")
              ->orWhere('name', 'ilike', "%{$this->personSearch}%")
              ->orWhere('phone', 'like', "%{$this->personSearch}%")
              ->orWhere('national_id', 'like', "%{$this->personSearch}%");
        })->limit(10)->get(['id', 'name', 'name_ar', 'phone', 'national_id']);
    }

    public function selectPerson(int $id): void
    {
        $person = Person::findOrFail($id);
        $this->personId = $person->id;
        $this->personNameAr = $person->name_ar ?? '';
        $this->personName = $person->name ?? '';
        $this->personPhone = $person->phone ?? '';
        $this->personNationalId = $person->national_id ?? '';
        $this->personDateOfBirth = $person->date_of_birth?->toDateString() ?? '';
        $this->personGender = $person->gender ?? '';
        $this->createNewPerson = false;
        $this->personSearch = '';
    }

    public function toggleCreateNew(): void
    {
        $this->createNewPerson = !$this->createNewPerson;
        if ($this->createNewPerson) {
            $this->personId = null;
        }
    }

    public function addQualification(): void
    {
        $this->qualifications[] = ['name' => '', 'issuer' => '', 'issue_date' => '', 'expiry_date' => ''];
    }

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

    public function rulesForStep(int $step): array
    {
        return match ($step) {
            1 => $this->createNewPerson ? [
                'personNameAr' => 'required|string|max:255',
                'personPhone' => 'required|string|max:20',
                'personGender' => 'required|in:male,female',
            ] : [
                'personId' => 'required|exists:people,id',
            ],
            2 => [
                'department' => 'required|string|max:100',
                'position' => 'required|string|max:100',
                'employmentType' => 'required|in:' . implode(',', array_column(EmploymentType::cases(), 'value')),
                'startDate' => 'required|date',
                'branchId' => 'required|exists:branches,id',
            ],
            3 => [
                'compensationModel' => 'required|in:' . implode(',', array_column(CompensationModel::cases(), 'value')),
            ],
            4 => [],
            5 => [],
            default => [],
        };
    }

    public function messagesForStep(int $step): array
    {
        return match ($step) {
            1 => [
                'personId.required' => 'يجب اختيار شخص من القائمة',
                'personId.exists' => 'الشخص المختار غير موجود',
                'personNameAr.required' => 'الاسم بالعربي مطلوب',
                'personPhone.required' => 'رقم الهاتف مطلوب',
                'personGender.required' => 'الجنس مطلوب',
                'personGender.in' => 'قيمة الجنس غير صالحة',
            ],
            2 => [
                'department.required' => 'القسم مطلوب',
                'position.required' => 'المسمى الوظيفي مطلوب',
                'employmentType.required' => 'نوع التوظيف مطلوب',
                'employmentType.in' => 'نوع التوظيف غير صالح',
                'startDate.required' => 'تاريخ البدء مطلوب',
                'branchId.required' => 'يجب اختيار الفرع',
                'branchId.exists' => 'الفرع غير موجود',
            ],
            3 => [
                'compensationModel.required' => 'نموذج التعويض مطلوب',
                'compensationModel.in' => 'نموذج التعويض غير صالح',
            ],
            default => [],
        };
    }

    public function nextStep(): void
    {
        $this->validate(
            $this->rulesForStep($this->currentStep),
            $this->messagesForStep($this->currentStep)
        );

        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;
        }
    }

    public function confirm(): void
    {
        try {
            DB::transaction(function () {
                $person = $this->resolveOrCreatePerson();
                $academyId = app('current_academy')->id;

                // Create Employee
                $employeeData = [
                    'academy_id' => $academyId,
                    'person_id' => $person->id,
                    'department' => $this->department,
                    'position' => $this->position,
                    'employment_type' => $this->employmentType,
                    'start_date' => $this->startDate,
                    'branch_id' => $this->branchId,
                ];

                $employee = app(EmployeeService::class)->create($employeeData, auth()->user());

                // Create Trainer
                $trainerData = [
                    'compensation_model' => $this->compensationModel,
                    'hourly_rate' => $this->hourlyRate ? (int) round((float) $this->hourlyRate * 100) : null,
                    'session_rate' => $this->sessionRate ? (int) round((float) $this->sessionRate * 100) : null,
                    'group_rate' => $this->groupRate ? (int) round((float) $this->groupRate * 100) : null,
                    'player_rate' => $this->playerRate ? (int) round((float) $this->playerRate * 100) : null,
                    'revenue_share_percent' => $this->revenueSharePercent ?: null,
                ];

                $trainerService = app(TrainerService::class);
                $trainer = $trainerService->create($employee, $trainerData, auth()->user());

                // Set Availability
                $slots = collect($this->availabilities)
                    ->filter(fn ($a) => $a['enabled'])
                    ->map(fn ($a) => [
                        'day_of_week' => $a['day_of_week'],
                        'start_time' => $a['start_time'],
                        'end_time' => $a['end_time'],
                        'type' => $a['type'],
                    ])
                    ->values()
                    ->toArray();

                if (!empty($slots)) {
                    $trainerService->setAvailability($trainer, $slots);
                }

                // Add Qualifications
                $validQualifications = collect($this->qualifications)
                    ->filter(fn ($q) => !empty($q['name']));

                foreach ($validQualifications as $qual) {
                    $trainerService->addQualification($trainer, [
                        'name' => $qual['name'],
                        'issuer' => $qual['issuer'] ?: null,
                        'issue_date' => $qual['issue_date'] ?: null,
                        'expiry_date' => $qual['expiry_date'] ?: null,
                    ]);
                }
            });

            $this->completed = true;
            session()->flash('success', 'تم إضافة المدرب بنجاح');
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    private function resolveOrCreatePerson(): Person
    {
        if ($this->personId) {
            return Person::findOrFail($this->personId);
        }

        return Person::create([
            'academy_id' => app('current_academy')->id,
            'name_ar' => $this->personNameAr,
            'name' => $this->personName ?: null,
            'phone' => $this->personPhone,
            'national_id' => $this->personNationalId ?: null,
            'date_of_birth' => $this->personDateOfBirth ?: null,
            'gender' => $this->personGender,
            'created_by' => auth()->id(),
        ]);
    }

    public function render()
    {
        return view('livewire.hr.create-trainer-wizard', [
            'stepLabels' => $this->getStepLabels(),
            'branches' => Branch::where('is_active', true)->orderBy('name_ar')->get(['id', 'name_ar']),
            'employmentTypes' => EmploymentType::cases(),
            'compensationModels' => CompensationModel::cases(),
            'availabilityTypes' => AvailabilityType::cases(),
        ]);
    }
}
