<?php

namespace App\Http\Controllers\Admin;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Models\Event;
use App\Models\EventCategory;
use App\Models\Media;
use App\Services\UploadService;

/**
 * ITSWEBER CMS – Admin Event Controller (Phase 4b)
 *
 * Images are attached via media_id (FK → iw_media).
 * No file uploads happen here – the media picker selects an existing
 * media record and stores its ID.
 */
class EventController extends Controller
{
    // -------------------------------------------------------------------------
    // LIST
    // -------------------------------------------------------------------------

    public function index(Request $request, array $params = []): void
    {
        $search        = trim($request->input('search', ''));
        $publishStatus = $request->input('publish_status', '');
        $eventStatus   = $request->input('event_status', '');
        $categoryId    = (int) $request->input('category_id', 0);
        $featuredRaw   = $request->input('featured', '');
        $featured      = ($featuredRaw === '') ? -1 : (int) $featuredRaw;

        $events     = Event::adminList($search, $publishStatus, $eventStatus, $categoryId, $featured);
        $categories = EventCategory::all('name');

        $this->renderAdmin('events/index', [
            'pageTitle'     => __('admin.events.title'),
            'events'        => $events,
            'categories'    => $categories,
            'search'        => $search,
            'publishStatus' => $publishStatus,
            'eventStatus'   => $eventStatus,
            'categoryId'    => $categoryId,
            'featured'      => $featured,
            'auth'          => $this->auth(),
            'csrf'          => $this->csrf(),
        ]);
    }

    // -------------------------------------------------------------------------
    // CREATE
    // -------------------------------------------------------------------------

    public function create(Request $request, array $params = []): void
    {
        $categories = EventCategory::all('name');

        $this->renderAdmin('events/form', [
            'pageTitle'  => __('admin.events.create'),
            'event'      => null,
            'categories' => $categories,
            'auth'       => $this->auth(),
            'csrf'       => $this->csrf(),
        ]);
    }

    public function store(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $data = $this->extractFormData($request);

        if (empty($data['title'])) {
            set_flash('error', __('messages.error.title_required'));
            Response::redirect(admin_url('events/create'));
            return;
        }

        if (empty($data['start_date'])) {
            set_flash('error', __('messages.error.start_date_required'));
            Response::redirect(admin_url('events/create'));
            return;
        }

        if (empty($data['slug'])) {
            $data['slug'] = slugify($data['title']);
        }

        $existing = Event::findBySlug($data['slug']);
        if ($existing) {
            $data['slug'] = $data['slug'] . '-' . bin2hex(random_bytes(4));
        }

        $data['created_by'] = $this->auth()->userId();
        $data['created_at'] = date('Y-m-d H:i:s');
        $data['updated_at'] = date('Y-m-d H:i:s');

        Event::create($data);

        set_flash('success', 'Event "' . $data['title'] . '" created successfully.');
        Response::redirect(admin_url('events'));
    }

    // -------------------------------------------------------------------------
    // EDIT / UPDATE
    // -------------------------------------------------------------------------

    public function edit(Request $request, array $params = []): void
    {
        $id    = (int) ($params['id'] ?? 0);
        $event = Event::findForAdmin($id);

        if (!$event) {
            set_flash('error', __('messages.not_found', ['item' => 'Event']));
            Response::redirect(admin_url('events'));
            return;
        }

        $categories = EventCategory::all('name');

        $this->renderAdmin('events/form', [
            'pageTitle'  => __('admin.events.edit'),
            'event'      => $event,
            'categories' => $categories,
            'auth'       => $this->auth(),
            'csrf'       => $this->csrf(),
        ]);
    }

    public function update(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $id    = (int) ($params['id'] ?? 0);
        $event = Event::findForAdmin($id);

        if (!$event) {
            set_flash('error', __('messages.not_found', ['item' => 'Event']));
            Response::redirect(admin_url('events'));
            return;
        }

        $data = $this->extractFormData($request);

        if (empty($data['title'])) {
            set_flash('error', __('messages.error.title_required'));
            Response::redirect(admin_url('events/edit/' . $id));
            return;
        }

        if (empty($data['start_date'])) {
            set_flash('error', __('messages.error.start_date_required'));
            Response::redirect(admin_url('events/edit/' . $id));
            return;
        }

        if (empty($data['slug'])) {
            $data['slug'] = slugify($data['title']);
        }

        $slugConflict = Event::findBySlug($data['slug']);
        if ($slugConflict && (int) $slugConflict['id'] !== $id) {
            $data['slug'] = $data['slug'] . '-' . bin2hex(random_bytes(4));
        }

        $data['updated_at'] = date('Y-m-d H:i:s');

        Event::updateById($id, $data);

        set_flash('success', 'Event updated successfully.');
        Response::redirect(admin_url('events'));
    }

    // -------------------------------------------------------------------------
    // DELETE
    // -------------------------------------------------------------------------

