<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\Event;
use App\Models\EventUser;
use App\Models\User;

class EventService
{
    private Event $eventModel;
    private EventUser $eventUserModel;
    private User $userModel;

    public function __construct()
    {
        $this->eventModel = new Event();
        $this->eventUserModel = new EventUser();
        $this->userModel = new User();
    }

    public function getEvents(array $filters = [], int $page = 1, int $perPage = 15): array
    {
        return $this->eventModel->findWithPagination($page, $perPage, $filters);
    }

    public function getEvent(int $id): array
    {
        $event = $this->eventModel->findById($id);
        if (!$event) {
            throw new \RuntimeException('Evento no encontrado', 404);
        }

        $event['users'] = $this->eventUserModel->getEventUsers($id);

        return $event;
    }

    public function createEvent(array $data): array
    {
        $eventId = $this->eventModel->create([
            'name' => $data['name'],
            'description' => $data['description'] ?? null,
            'start_date' => $data['start_date'] ?? null,
            'end_date' => $data['end_date'] ?? null,
            'location' => $data['location'] ?? null,
        ]);

        if (!empty($data['user_ids'])) {
            $this->eventUserModel->syncUsers($eventId, $data['user_ids']);
        }

        return $this->getEvent($eventId);
    }

    public function updateEvent(int $id, array $data): array
    {
        $event = $this->eventModel->findById($id);
        if (!$event) {
            throw new \RuntimeException('Evento no encontrado', 404);
        }

        $updateData = [];
        foreach (['name', 'description', 'start_date', 'end_date', 'location'] as $field) {
            if (array_key_exists($field, $data)) {
                $updateData[$field] = $data[$field];
            }
        }

        if (!empty($updateData)) {
            $this->eventModel->update($id, $updateData);
        }

        if (array_key_exists('user_ids', $data)) {
            $this->eventUserModel->syncUsers($id, $data['user_ids']);
        }

        return $this->getEvent($id);
    }

    public function toggleStatus(int $id): array
    {
        $event = $this->eventModel->findById($id);
        if (!$event) {
            throw new \RuntimeException('Evento no encontrado', 404);
        }

        $newStatus = $event['status'] === 'active' ? 'inactive' : 'active';
        $this->eventModel->update($id, ['status' => $newStatus]);

        return $this->getEvent($id);
    }

    public function getUserEvents(int $userId): array
    {
        return $this->eventUserModel->getUserEvents($userId);
    }

    public function selectEvent(int $userId, int $eventId): array
    {
        $event = $this->eventModel->findById($eventId);
        if (!$event) {
            throw new \RuntimeException('Evento no encontrado', 404);
        }

        if ($event['status'] !== 'active') {
            throw new \RuntimeException('El evento no está activo', 400);
        }

        $this->userModel->setCurrentEvent($userId, $eventId);

        return $event;
    }

    public function deselectEvent(int $userId): void
    {
        $this->userModel->update($userId, ['current_event_id' => null]);
    }

    public function deleteEvent(int $id): void
    {
        $event = $this->eventModel->findById($id);
        if (!$event) {
            throw new \RuntimeException('Evento no encontrado', 404);
        }

        $this->eventModel->delete($id);
    }
}
