<?php

namespace App\Http\Controllers;

use App\Models\Access;
use App\Models\Gallery;
use App\Models\Image;
use App\Models\Tenant;
use Gumlet\ImageResize;
use Illuminate\Http\Request;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use phpDocumentor\Reflection\Types\Integer;

class PublicController extends BaseController
{

    const SIZE_SMALL = 300;
    const SIZE_MEDIUM = 600;
    const SIZE_BIG = 1200;
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    public function listGalleriesView($name) {
        $tenant = Tenant::query()->where("url", "=", $name)->firstOrFail();
        $galleries = Gallery::query()->where("tenant", "=", $tenant->id)->get();
        return view("themes.tenant.kuvia-blog.list", ["galleries" => $galleries, "tenant" => $tenant]);
    }

    public function listGalleryImagesView($tenant, $gallery) {
        $tenant = Tenant::query()->where("url", "=", $tenant)->firstOrFail();
        $gallery = Gallery::getByTenantAndUrl($tenant->id, $gallery);
        $images = Image::query()->where("gallery", "=", $gallery->id)->get();
        return view("themes.gallery.gallery.list", ["gallery" => $gallery, "tenant" => $tenant, "images" => $images]);
    }

    public function returnImageFile2($tenant, $gallery, $image, Request $request) {
        $image = Image::query()->where("id", "=", $image)->firstOrFail();
        $size = $request->input("size", "medium");
        $file = Storage::disk($image->driver)->response($image->path);
        return $file;
    }

    public function returnImageFile($tenant, $gallery, $image, Request $request) {
        $uid = uniqid();
        Log::info($uid.": Start", [$image]);
        $globalstart = microtime(true);
        $tenant = Tenant::query()->where("url", "=", $tenant)->firstOrFail();
        $gallery = Gallery::getByTenantAndUrl($tenant->id, $gallery);
        $image = Image::query()->where("gallery", "=", $gallery->id)->where("id", "=", $image)->firstOrFail();
        $size = $request->input("size", "medium");
        //$size = "medium";

        $cacheName = "cache/".$tenant->id."_".$gallery->id."_".$image->id;

        //File exists in the right size
        if (Storage::disk('cache')->exists($cacheName."_".$size)) {
            $this->addAccessLog($tenant->id, $gallery->id, $image->id, "Cache", Storage::disk('cache')->size($cacheName."_".$size));
            Log::info($uid.": Return ".$size." from Cache, Gesamtzeit: ".(microtime(true)-$globalstart), [$image->id]);
            return Storage::disk('cache')->response($cacheName."_".$size, null, ['Cache-Control'=> 'max-age='.(60*60*24).', public']);
        }

        //If File exists in the needed format return
        $file = null;
        if (Storage::disk('cache')->exists($cacheName."_orginal")) {
            $file = Storage::disk("cache")->get($cacheName."_orginal");
        } else {
            Log::info("Get from S3");
            $start = microtime(true);
            $this->addAccessLog($tenant->id, $gallery->id, $image->id, "Access", $image->size);
            $file = Storage::disk($image->driver)->get($image->path);
            Storage::disk("cache")->put($cacheName."_orginal", $file);
            Log::info("Dauer s3: ".(microtime(true) - $start), [$image->filename]);
        }

        //Resize
        if($size == "small") {
            $start = microtime(true);
            $image = ImageResize::createFromString($file);
            $image->resizeToLongSide(self::SIZE_SMALL);
            Storage::disk("cache")->put($cacheName."_small", $image->getImageAsString());
            $ende = microtime(true);
            Log::info("Dauer umwandlung small: ".($ende-$start). "/" . "Gesamtzeit: ".(microtime(true)-$globalstart));
            return Storage::disk('cache')->response($cacheName."_small");
        }
        if($size == "medium") {
            $start = microtime(true);
            $image = ImageResize::createFromString($file);
            $image->resizeToLongSide(self::SIZE_MEDIUM);
            Storage::disk("cache")->put($cacheName."_medium", $image->getImageAsString());
            $ende = microtime(true);
            Log::info("Dauer umwandlung medium: ".($ende-$start). "/" . "Gesamtzeit: ".(microtime(true)-$globalstart));
            return Storage::disk('cache')->response($cacheName."_medium");
        }

        if($size == "big") {
            $start = microtime(true);
            $image = ImageResize::createFromString($file);
            $image->resizeToLongSide(self::SIZE_BIG);
            Storage::disk("cache")->put($cacheName."_big", $image->getImageAsString());
            $ende = microtime(true);
            Log::info("Dauer umwandlung big: ".($ende-$start). "/" . "Gesamtzeit: ".(microtime(true)-$globalstart));
            return Storage::disk('cache')->response($cacheName."_big");
        }


       return abort(500);
    }
    private function addAccessLog(int $tenant, int $gallery, int $image, string $typ, int $size) {
        $access = new Access();
        $access->year = date("Y");
        $access->month = date("m");
        $access->day = date("d");
        $access->hour = date("H");
        $access->image = $image;
        $access->gallery = $gallery;
        $access->tenant = $tenant;
        $access->typ = $typ;
        $access->size = $size;
        $access->saveOrFail();
    }
}
