<?php
namespace App\Helper;

use App\Entity\File;
use App\Models\Gallery;
use App\Models\Tenant;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class  Image {
    /*
     * @var \App\Helper\ImagePreparation $imagePreparation
     */
    private $imagePreparation;

    /*
     * @var \App\Helper\Access $access
     */
    private $access;



    public function __construct(ImagePreparation $imagePreparation, Access $access)
    {
        Log::info("Create Image Helper Class");
        $this->imagePreparation = $imagePreparation;
        $this->access = $access;
    }

    public function getImageById(int $id, ?int $size) : File {
        Log::info("Get Image by id",  ["id" => $id, "size" => $size]);
        $image = \App\Models\Image::query()->where("id", "=", $id)->firstOrFail();
        return $this->getImage($image, $size);
    }

    public function validateGalleryAndTenant(\App\Models\Image $image, string $gallery_url, string $tenant_url) : bool
    {
        $res = DB::select("SELECT `galleries`.`url` AS 'gallery_url', `tenants`.`url` AS 'tenant_url' FROM images LEFT JOIN `galleries` ON `images`.`gallery` = `galleries`.`id` LEFT JOIN `tenants` ON `tenants`.`id` = `galleries`.`tenant` WHERE `images`.`id` = ".$image->id.";");
        if($res[0]->gallery_url == $gallery_url && $res[0]->tenant_url == $tenant_url) {
            return true;
        }
        return false;
    }

    public function getImage(\App\Models\Image $image, ?int $size) : File {
        $cacheName = $this->getCachePath($image, $size);
        Log::info("Get Image", ["id" => $image->id, "size" => $size, "cachename" => $cacheName]);

        if(Storage::disk("cache")->exists($cacheName) && $image->refreshCache == false) {
            Log::info("Found Image on Cache", ["id" => $image->id, "size" => $size, "cachename" => $cacheName]);
            return new File("cache", $cacheName);
        }

        $file = $this->getRawImage($image);
        $gallery = Gallery::query()->where("id", "=", $image->gallery)->firstOrFail();
        $tenant = Tenant::query()->where("id", "=", $gallery->tenant)->firstOrFail();

        $watermarkFile = null;
        if(!is_null($tenant->watermark)) {
            Log::info("Image has Watermark", ["id" => $image->id, "size" => $size, "cachename" => $cacheName]);
            $watermarkModel = \App\Models\Image::query()->where("id", "=", $tenant->watermark)->firstOrFail();
            $watermarkFile = $this->getRawImage($watermarkModel, true);
        }

        $jpg = $this->imagePreparation->prepare($file, $size, $watermarkFile);

        Storage::disk("cache")->put($cacheName, $jpg);

        $image->refreshCache = false;
        $image->saveOrFail();

        $file = new File("cache", $cacheName);
        $file->setContent($jpg);
        unset($jpg);

        return $file;
    }

    public function getRawImage(\App\Models\Image $image, bool $cache = null): File {
        $cacheName = $this->getCachePath($image, null);
        if(Storage::disk("cache")->exists($cacheName)) {
            Log::info("Get RAW-Image File from cache", ["image_id" => $image->id]);
            return new File("cache", $cacheName);
        }

        if($cache === true || is_null($cache)) {
            Log::info("Get RAW-Image File from s3", ["image_id" => $image->id]);
            $content = Storage::disk($image->driver)->get($image->path);
            Storage::disk("cache")->put($cacheName, $content);
            $file = new File("cache", $cacheName);
            $this->access->add($image, $file, Access::TYPE_S3);
            $file->setContent($content);
            return $file;
        }

        return new File($image->driver, $image->path);
    }




    public function getCachePath(\App\Models\Image $image, ?int $size): string
    {
        if(is_null($size)) {
            $size = "orginal";
        }
        $cacheName = $image->id."_".$size."_".$image->filename;
        return $cacheName;
    }
}
