<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Http\Requests\Event\RegisterEventRequest;
use App\Http\Resources\EventRegistrationResource;
use App\Http\Resources\EventResource;
use App\Models\Event;
use App\Models\EventCoTraveler;
use App\Models\EventRegistration;
use App\Models\EventWishlist;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class EventController extends Controller
{
    public function index(Request $request)
    {
        $query = Event::where('is_published', true);

        if ($request->filled('search')) {
            $query->where(function ($q) use ($request) {
                $q->where('name', 'like', '%' . $request->search . '%')
                  ->orWhere('destination', 'like', '%' . $request->search . '%');
            });
        }

        if ($request->filled('type')) {
            $query->whereIn('type', (array) $request->type);
        }

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        if ($request->filled('min_price')) {
            $query->where('price', '>=', (int) $request->min_price);
        }

        if ($request->filled('max_price')) {
            $query->where('price', '<=', (int) $request->max_price);
        }

        $events = $query->orderBy('is_featured', 'desc')
                        ->orderBy('start_date', 'asc')
                        ->paginate(15);

        // Attach is_wishlisted flag when user is authenticated
        if ($request->user()) {
            $wishlistedIds = EventWishlist::where('user_id', $request->user()->id)
                ->pluck('event_id')
                ->flip();

            $events->getCollection()->transform(function ($event) use ($wishlistedIds) {
                $event->is_wishlisted = $wishlistedIds->has($event->id);
                return $event;
            });
        }

        return $this->paginated($events, EventResource::class);
    }

    public function featured(Request $request)
    {
        $events = Event::where('is_published', true)
            ->where('is_featured', true)
            ->where('status', '!=', 'past')
            ->orderBy('start_date', 'asc')
            ->limit(10)
            ->get();

        return $this->success(EventResource::collection($events));
    }

    public function past(Request $request)
    {
        $events = Event::where('is_published', true)
            ->where('status', 'past')
            ->orderBy('start_date', 'desc')
            ->paginate(15);

        return $this->paginated($events, EventResource::class);
    }

    public function show(Request $request, Event $event)
    {
        if (! $event->is_published) {
            return $this->notFound('Event not found.');
        }

        // Attach is_wishlisted when authenticated
        if ($request->user()) {
            $event->is_wishlisted = EventWishlist::where('user_id', $request->user()->id)
                ->where('event_id', $event->id)
                ->exists();
        }

        return $this->success(new EventResource($event));
    }

    public function register(RegisterEventRequest $request, Event $event)
    {
        if (! $event->is_published || $event->status === 'past') {
            return $this->error('Registration is not available for this event.', 422);
        }

        if ($event->status === 'sold_out') {
            return $this->error('This event is sold out.', 422);
        }

        $existing = EventRegistration::where('user_id', $request->user()->id)
            ->where('event_id', $event->id)
            ->where('status', '!=', 'cancelled')
            ->first();

        if ($existing) {
            return $this->error('You are already registered for this event.', 422);
        }

        $registration = EventRegistration::create([
            'user_id'             => $request->user()->id,
            'event_id'            => $event->id,
            'registration_number' => 'FH-' . date('Y') . '-' . strtoupper(Str::random(6)),
            'status'              => 'registered',
            'special_requests'    => $request->special_requests,
            'registered_at'       => now(),
        ]);

        if ($request->filled('co_travelers')) {
            $coTravelers = collect($request->co_travelers)->map(fn ($ct) => [
                'registration_id' => $registration->id,
                'name'            => $ct['name'],
                'its_number'      => $ct['its_number'] ?? null,
                'relationship'    => $ct['relationship'] ?? null,
                'created_at'      => now(),
                'updated_at'      => now(),
            ])->all();

            EventCoTraveler::insert($coTravelers);
        }

        if ($event->spots_remaining !== null && $event->spots_remaining > 0) {
            $event->decrement('spots_remaining');

            if ($event->spots_remaining === 0) {
                $event->update(['status' => 'sold_out']);
            } elseif ($event->spots_remaining <= 5) {
                $event->update(['status' => 'limited']);
            }
        }

        return $this->created(
            new EventRegistrationResource($registration->load('coTravelers', 'event')),
            'Registration successful.'
        );
    }

    public function myRegistration(Request $request, Event $event)
    {
        $registration = EventRegistration::where('user_id', $request->user()->id)
            ->where('event_id', $event->id)
            ->with('coTravelers', 'event')
            ->first();

        if (! $registration) {
            return $this->notFound('No registration found for this event.');
        }

        return $this->success(new EventRegistrationResource($registration));
    }

    public function cancelRegistration(Request $request, Event $event)
    {
        $registration = EventRegistration::where('user_id', $request->user()->id)
            ->where('event_id', $event->id)
            ->where('status', '!=', 'cancelled')
            ->firstOrFail();

        $registration->update(['status' => 'cancelled']);

        if ($event->spots_remaining !== null) {
            $event->increment('spots_remaining');

            if ($event->status === 'sold_out') {
                $event->update(['status' => 'limited']);
            }
        }

        return $this->success(null, 'Registration cancelled successfully.');
    }

    public function toggleWishlist(Request $request, Event $event)
    {
        if (! $event->is_published) {
            return $this->notFound('Event not found.');
        }

        $wishlist = EventWishlist::where('user_id', $request->user()->id)
            ->where('event_id', $event->id)
            ->first();

        if ($wishlist) {
            $wishlist->delete();
            return $this->success(['wishlisted' => false], 'Removed from wishlist.');
        }

        EventWishlist::create([
            'user_id'  => $request->user()->id,
            'event_id' => $event->id,
        ]);

        return $this->success(['wishlisted' => true], 'Added to wishlist.');
    }

    public function wishlist(Request $request)
    {
        $wishlistedIds = EventWishlist::where('user_id', $request->user()->id)
            ->pluck('event_id')
            ->flip();

        $events = Event::whereIn('id', $wishlistedIds->keys())
            ->where('is_published', true)
            ->orderBy('start_date', 'asc')
            ->get()
            ->each(fn ($e) => $e->is_wishlisted = true);

        return $this->success(EventResource::collection($events));
    }
}
