<?php

namespace App\Http\Controllers\Media;

use App\Http\Controllers\Controller;
use App\Models\Gallery;
use App\Models\GalleryImage;
use App\Models\Organization;
use App\Models\GalleryType;
use App\Http\Requests\StoreGalleryRequest;
use App\Http\Requests\UpdateGalleryRequest;
use App\Http\Requests\UploadGalleryImageRequest;
use App\Services\GalleryService;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\View\View;

/**
 * GalleryController
 *
 * Handles CRUD operations for galleries and gallery images.
 * Manages gallery creation, image uploads, editing, and deletion.
 * Permission-gated for managers, trainers, and super managers.
 */
class GalleryController extends Controller
{
    public function __construct(protected GalleryService $galleryService) {}

    /**
     * Display a listing of galleries for an organization.
     */
    public function index(Request $request): View
    {
        abort_unless(auth()->user()->can('view galleries'), 403,
            'You do not have permission to view galleries.');

        $organizations = Organization::orderBy('name')->get();
        $galleryTypes = GalleryType::active()->ordered()->get();

        $query = Gallery::with(['organization', 'type', 'creator', 'images' => function ($q) {
            $q->limit(1);
        }])->withCount('images');

        // Filter by organization
        if ($request->filled('organization_id')) {
            $query->ofOrganization($request->organization_id);
        }

        // Filter by gallery type
        if ($request->filled('gallery_type_id')) {
            $query->ofType($request->gallery_type_id);
        }

        // Filter by publication status
        if ($request->filled('is_published')) {
            $published = $request->is_published === '1';
            $query->where('is_published', $published);
        }

        // Search
        if ($request->filled('search')) {
            $query->search($request->search);
        }

        $galleries = $query->ordered()->paginate(12);

        return view('media.galleries.index', compact(
            'galleries',
            'organizations',
            'galleryTypes'
        ));
    }

    /**
     * Show the form for creating a new gallery.
     */
    public function create(Request $request): View
    {
        abort_unless(auth()->user()->can('create galleries'), 403,
            'You do not have permission to create galleries.');

        $organizations = Organization::orderBy('name')->get();
        $galleryTypes = GalleryType::active()->ordered()->get();

        // Pre-select organization if provided
        $selectedOrganization = $request->filled('organization_id') ? $request->organization_id : null;

        return view('media.galleries.create', compact(
            'organizations',
            'galleryTypes',
            'selectedOrganization'
        ));
    }

    /**
     * Store a newly created gallery in storage.
     */
    public function store(StoreGalleryRequest $request): RedirectResponse
    {
        $organizationId = $request->input('organization_id');
        $gallery = $this->galleryService->createGallery(
            $organizationId,
            $request->validated(),
            auth()->id()
        );

        return redirect()
            ->route('media.galleries.show', $gallery)
            ->with('success', 'Gallery created successfully!');
    }

    /**
     * Display the specified gallery with images.
     */
    public function show(Gallery $gallery): View
    {
        abort_unless(auth()->user()->can('view galleries'), 403,
            'You do not have permission to view galleries.');

        $gallery->load([
            'organization',
            'type',
            'creator',
            'images' => function ($query) {
                $query->ordered();
            }
        ]);

        return view('media.galleries.show', compact('gallery'));
    }

    /**
     * Show the form for editing the specified gallery.
     */
    public function edit(Gallery $gallery): View
    {
        abort_unless(auth()->user()->can('edit galleries'), 403,
            'You do not have permission to edit galleries.');

        $organizations = Organization::orderBy('name')->get();
        $galleryTypes = GalleryType::active()->ordered()->get();

        return view('media.galleries.edit', compact(
            'gallery',
            'organizations',
            'galleryTypes'
        ));
    }

    /**
     * Update the specified gallery in storage.
     */
    public function update(UpdateGalleryRequest $request, Gallery $gallery): RedirectResponse
    {
        $this->galleryService->updateGallery($gallery, $request->validated(), auth()->id());

        return redirect()
            ->route('media.galleries.show', $gallery)
            ->with('success', 'Gallery updated successfully!');
    }

