<?php

namespace App\Livewire\Events;

use App\Domain\Event\Enums\EventType;
use App\Domain\Event\Enums\FormFieldType;
use App\Domain\Event\Enums\LocationType;
use App\Domain\Event\Models\Event;
use App\Domain\Event\Services\EventService;
use App\Domain\Facility\Models\Facility;
use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Website\Enums\MediaCollection;
use App\Domain\Website\Services\MediaService;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
use Livewire\WithFileUploads;

#[Layout('layouts.app')]
#[Title('إنشاء حدث')]
class CreateEventWizard extends Component
{
    use WithFileUploads;

    public ?Event $event = null;
    public bool $editing = false;
    public int $currentStep = 1;
    public int $totalSteps = 4;
    public bool $completed = false;

    // Step 1: Details
    public string $title = '';
    public string $titleEn = '';
    public string $description = '';
    public string $descriptionEn = '';
    public string $type = '';
    public string $locationType = 'facility';
    public ?int $facilityId = null;
    public string $locationName = '';
    public string $locationAddress = '';
    public string $startsAt = '';
    public string $endsAt = '';
    public string $registrationOpensAt = '';
    public string $registrationClosesAt = '';
    public ?int $maxCapacity = null;

    // Step 2: Form Fields
    public array $formFields = [];

    // Step 3: Media
    public $coverPhoto = null;
    public array $galleryPhotos = [];

    public function mount(?Event $event = null): void
    {
        if ($event && $event->exists) {
            $this->authorize('events.update');
            $this->event = $event;
            $this->editing = true;
            $this->fillFromEvent($event);
        } else {
            $this->authorize('events.create');
            $this->formFields = $this->getDefaultFields();
        }
    }

    private function fillFromEvent(Event $event): void
    {
        $this->title = $event->title;
        $this->titleEn = $event->title_en ?? '';
        $this->description = $event->description ?? '';
        $this->descriptionEn = $event->description_en ?? '';
        $this->type = $event->type->value;
        $this->locationType = $event->location_type->value;
        $this->facilityId = $event->facility_id;
        $this->locationName = $event->location_name ?? '';
        $this->locationAddress = $event->location_address ?? '';
        $this->startsAt = $event->starts_at?->format('Y-m-d\TH:i');
        $this->endsAt = $event->ends_at?->format('Y-m-d\TH:i');
        $this->registrationOpensAt = $event->registration_opens_at?->format('Y-m-d\TH:i') ?? '';
        $this->registrationClosesAt = $event->registration_closes_at?->format('Y-m-d\TH:i') ?? '';
        $this->maxCapacity = $event->max_capacity;
        $this->formFields = $event->form_fields ?: $this->getDefaultFields();
    }

    private function getDefaultFields(): array
    {
        return [
            [
                'key' => 'name',
                'type' => 'text',
                'label' => 'الاسم الكامل',
                'label_en' => 'Full Name',
                'placeholder' => '',
                'is_required' => true,
                'sort_order' => 1,
                'options' => [],
                'width' => 'full',
            ],
            [
                'key' => 'phone',
                'type' => 'phone',
                'label' => 'رقم الهاتف',
                'label_en' => 'Phone',
                'placeholder' => '01XXXXXXXXX',
                'is_required' => true,
                'sort_order' => 2,
                'options' => [],
                'width' => 'half',
            ],
            [
                'key' => 'email',
                'type' => 'email',
                'label' => 'البريد الإلكتروني',
                'label_en' => 'Email',
                'placeholder' => '',
                'is_required' => false,
                'sort_order' => 3,
                'options' => [],
                'width' => 'half',
            ],
        ];
    }

    public function nextStep(): void
    {
        $this->validateStep();
        $this->currentStep = min($this->currentStep + 1, $this->totalSteps);
    }

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

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

    private function validateStep(): void
    {
        $rules = match ($this->currentStep) {
            1 => [
                'title' => 'required|string|max:255',
                'type' => 'required|in:' . implode(',', array_column(EventType::cases(), 'value')),
                'locationType' => 'required|in:facility,external',
                'facilityId' => $this->locationType === 'facility' ? 'required|exists:facilities,id' : 'nullable',
                'locationName' => $this->locationType === 'external' ? 'required|string|max:255' : 'nullable',
                'startsAt' => 'required|date',
                'endsAt' => 'required|date|after:startsAt',
            ],
            2 => [],
            3 => [
                'coverPhoto' => 'nullable|image|max:2048',
            ],
            default => [],
        };

        if (! empty($rules)) {
            $this->validate($rules, [
                'title.required' => 'عنوان الحدث مطلوب',
                'type.required' => 'نوع الحدث مطلوب',
                'locationType.required' => 'نوع الموقع مطلوب',
                'facilityId.required' => 'يرجى اختيار المنشأة',
                'locationName.required' => 'اسم الموقع مطلوب',
                'startsAt.required' => 'تاريخ البداية مطلوب',
                'endsAt.required' => 'تاريخ النهاية مطلوب',
                'endsAt.after' => 'تاريخ النهاية يجب أن يكون بعد تاريخ البداية',
            ]);
        }
    }

