<?php

namespace App\Http\Controllers;

use App\Jobs\ResizeImage;
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\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use phpDocumentor\Reflection\Types\Integer;

class PublicController extends BaseController
{

    public static $size = ["pixel" => 100, "small" => 300, "medium" => 600, "big" => 1200];

    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    public function listGalleriesView($name) {
        $tenant = Tenant::query()->where("url", "=", $name)->firstOrFail();
        $galleries = Gallery::query()
            ->where("tenant", "=", $tenant->id)
            ->where("status", "=", "online")
            ->where("listed", "=", 1)
            ->orderByDesc("gallery_create_time")
            ->orderByDesc("created_at")
            ->get();
        $parser = new \Parsedown();
        foreach ($galleries as $gallery) {
            $gallery->html = $parser->parse($gallery->description);
        }
        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);
        if($gallery->status == "online" || (Auth::check() && $gallery->status == "preview" && Auth::user()->id == $tenant->owner)) {
            $images = Image::query()
                ->where("gallery", "=", $gallery->id)
                ->whereNull("deleted_at")
                ->orderBy("rating")
                ->orderBy("DateTimeOriginal")
                ->get();
        } else {
            abort( 404);
        }

        $parser = new \Parsedown();
        $gallery->html = $parser->parse($gallery->description);

        return view("themes.gallery.gallery-detail.list", ["gallery" => $gallery, "tenant" => $tenant, "images" => $images]);
    }

    public function returnImageFile($tenant_url, $gallery_url, $image_id, Request $request) {
        $sizeName = $request->input("size", "medium");
        if(!array_key_exists($sizeName, self::$size)) {
            abort(400, "Size not exists");
        }
        $size = (int)self::$size[$sizeName];

        $image = Image::query()->where("id", "=", $image_id)->firstOrFail();
        $gallery = Gallery::query()->where("url", "=", $gallery_url)->firstOrFail();
        $tenant = Tenant::query()->where("url", "=", $tenant_url)->firstOrFail();
        if($image->gallery != $gallery->id) {
            abort(404, "Gallery not match");
        }

        if($gallery->tenant != $tenant->id) {
            abort(404, "Tenant not match");
        }

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

        //Check if exsits in cache and return from it
        $r = $this->tryReturnFromCache($cacheName."_".$size, $tenant->id, $gallery->id, $image->id);
        if($r != null) {
            return $r;
        }


        //Return from s3, takes a loooong time
        ResizeImage::dispatchSync($image->id, $size);

        $r = $this->tryReturnFromCache($cacheName."_".$size, $tenant->id, $gallery->id, $image->id);
        if($r != null) {
            return $r;
        }

        return abort(500, "Something go wrong");

    }

    private function tryReturnFromCache($cacheName, $tenant_id, $gallery_id, $image_id) {
        if(Storage::disk('cache')->exists($cacheName)) {
            $this->addAccessLog($tenant_id, $gallery_id, $image_id, "Cache", Storage::disk('cache')->size($cacheName));
            return Storage::disk('cache')->response($cacheName, null, ['Cache-Control'=> 'max-age='.(60*60*24).', public']);
        }
        return null;
    }


    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();
    }
}
