<?php

namespace App\Controllers;

use App\Core\Controller;
use App\Helpers\Auth;
use App\Helpers\Url;
use App\Models\Event;
use App\Models\EventAttendance;
use App\Models\AuditLog;

class EventController extends Controller
{
    public function __construct()
    {
        parent::__construct();
    }

    public function index()
    {
        $model = new Event();
        if (Auth::check()) {
            $events = $model->all();
            $this->view('events/index', ['events' => $events]);
        } else {
            $events = $model->getPublicUpcoming(20);
            $this->view('events/public', ['events' => $events], false);
        }
    }

    public function show($params)
    {
        $model = new Event();
        $event = $model->getWithCreator($params['id'] ?? null);
        if (!$event) {
            $_SESSION['error'] = 'Event not found';
            $this->redirect('/events');
        }

        if ($event->visibility === 'private' && !Auth::check()) {
            $_SESSION['error'] = 'Please log in to view this event';
            $this->redirect('/login');
        }

        $attendanceModel = new EventAttendance();
        $attendeeCount = $model->getAttendeeCount($event->id);
        $isRegistered = Auth::check() ? $attendanceModel->isRegistered($event->id, Auth::id()) : false;

        $viewName = Auth::check() ? 'events/show' : 'events/public_show';
        $useLayout = Auth::check();
        $this->view($viewName, [
            'event' => $event,
            'attendeeCount' => $attendeeCount,
            'isRegistered' => $isRegistered,
        ], $useLayout);
    }

    public function create()
    {
        Auth::requireLogin();
        $this->view('events/form');
    }

    public function store()
    {
        Auth::requireLogin();
        $model = new Event();
        $coverImage = $this->handleImageUpload('cover_image');

        $data = [
            'title' => $_POST['title'] ?? '',
            'description' => $_POST['description'] ?? '',
            'event_type' => $_POST['event_type'] ?? 'meeting',
            'venue' => $_POST['venue'] ?? '',
            'start_datetime' => $_POST['start_datetime'] ?? '',
            'end_datetime' => $_POST['end_datetime'] ?? null,
            'registration_deadline' => $_POST['registration_deadline'] ?? null,
            'max_attendees' => $_POST['max_attendees'] ?? null,
            'fee' => $_POST['fee'] ?? 0,
            'visibility' => $_POST['visibility'] ?? 'public',
            'status' => 'upcoming',
            'created_by' => Auth::id(),
        ];

        if ($coverImage) {
            $data['cover_image'] = $coverImage;
        }

        $model->create($data);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'event.create', 'events', $model->db->lastInsertId(), "Created event: {$data['title']}");

        $_SESSION['success'] = 'Event created successfully';
        $this->redirect('/events');
    }

    public function edit($params)
    {
        Auth::requireLogin();
        $model = new Event();
        $event = $model->find($params['id'] ?? null);
        if (!$event) {
            $_SESSION['error'] = 'Event not found';
            $this->redirect('/events');
        }
        $this->view('events/form', ['event' => $event]);
    }

    public function update($params)
    {
        Auth::requireLogin();
        $id = $params['id'] ?? null;
        $model = new Event();
        $event = $model->find($id);
        if (!$event) {
            $_SESSION['error'] = 'Event not found';
            $this->redirect('/events');
        }

        $coverImage = $event->cover_image;
        if (!empty($_FILES['cover_image']['name'])) {
            if ($coverImage && file_exists($coverImage)) {
                unlink($coverImage);
            }
            $coverImage = $this->handleImageUpload('cover_image');
        }

        $data = [
            'title' => $_POST['title'] ?? '',
            'description' => $_POST['description'] ?? '',
            'event_type' => $_POST['event_type'] ?? 'meeting',
            'venue' => $_POST['venue'] ?? '',
            'start_datetime' => $_POST['start_datetime'] ?? '',
            'end_datetime' => $_POST['end_datetime'] ?? null,
            'registration_deadline' => $_POST['registration_deadline'] ?? null,
            'max_attendees' => $_POST['max_attendees'] ?? null,
            'fee' => $_POST['fee'] ?? 0,
            'visibility' => $_POST['visibility'] ?? 'public',
            'status' => $_POST['status'] ?? 'upcoming',
        ];

        if ($coverImage) {
            $data['cover_image'] = $coverImage;
        }

        $model->update($id, $data);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'event.update', 'events', $id, "Updated event: {$data['title']}");

        $_SESSION['success'] = 'Event updated successfully';
        $this->redirect('/events');
    }

    private function handleImageUpload($fieldName)
    {
        if (empty($_FILES[$fieldName]['name'])) {
            return null;
        }
        $allowed = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
        $ext = strtolower(pathinfo($_FILES[$fieldName]['name'], PATHINFO_EXTENSION));
        if (!in_array($ext, $allowed)) {
            return null;
        }
        $uploadDir = $_SERVER['DOCUMENT_ROOT'] . Url::getBaseUrl() . '/uploads/events/';
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }
        $filename = uniqid('evt_') . '.' . $ext;
        $dest = $uploadDir . $filename;
        if (move_uploaded_file($_FILES[$fieldName]['tmp_name'], $dest)) {
            return 'uploads/events/' . $filename;
        }
        return null;
    }

    public function delete($params)
    {
        Auth::requireLogin();
        $id = $params['id'] ?? null;
        $model = new Event();
        $event = $model->find($id);
        if ($event) {
            if ($event->cover_image && file_exists($event->cover_image)) {
                unlink($event->cover_image);
            }
            $audit = new AuditLog();
            $audit->log(Auth::id(), 'event.delete', 'events', $id, "Deleted event: {$event->title}");
            $model->delete($id);
            $_SESSION['success'] = 'Event deleted';
        }
        $this->redirect('/events');
    }

    public function register($params)
    {
        Auth::requireLogin();
        $eventId = $params['id'] ?? null;
        $eventModel = new Event();
        $event = $eventModel->find($eventId);

        if (!$event) {
            $_SESSION['error'] = 'Event not found';
            $this->redirect('/events');
        }

        $attendanceModel = new EventAttendance();
        if ($attendanceModel->isRegistered($eventId, Auth::id())) {
            $_SESSION['error'] = 'Already registered';
            $this->redirect('/events/' . $eventId);
        }

        if ($event->max_attendees && $eventModel->getAttendeeCount($eventId) >= $event->max_attendees) {
            $_SESSION['error'] = 'Event is full';
            $this->redirect('/events/' . $eventId);
        }

        $attendanceModel->create([
            'event_id' => $eventId,
            'user_id' => Auth::id(),
            'status' => 'registered',
        ]);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'event.register', 'events', $eventId, "Registered for event: {$event->title}");

        $_SESSION['success'] = 'Registered for event successfully';
        $this->redirect('/events/' . $eventId);
    }

    public function unregister($params)
    {
        Auth::requireLogin();
        $eventId = $params['id'] ?? null;
        $stmt = $this->db->prepare("DELETE FROM event_attendance WHERE event_id = ? AND user_id = ?");
        $stmt->execute([$eventId, Auth::id()]);

        $_SESSION['success'] = 'Registration cancelled';
        $this->redirect('/events/' . $eventId);
    }

    public function attendees($params)
    {
        Auth::requireLogin();
        $eventId = $params['id'] ?? null;
        $attendanceModel = new EventAttendance();
        $attendees = $attendanceModel->getByEvent($eventId);

        $eventModel = new Event();
        $event = $eventModel->find($eventId);

        $this->view('events/attendees', ['attendees' => $attendees, 'event' => $event]);
    }
}
