<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Media;
use Intervention\Image\ImageManager;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Encoders\WebpEncoder;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;

use App\Http\Resources\Media as MediaCollection;

class MediaController extends Controller
{

    public function index(Request $request)
    {
        try {
            $limit = $request->query('limit', 40);
            if($request->media_source == 'mymedia'){
                $media = Media::where('user_id',$request->user()->id)->paginate($limit);
            }else{
                $media = Media::paginate($limit);
            }
            
           // $specificationCollection = SpecificationCollection::collection($specification->items());
            $responseData = [
                'records' => MediaCollection::collection($media->items()),
                'pagination' => [
                    'current_page' => $media->currentPage(),
                    'last_page' => $media->lastPage(),
                    'per_page' => $media->perPage(),
                    'total' => $media->total(),
                ],
            ];

            return response()->json($responseData);
        } catch (QueryException $e) {
            return response()->json(['message' => 'Database error: ' . $e->getMessage()], 500);
        } catch (\Exception $e) {
            return response()->json(['message' => 'An unexpected error occurred: ' . $e->getMessage()], 500);
        }
    }

    public function upload(Request $request)
    {
        $request->validate([
            'files.*' => 'required|file|max:20480', // 20MB max file size
        ]);

        $files = $request->file('files');
        $responses = [];

        foreach ($files as $file) {
            $responses[] = $this->handleFileUpload($request, $file);
        }

        return response()->json([$responses]);
    }

    private function handleFileUpload($request, $file)
    {
        $originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
        $extension = $file->getClientOriginalExtension();
        $year = date('Y');
        $month = date('m');

        // Create directories
        $directory = "public/$year/$month";
        $webpDirectory = "public/$year/$month/webp";
        $thumbnailDirectory = "public/$year/$month/thumbnail";
        Storage::makeDirectory($directory);
        Storage::makeDirectory($webpDirectory);
        Storage::makeDirectory($thumbnailDirectory);

        // Check if the file exists and append counter if necessary
        $filename = $this->generateUniqueFilename($directory, $originalFilename, $extension);

        // Save original file
        $originalPath = $file->storeAs($directory, $filename . '.' . $extension);
        $thumbPath = null;
        $webpPath = null;

       // return $originalPath;
        if (in_array($extension, ['jpg', 'jpeg', 'png','webp'])) {
            // Convert to webP and resize if necessary

            if (!file_exists(storage_path("app/$originalPath"))) {
                return "File not found: ".storage_path("app/$originalPath");
            }

            $absolutePath = storage_path("app/$originalPath");
            $manager = new ImageManager(Driver::class);// Uses the default driver configuration

            $image = $manager->read($absolutePath); // Load the image
    
            if ($image->width() > 1920) {
                $image->scaleDown(width: 1920);
            }
    
            $webpPath = "$directory/webp/$filename.webp";
    
            // Encode the image to webp format
            $image->encode(new WebpEncoder(quality: 60))->save(storage_path("app/$webpPath"));
    
            //return "Image successfully converted and saved to $webpPath";


            // Create thumbnail
            $thumbnail = $manager->read($absolutePath);
            $thumbnail->cover(300, 300, 'center');
            $thumbPath = "$directory/thumbnail/$filename-thumb.webp";
            $thumbnail->encode(new WebpEncoder(quality: 60))->save(storage_path("app/$thumbPath"));
            $thumbFileSize = filesize(storage_path("app/$thumbPath"));
            $webPFileSize =  filesize(storage_path("app/$webpPath"));

        }else{

            if (!file_exists(storage_path("app/$originalPath"))) {
                return "File not found: ".storage_path("app/$originalPath");
            }
            $absolutePath = storage_path("app/$originalPath");
            $webpPath = $directory.'/'.$filename.'.'.$extension;
            $thumbPath = $directory.'/'.$filename.'.'.$extension;
            $thumbFileSize = filesize(storage_path("app/$originalPath"));
            $webPFileSize =  filesize(storage_path("app/$originalPath"));
        }

        // Store metadata
       $media = Media::create([
            'name' => $filename,
            'path' => $originalPath,
            'orignal_size' => $file->getSize(),
            'thumb_path' => $thumbPath,
            'thumb_size' => $thumbFileSize,
            'user_id' => $request->user()->id,
            'webp_path' => $webpPath,
            'webp_size' => $webPFileSize,

            'type' => $file->getClientMimeType(),
        ]);

        $media = [
            'id' => $media->id,
            'name' => $media->name,
            'path' => url(Storage::url($media->path)),
            'orignal_size' => $media->orignal_size,
            'thumb_path' => $media->thumb_path ? url(Storage::url($media->thumb_path)) : null,
            'thumb_size' => $media->thumb_size,
            'webp_path' => $media->webp_path ? url(Storage::url($media->webp_path)) : null,
            'webp_size' => $media->webp_size,
            'uploaded_at' => $media->created_at,
            'message' => "Files has uploaded."
        ];

        return response()->json(['message' => 'Files has Uploaded.', 'record' => $media], 200); 
    }

    private function generateUniqueFilename($directory, $filename, $extension)
    {
        $counter = 1;
        $uniqueFilename = $filename;

        while (Storage::exists("$directory/$uniqueFilename.$extension")) {
            $uniqueFilename = $filename . '-' . $counter;
            $counter++;
        }

        return $uniqueFilename;
    }

    public function show($id)
    {
        $media = Media::findOrFail($id);

        return response()->json([
            'id' => $media->id,
            'name' => $media->name,
            'path' => Storage::url($media->path),
            'thumb_path' => $media->thumb_path ? Storage::url($media->thumb_path) : null,
            'webp_path' => $media->webp_path ? Storage::url($media->webp_path) : null,
            'size' => $media->size,
            'uploaded_at' => $media->created_at,
        ]);
    }

    public function delete($id)
    {
        $ids = explode(",",$id);
        $mediaItems = Media::whereIn('id', $ids)->get();

        foreach ($mediaItems as $media) {
            // Delete the files from storage
            Storage::delete($media->path);
            Storage::delete($media->thumb_path);
            Storage::delete($media->webp_path);

            // Delete the media record from the database
            $media->delete();
        }

        return response()->json(['message' => 'Media deleted successfully']);
    }



    public function selectedImage(Request $request)
    {
        try {
            if(is_array($request->ids)){
                $media = Media::whereIn('id', $request->ids)->get();
                return response()->json(['records' => MediaCollection::collection($media)]);
            }else{
                $media = Media::findOrFail($request->ids);
                return response()->json(['records' =>  [new MediaCollection($media)]]);
            }
            
        } catch (QueryException $e) {
            return response()->json(['message' => 'Database error: ' . $e->getMessage()], 500);
        } catch (\Exception $e) {
            return response()->json(['message' => 'An unexpected error occurred: ' . $e->getMessage()], 500);
        }
    }


}