    /**
     * Remove the specified gallery from storage.
     */
    public function destroy(Gallery $gallery): RedirectResponse
    {
        abort_unless(auth()->user()->can('delete galleries'), 403,
            'You do not have permission to delete galleries.');

        $this->galleryService->deleteGallery($gallery);

        return redirect()
            ->route('media.galleries.index')
            ->with('success', 'Gallery and all its images have been deleted successfully!');
    }

    /**
     * Upload images to a gallery.
     */
    public function uploadImages(UploadGalleryImageRequest $request, Gallery $gallery): RedirectResponse
    {
        abort_unless(auth()->user()->can('upload gallery images'), 403,
            'You do not have permission to upload gallery images.');

        $validated = $request->validated();
        $files = $validated['images'];
        $titles = $validated['titles'];
        $descriptions = $validated['descriptions'] ?? [];

        try {
            $this->galleryService->uploadMultipleImages(
                $gallery,
                $files,
                $titles,
                $descriptions,
                auth()->id()
            );

            return redirect()
                ->route('media.galleries.show', $gallery)
                ->with('success', 'Images uploaded successfully!');
        } catch (\Exception $e) {
            return redirect()
                ->route('media.galleries.show', $gallery)
                ->with('error', 'Image upload failed: ' . $e->getMessage());
        }
    }

    /**
     * Update image metadata (title, description).
     */
    public function updateImage(Request $request, GalleryImage $image): JsonResponse
    {
        abort_unless(auth()->user()->can('edit gallery images'), 403,
            'You do not have permission to edit gallery images.');

        $validated = $request->validate([
            'title'       => 'required|string|max:191',
            'description' => 'nullable|string|max:1000',
        ]);

        try {
            $this->galleryService->updateImage($image, $validated);

            return response()->json([
                'success' => true,
                'message' => 'Image metadata updated successfully!',
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update image: ' . $e->getMessage(),
            ], 422);
        }
    }

    /**
     * Delete an image from a gallery.
     */
    public function deleteImage(GalleryImage $image): RedirectResponse
    {
        abort_unless(auth()->user()->can('delete gallery images'), 403,
            'You do not have permission to delete gallery images.');

        $gallery = $image->gallery;

        try {
            $this->galleryService->deleteGalleryImage($image);

            return redirect()
                ->route('media.galleries.show', $gallery)
                ->with('success', 'Image deleted successfully!');
        } catch (\Exception $e) {
            return redirect()
                ->route('media.galleries.show', $gallery)
                ->with('error', 'Failed to delete image: ' . $e->getMessage());
        }
    }

    /**
     * Reorder images in a gallery.
     */
    public function reorderImages(Request $request, Gallery $gallery): JsonResponse
    {
        abort_unless(auth()->user()->can('edit galleries'), 403,
            'You do not have permission to reorder images.');

        $validated = $request->validate([
            'image_ids' => 'required|array',
            'image_ids.*' => 'required|integer|exists:gallery_images,id',
        ]);

        try {
            $this->galleryService->reorderImages($gallery, $validated['image_ids']);

            return response()->json([
                'success' => true,
                'message' => 'Images reordered successfully!',
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to reorder images: ' . $e->getMessage(),
            ], 422);
        }
    }

    /**
     * Publish a gallery.
     */
    public function publish(Gallery $gallery): RedirectResponse
    {
        abort_unless(auth()->user()->can('edit galleries'), 403);

        $this->galleryService->publishGallery($gallery, true, auth()->id());

        return redirect()
            ->route('media.galleries.show', $gallery)
            ->with('success', 'Gallery published successfully!');
    }

    /**
     * Unpublish a gallery.
     */
    public function unpublish(Gallery $gallery): RedirectResponse
    {
        abort_unless(auth()->user()->can('edit galleries'), 403);

        $this->galleryService->publishGallery($gallery, false, auth()->id());

        return redirect()
            ->route('media.galleries.show', $gallery)
            ->with('success', 'Gallery unpublished successfully!');
    }
}
