<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\User;
use App\Models\Artist;
use App\Models\Artwork;
use App\Models\Episode;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Intervention\Image\Facades\Image;
use Carbon\Carbon;
use ImageOptimizer;

class StashAndOptimizeLegacyArtworkJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $artist;

    protected $artwork;

    public $tries = 2;

    /**
     * Create a new job instance.
     */
    public function __construct($artist, $artwork)
    {
        $this->artist = $artist;
        $this->artwork = $artwork;
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        $date = Carbon::parse($this->artwork->created_at);
        $basename = $date->format('Y') 
        . '/' . $date->format('m') 
        . '/' . Str::slug($this->artist->name) 
        . '-' . Str::slug($this->artwork->title) 
        . '_' . $this->artwork->id . '.jpg';
        $filename = 'artworks/' . $basename;
        $thumbnailName = 'thumbnails/' . $basename;
        if (Storage::disk('static')->exists($filename)) {
            Log::channel('artwork_import')->error($filename . ' already exists. Filesize: ' . Storage::disk('static')->size($filename));
            $this->createArtwork($basename);
            return;
        }
        $img = Image::make('/legacypublic' . $this->artwork->path . '/' . $this->artwork->filename)
            ->resize(3000, null, function ($constraint) {
                $constraint->aspectRatio();
            })
            ->encode('jpg', 100);
        $thumbImg = Image::make('/legacypublic' . $this->artwork->path . '/' . $this->artwork->filename)
            ->resize(512, null, function ($constraint) {
                $constraint->aspectRatio();
            })
            ->encode('jpg', 100);
        $imgLocation = Storage::disk('static')->put($filename, $img);
        $thumbLocation = Storage::disk('static')->put($thumbnailName, $thumbImg);
        $size_before = Storage::disk('static')->size($filename);
        $thumb_size_before = Storage::disk('static')->size($thumbnailName);
        ImageOptimizer::optimize(Storage::disk('static')->path($filename));
        ImageOptimizer::optimize(Storage::disk('static')->path($thumbnailName));
        $size_after = Storage::disk('static')->size($filename);
        $thumb_size_after = Storage::disk('static')->size($thumbnailName);
        $diff = $size_before - $size_after;
        $thumbDiff = $thumb_size_before - $thumb_size_after;
        Log::channel('artwork_import')->info('Filesize Before: ' . $size_before);
        Log::channel('artwork_import')->info('Filesize After: ' . $size_after);
        $perc_smaller = ($diff / $size_before) * 100;
        $thumb_perc_smaller = ($thumbDiff / $thumb_size_before) * 100;
        Log::channel('artwork_import')->info(number_format($perc_smaller, 2) . '% smaller.');
        Log::channel('artwork_import')->info(number_format($thumb_perc_smaller, 2) . '% smaller thumbnail - ' . $thumb_size_after);
        Log::channel('artwork_import')->info('Saved and resized ' . $filename);
        $this->createArtwork($basename);
    }

    private function createArtwork($basename) {
        $artwork = Artwork::where('legacy_id', $this->artwork->id)->first();
        if (!$this->artwork->episode_id) {
            $episode = Episode::where('episode_date', '>=', Carbon::parse($this->artwork->created_at)->startOfDay())
                ->orderBy('episode_date', 'asc')
                ->first();
        } else {
            $episode = Episode::where('legacy_id', $this->artwork->episode_id)->first();
        }
        if (!$artwork) {
            $artwork = Artwork::where('filename', $basename)->first();
            if ($artwork) {
                $artwork->legacy_id = $this->artwork->id;
                $artwork->episode_id = $episode->id ?? null;
                $artwork->save();
                return;
            }
        }
        if (!$artwork) {
            Log::channel('artwork_import')->info('making new artwork model for ' . $basename);
            Artwork::factory()->state([
                'title' => $this->artwork->title,
                'artist_id' => $this->artist->id,
                'description' => '',
                'podcast_id' => 1,
                'overlay_id' => $this->artwork->overlay_id,
                'episode_id' => $episode->id ?? null,
                'filename' => $basename ?? null,
                'created_at' => Carbon::parse($this->artwork->created_at),
                'updated_at' => Carbon::parse($this->artwork->updated_at),
                'legacy_id' => $this->artwork->id,
            ])->create();
        } else {
            Log::channel('artwork_import')->info($artwork->id . ' has a model it exists with ' . $artwork->filename);
        }
    }
}