    public function delete(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $id    = (int) ($params['id'] ?? 0);
        $event = Event::findForAdmin($id);

        if (!$event) {
            set_flash('error', __('messages.not_found', ['item' => 'Event']));
            Response::redirect(admin_url('events'));
            return;
        }

        Event::deleteById($id);
        set_flash('success', 'Event "' . $event['title'] . '" deleted.');
        Response::redirect(admin_url('events'));
    }

    public function bulk(Request $request, array $params = []): void
    {
        $this->validateCsrf();
        $ids    = array_map('intval', $request->input('ids', []));
        $action = $request->input('bulk_action', '');

        if (empty($ids)) {
            Response::redirect(admin_url('events'));
            return;
        }

        $count = 0;
        foreach ($ids as $id) {
            if ($action === 'delete') {
                Event::deleteById($id);
                $count++;
            } elseif ($action === 'publish') {
                Event::updateById($id, ['publish_status' => 'published']);
                $count++;
            } elseif ($action === 'draft') {
                Event::updateById($id, ['publish_status' => 'draft']);
                $count++;
            }
        }

        set_flash('success', __('messages.bulk_action_done', ['count' => $count]));
        Response::redirect(admin_url('events'));
    }

    // -------------------------------------------------------------------------
    // DIRECT IMAGE UPLOAD (Phase 4b.1)
    // -------------------------------------------------------------------------

    /**
     * Quick-upload an image directly from the event form.
     * Stores the file via UploadService, creates a Media record, and returns
     * JSON so the form JS can immediately set the media_id + preview.
     *
     * POST /admin/events/upload-image
     */
    public function uploadImage(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $file = $request->file('image_file') ?? [];

        if (empty($file['tmp_name'])) {
            Response::json(['ok' => false, 'error' => 'No file received.'], 400);
            return;
        }

        // Use the central media subdirectory so the upload lands in the Media Manager
        $relPath = UploadService::upload($file, 'media', 'media', true, true);

        if ($relPath === null) {
            Response::json([
                'ok'    => false,
                'error' => 'Upload failed. Allowed types: JPG, PNG, GIF, WebP. Max size: 5 MB.',
            ], 422);
            return;
        }

        // Build a readable title from the original filename
        $rawTitle = pathinfo($file['name'] ?? '', PATHINFO_FILENAME);
        $title    = ucwords(strtolower(preg_replace('/[_\-]+/', ' ', $rawTitle)));

        $uploadsDir = UploadService::uploadsDir();
        $fileSize   = (int) @filesize($uploadsDir . $relPath);
        $mime       = mime_content_type($uploadsDir . $relPath) ?: 'application/octet-stream';

        $mediaId = Media::create([
            'folder_id'     => null,
            'filename'      => basename($relPath),
            'original_name' => $file['name'] ?? basename($relPath),
            'file_path'     => $relPath,
            'file_type'     => $mime,
            'file_size'     => $fileSize,
            'title'         => $title,
            'alt_text'      => null,
            'description'   => null,
            'uploaded_by'   => $this->auth()->userId(),
        ]);

        Response::json([
            'ok'        => true,
            'media_id'  => (int) $mediaId,
            'url'       => '/uploads/' . ltrim($relPath, '/'),
            'thumb_url' => thumb_url($relPath),
        ]);
    }

    // -------------------------------------------------------------------------
    // HELPERS
    // -------------------------------------------------------------------------

    /**
     * Extract and sanitise form data from the request.
     */
    private function extractFormData(Request $request): array
    {
        $title         = trim($request->input('title', ''));
        $slug          = trim($request->input('slug', ''));
        $excerpt       = trim($request->input('excerpt', ''));
        $content       = $request->input('content', '');
        $location      = trim($request->input('location', ''));
        $startDate     = trim($request->input('start_date', ''));
        $startTime     = trim($request->input('start_time', '')) ?: null;
        $endDate       = trim($request->input('end_date', '')) ?: null;
        $endTime       = trim($request->input('end_time', '')) ?: null;
        $mediaId       = (int) $request->input('media_id', 0) ?: null;
        $categoryId    = (int) $request->input('category_id', 0) ?: null;
        $isFeatured    = $request->input('is_featured') === '1' ? 1 : 0;
        $publishStatus = in_array($request->input('publish_status'), ['draft', 'published'], true)
                            ? $request->input('publish_status')
                            : 'draft';
        $eventStatus   = in_array($request->input('event_status'), ['scheduled', 'postponed', 'cancelled'], true)
                            ? $request->input('event_status')
                            : 'scheduled';

        return [
            'title'          => $title,
            'slug'           => $slug,
            'excerpt'        => $excerpt ?: null,
            'content'        => $content ?: null,
            'location'       => $location ?: null,
            'start_date'     => $startDate,
            'start_time'     => $startTime,
            'end_date'       => $endDate,
            'end_time'       => $endTime,
            'media_id'       => $mediaId,
            'category_id'    => $categoryId,
            'is_featured'    => $isFeatured,
            'publish_status' => $publishStatus,
            'event_status'   => $eventStatus,
        ];
    }
}
