<?php

namespace App\Livewire\HR;

use App\Domain\HR\Enums\CompensationModel;
use App\Domain\HR\Models\Employee;
use App\Domain\HR\Models\Trainer;
use App\Domain\HR\Services\TrainerService;
use App\Domain\Shared\Exceptions\DomainException;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('بيانات المدرب')]
class TrainerForm extends Component
{
    public ?Trainer $trainer = null;
    public bool $editing = false;

    // Employee selection
    public string $employeeSearch = '';
    public ?int $employeeId = null;
    public string $selectedEmployeeName = '';

    // Form fields
    public string $bio = '';
    public string $bioAr = '';
    public array $specializations = [];
    public array $sports = [];
    public ?string $maxDailySessions = null;
    public ?string $maxWeeklyHours = null;
    public string $compensationModel = 'salary';
    public ?string $hourlyRate = null;
    public ?string $sessionRate = null;
    public ?string $groupRate = null;
    public ?string $playerRate = null;
    public ?string $revenueSharePercent = null;

    // Qualifications
    public array $qualifications = [];
    public string $newQualName = '';
    public string $newQualIssuer = '';
    public ?string $newQualIssueDate = null;
    public ?string $newQualExpiryDate = null;

    public function mount(?Trainer $trainer = null): void
    {
        if ($trainer && $trainer->exists) {
            $this->authorize('trainers.update');
            $this->trainer = $trainer->load(['employee.person', 'qualifications']);
            $this->editing = true;

            $this->employeeId = $trainer->employee_id;
            $this->selectedEmployeeName = $trainer->employee->person->name_ar ?? '';
            $this->bio = $trainer->bio ?? '';
            $this->bioAr = $trainer->bio_ar ?? '';
            $this->specializations = $trainer->specializations ?? [];
            $this->sports = $trainer->sports ?? [];
            $this->maxDailySessions = $trainer->max_daily_sessions ? (string) $trainer->max_daily_sessions : null;
            $this->maxWeeklyHours = $trainer->max_weekly_hours ? (string) $trainer->max_weekly_hours : null;
            $this->compensationModel = $trainer->compensation_model->value;
            $this->hourlyRate = $trainer->hourly_rate ? (string) ($trainer->hourly_rate / 100) : null;
            $this->sessionRate = $trainer->session_rate ? (string) ($trainer->session_rate / 100) : null;
            $this->groupRate = $trainer->group_rate ? (string) ($trainer->group_rate / 100) : null;
            $this->playerRate = $trainer->player_rate ? (string) ($trainer->player_rate / 100) : null;
            $this->revenueSharePercent = $trainer->revenue_share_percent ? (string) $trainer->revenue_share_percent : null;
            $this->qualifications = $trainer->qualifications->map(fn ($q) => [
                'id' => $q->id,
                'name' => $q->name,
                'issuer' => $q->issuer,
                'issue_date' => $q->issue_date?->format('Y-m-d'),
                'expiry_date' => $q->expiry_date?->format('Y-m-d'),
                'is_verified' => $q->is_verified,
            ])->toArray();
        } else {
            $this->authorize('trainers.create');
        }
    }

    public function rules(): array
    {
        return [
            'employeeId' => 'required|exists:employees,id',
            'bio' => 'nullable|string|max:2000',
            'bioAr' => 'nullable|string|max:2000',
            'compensationModel' => 'required|in:' . implode(',', array_column(CompensationModel::cases(), 'value')),
            'maxDailySessions' => 'nullable|integer|min:1|max:20',
            'maxWeeklyHours' => 'nullable|numeric|min:1|max:168',
            'hourlyRate' => 'nullable|numeric|min:0',
            'sessionRate' => 'nullable|numeric|min:0',
            'groupRate' => 'nullable|numeric|min:0',
            'playerRate' => 'nullable|numeric|min:0',
            'revenueSharePercent' => 'nullable|numeric|min:0|max:100',
        ];
    }

    public function messages(): array
    {
        return [
            'employeeId.required' => 'يجب اختيار موظف',
            'employeeId.exists' => 'الموظف المختار غير موجود',
            'compensationModel.required' => 'نموذج التعويض مطلوب',
            'compensationModel.in' => 'نموذج التعويض غير صالح',
            'maxDailySessions.integer' => 'الحد الأقصى للحصص يجب أن يكون رقماً صحيحاً',
            'maxWeeklyHours.numeric' => 'ساعات العمل الأسبوعية يجب أن تكون رقماً',
            'revenueSharePercent.max' => 'نسبة الإيرادات لا يمكن أن تتجاوز 100%',
        ];
    }

    public function save(TrainerService $service): void
    {
        $this->validate();

        $data = [
            'bio' => $this->bio ?: null,
            'bio_ar' => $this->bioAr ?: null,
            'specializations' => $this->specializations,
            'sports' => $this->sports,
            'max_daily_sessions' => $this->maxDailySessions ? (int) $this->maxDailySessions : null,
            'max_weekly_hours' => $this->maxWeeklyHours ?: null,
            '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,
        ];

        try {
            if ($this->editing) {
                $service->update($this->trainer, $data, auth()->user());
                session()->flash('success', __('تم تحديث بيانات المدرب بنجاح'));
            } else {
                $employee = Employee::findOrFail($this->employeeId);
                $service->create($employee, $data, auth()->user());
                session()->flash('success', __('تم إضافة المدرب بنجاح'));
            }

            $this->redirect(route('trainers.list'), navigate: true);
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function addQualification(): void
    {
        if (! $this->newQualName) {
            return;
        }

        $this->qualifications[] = [
            'id' => null,
            'name' => $this->newQualName,
            'issuer' => $this->newQualIssuer,
            'issue_date' => $this->newQualIssueDate,
            'expiry_date' => $this->newQualExpiryDate,
            'is_verified' => false,
        ];

        $this->newQualName = '';
        $this->newQualIssuer = '';
        $this->newQualIssueDate = null;
        $this->newQualExpiryDate = null;
    }

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

    public function selectEmployee(int $id): void
    {
        $employee = Employee::with('person')->find($id);
        if ($employee) {
            $this->employeeId = $employee->id;
            $this->selectedEmployeeName = $employee->person->name_ar;
            $this->employeeSearch = '';
        }
    }

    public function render()
    {
        $searchResults = [];
        if (strlen($this->employeeSearch) >= 2) {
            $searchResults = Employee::with('person')
                ->active()
                ->doesntHave('trainer')
                ->whereHas('person', function ($q) {
                    $q->where('name_ar', 'ilike', "%{$this->employeeSearch}%")
                        ->orWhere('name', 'ilike', "%{$this->employeeSearch}%");
                })
                ->limit(10)->get();
        }

        return view('livewire.hr.trainer-form', [
            'searchResults' => $searchResults,
            'compensationModels' => CompensationModel::cases(),
            'activities' => \App\Domain\Training\Models\Activity::where('is_active', true)->orderBy('name_ar')->get(),
        ]);
    }
}
