<?php

namespace App\Http\Livewire\Tenant;

use App\Models\Employee;
use App\Models\Service;
use App\Support\PublicUploader;
use App\Support\Tenant;
use Livewire\Attributes\Validate;
use Livewire\Component;
use Livewire\WithFileUploads;

class EmployeeForm extends Component
{
    use WithFileUploads;

    public ?Employee $employee = null;

    #[Validate('required|string|max:100')]
    public string $first_name = '';

    #[Validate('nullable|string|max:100')]
    public string $last_name = '';

    #[Validate('nullable|email|max:255')]
    public string $email = '';

    #[Validate('nullable|string|max:25')]
    public string $phone = '';

    #[Validate('nullable|string|max:100')]
    public string $position = '';

    #[Validate('nullable|string|max:1000')]
    public string $bio = '';

    #[Validate('regex:/^#[0-9a-fA-F]{6}$/')]
    public string $color = '#4f46e5';

    #[Validate('nullable|image|max:2048')]
    public $photo = null;

    public ?string $current_photo_url = null;

    public bool $is_active = true;
    public bool $is_bookable = true;

    /** @var array<int> */
    public array $service_ids = [];

    public function mount($employee = null, ?int $employeeId = null): void
    {
        if ($employee instanceof Employee || $employeeId) {
            $this->employee = $employee instanceof Employee
                ? $employee->loadMissing('services:id')
                : Employee::with('services:id')->findOrFail($employeeId);

            $data = $this->employee->only([
                'first_name', 'last_name', 'email', 'phone',
                'position', 'bio', 'color', 'is_active', 'is_bookable',
            ]);

            foreach (['last_name', 'email', 'phone', 'position', 'bio'] as $field) {
                $data[$field] = $data[$field] ?? '';
            }
            $data['color'] = $data['color'] ?: '#4f46e5';
            $data['is_active'] = (bool) $data['is_active'];
            $data['is_bookable'] = (bool) $data['is_bookable'];

            $this->fill($data);
            $this->service_ids = $this->employee->services->pluck('id')->all();
            $this->current_photo_url = $this->employee->photoUrl();
        }
    }

    public function save()
    {
        $this->validate();

        validator([
            'service_ids' => $this->service_ids,
        ], [
            'service_ids' => ['array'],
            'service_ids.*' => ['integer', 'exists:services,id'],
        ])->validate();

        $data = [
            'first_name'  => $this->first_name,
            'last_name'   => $this->last_name ?: null,
            'email'       => $this->email ?: null,
            'phone'       => $this->phone ?: null,
            'position'    => $this->position ?: null,
            'bio'         => $this->bio ?: null,
            'color'       => $this->color,
            'is_active'   => $this->is_active,
            'is_bookable' => $this->is_bookable,
            'branch_id'   => Tenant::current()?->mainBranch?->id,
        ];

        if ($this->photo) {
            if ($this->employee?->photo_path) {
                PublicUploader::delete($this->employee->photo_path);
            }

            $data['photo_path'] = PublicUploader::store($this->photo, 'employees');
        }

        if ($this->employee) {
            $this->employee->update($data);
        } else {
            $this->employee = Employee::create($data);
        }

        $sync = collect($this->service_ids)
            ->mapWithKeys(fn ($id) => [$id => ['company_id' => Tenant::id()]])
            ->all();
        $this->employee->services()->sync($sync);

        session()->flash('success', 'Empleado guardado.');
        return redirect()->route('tenant.employees.index');
    }

    public function selectAllServices(): void
    {
        $this->service_ids = Service::active()->pluck('id')->map(fn ($id) => (int) $id)->all();
    }

    public function clearServices(): void
    {
        $this->service_ids = [];
    }

    public function render()
    {
        return view('livewire.tenant.employee-form', [
            'services' => Service::active()->orderBy('name')->get(['id', 'name']),
        ]);
    }
}
