<?php

namespace App\Http\Controllers;

use App\Models\Park;
use App\Models\Photo;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\ImageManager;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Encoders\JpegEncoder;
use Illuminate\Support\Str;

class PhotoController extends Controller
{
    /**
     * Display a listing of the photos for a park.
     */
    public function index(Park $park)
    {
        $photos = $park->photos()->ordered()->get();
        
        return response()->json([
            'photos' => $photos,
            'featured_photo' => $park->featuredPhoto(),
        ]);
    }

    /**
     * Store a newly uploaded photo.
     */
    public function store(Request $request, Park $park)
    {
        $request->validate([
            'photo' => 'required|image|max:10240', // 10MB max
            'title' => 'nullable|string|max:255',
            'description' => 'nullable|string',
            'alt_text' => 'nullable|string|max:255',
            'credit' => 'nullable|string|max:255',
            'source_url' => 'nullable|url|max:255',
            'is_featured' => 'nullable|boolean',
        ]);

        // Handle file upload
        if ($request->hasFile('photo')) {
            $file = $request->file('photo');
            $originalFilename = $file->getClientOriginalName();
            $extension = $file->getClientOriginalExtension();
            
            // Generate a unique filename
            $filename = time() . '_' . Str::slug(pathinfo($originalFilename, PATHINFO_FILENAME)) . '.' . $extension;
            
            // Define the storage path
            $storagePath = 'photos/parks/' . $park->id;
            $fullPath = $storagePath . '/' . $filename;
            
            // Store the original file
            $file->storeAs('public/' . $storagePath, $filename);
            
            // Create image manager instance
            $manager = new ImageManager(new Driver());
            
            // Get image dimensions
            $image = $manager->read($file);
            $width = $image->width();
            $height = $image->height();
            
            // Generate thumbnail
            $thumbnailFilename = pathinfo($filename, PATHINFO_FILENAME) . '_thumb.' . $extension;
            $thumbnail = $manager->read($file)->scaleDown(width: 300, height: 300);
            
            // Save thumbnail
            $encodedThumbnail = $thumbnail->encode(
                new JpegEncoder(80)
            );
            Storage::put(
                'public/' . $storagePath . '/' . $thumbnailFilename,
                $encodedThumbnail->toString()
            );
            
            // Create photo record
            $photo = $park->addPhoto([
                'title' => $request->input('title'),
                'description' => $request->input('description'),
                'file_path' => $fullPath,
                'file_name' => $originalFilename,
                'file_size' => $file->getSize(),
                'mime_type' => $file->getMimeType(),
                'width' => $width,
                'height' => $height,
                'alt_text' => $request->input('alt_text'),
                'credit' => $request->input('credit'),
                'source_url' => $request->input('source_url'),
                'is_featured' => $request->input('is_featured', false),
            ]);
            
            return response()->json([
                'message' => 'Photo uploaded successfully',
                'photo' => $photo,
            ], 201);
        }
        
        return response()->json([
            'message' => 'No photo file provided',
        ], 400);
    }

    /**
     * Display the specified photo.
     */
    public function show(Photo $photo)
    {
        return response()->json($photo);
    }

    /**
     * Update the specified photo.
     */
    public function update(Request $request, Photo $photo)
    {
        $request->validate([
            'title' => 'nullable|string|max:255',
            'description' => 'nullable|string',
            'alt_text' => 'nullable|string|max:255',
            'credit' => 'nullable|string|max:255',
            'source_url' => 'nullable|url|max:255',
            'is_featured' => 'nullable|boolean',
        ]);
        
        $photo->update($request->only([
            'title', 'description', 'alt_text', 'credit', 'source_url'
        ]));
        
        // Handle featured status
        if ($request->has('is_featured') && $request->input('is_featured')) {
            $photo->setAsFeatured();
        }
        
        return response()->json([
            'message' => 'Photo updated successfully',
            'photo' => $photo,
        ]);
    }

    /**
     * Remove the specified photo.
     */
    public function destroy(Photo $photo)
    {
        // Get the file paths
        $filePath = 'public/' . $photo->file_path;
        $pathInfo = pathinfo($photo->file_path);
        $thumbnailPath = 'public/' . $pathInfo['dirname'] . '/' . $pathInfo['filename'] . '_thumb.' . $pathInfo['extension'];
        
        // Delete the files
        Storage::delete([$filePath, $thumbnailPath]);
        
        // Delete the record
        $photo->delete();
        
        return response()->json([
            'message' => 'Photo deleted successfully',
        ]);
    }

    /**
     * Reorder photos for a park.
     */
    public function reorder(Request $request, Park $park)
    {
        $request->validate([
            'photo_ids' => 'required|array',
            'photo_ids.*' => 'required|integer|exists:photos,id',
        ]);
        
        $success = $park->reorderPhotos($request->input('photo_ids'));
        
        if ($success) {
            return response()->json([
                'message' => 'Photos reordered successfully',
            ]);
        }
        
        return response()->json([
            'message' => 'Failed to reorder photos',
        ], 500);
    }

    /**
     * Set a photo as featured.
     */
    public function setFeatured(Request $request, Park $park, Photo $photo)
    {
        if ($photo->photoable_id !== $park->id || $photo->photoable_type !== Park::class) {
            return response()->json([
                'message' => 'Photo does not belong to this park',
            ], 400);
        }
        
        $success = $park->setFeaturedPhoto($photo);
        
        if ($success) {
            return response()->json([
                'message' => 'Featured photo set successfully',
            ]);
        }
        
        return response()->json([
            'message' => 'Failed to set featured photo',
        ], 500);
    }
}