    // Form Builder Actions
    public function addField(): void
    {
        $order = count($this->formFields) + 1;
        $this->formFields[] = [
            'key' => 'field_' . $order,
            'type' => 'text',
            'label' => '',
            'label_en' => '',
            'placeholder' => '',
            'is_required' => false,
            'sort_order' => $order,
            'options' => [],
            'width' => 'full',
        ];
    }

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

    public function moveFieldUp(int $index): void
    {
        if ($index <= 0) return;

        $temp = $this->formFields[$index];
        $this->formFields[$index] = $this->formFields[$index - 1];
        $this->formFields[$index - 1] = $temp;
        $this->reorderFields();
    }

    public function moveFieldDown(int $index): void
    {
        if ($index >= count($this->formFields) - 1) return;

        $temp = $this->formFields[$index];
        $this->formFields[$index] = $this->formFields[$index + 1];
        $this->formFields[$index + 1] = $temp;
        $this->reorderFields();
    }

    public function addOption(int $fieldIndex): void
    {
        $this->formFields[$fieldIndex]['options'][] = ['value' => '', 'label' => ''];
    }

    public function removeOption(int $fieldIndex, int $optionIndex): void
    {
        unset($this->formFields[$fieldIndex]['options'][$optionIndex]);
        $this->formFields[$fieldIndex]['options'] = array_values($this->formFields[$fieldIndex]['options']);
    }

    private function reorderFields(): void
    {
        foreach ($this->formFields as $i => &$field) {
            $field['sort_order'] = $i + 1;
            $field['key'] = $field['key'] ?: 'field_' . ($i + 1);
        }
    }

    public function save(EventService $eventService, MediaService $mediaService): void
    {
        $this->validateStep();

        $academyId = app('current_academy')->id;

        $data = [
            'academy_id' => $academyId,
            'title' => $this->title,
            'title_en' => $this->titleEn ?: null,
            'description' => $this->description ?: null,
            'description_en' => $this->descriptionEn ?: null,
            'type' => $this->type,
            'location_type' => $this->locationType,
            'facility_id' => $this->locationType === 'facility' ? $this->facilityId : null,
            'location_name' => $this->locationType === 'external' ? $this->locationName : null,
            'location_address' => $this->locationType === 'external' ? $this->locationAddress : null,
            'starts_at' => $this->startsAt,
            'ends_at' => $this->endsAt,
            'registration_opens_at' => $this->registrationOpensAt ?: null,
            'registration_closes_at' => $this->registrationClosesAt ?: null,
            'max_capacity' => $this->maxCapacity ?: null,
            'form_fields' => $this->formFields,
        ];

        try {
            if ($this->editing) {
                $event = $eventService->update($this->event, $data, auth()->user());
            } else {
                $event = $eventService->create($data, auth()->user());
            }

            // Upload cover
            if ($this->coverPhoto) {
                if ($event->cover) {
                    $mediaService->replace($event->cover, $this->coverPhoto);
                } else {
                    $mediaService->upload(
                        $this->coverPhoto,
                        MediaCollection::EventCover,
                        Event::class,
                        $event->id
                    );
                }
            }

            // Upload gallery
            foreach ($this->galleryPhotos as $photo) {
                $mediaService->upload(
                    $photo,
                    MediaCollection::EventGallery,
                    Event::class,
                    $event->id
                );
            }

            $this->event = $event;
            $this->completed = true;
            session()->flash('success', $this->editing ? 'تم تحديث الحدث بنجاح' : 'تم إنشاء الحدث بنجاح');
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        } catch (\Exception $e) {
            session()->flash('error', 'حدث خطأ أثناء الحفظ: ' . $e->getMessage());
        }
    }

    public function render()
    {
        return view('livewire.events.create-event-wizard', [
            'eventTypes' => EventType::cases(),
            'locationTypes' => LocationType::cases(),
            'fieldTypes' => FormFieldType::cases(),
            'facilities' => Facility::where('status', 'active')->orderBy('name_ar')->get(['id', 'name_ar']),
        ]);
    }
}
