<?php

namespace App\Jobs\Tasks;

use App\Helpers\FirstParty\OSSUploader\OSSUploader;
use App\Helpers\ThirdParty\DFS\SettingSerpLiveAdvanced;
use App\Jobs\PublishIndexPostJob;
use App\Models\NewsSerpResult;
use DFSClientV3\DFSClient;
use Exception;
use Illuminate\Support\Facades\Http;
use Image;

class GenerateArticleFeaturedImageTask
{
    public static function handle($post)
    {
        $keyword = $post->main_keyword;

        if (is_array($post->keywords)) {
            if (count($post->keywords) > 0) {
                $keyword .= ' '.implode(' ', $post->keywords);
            }
        }

        $title = $post->short_title;
        $article_type = $post->type;
        $country_iso = 'US';
        $country_name = get_country_name_by_iso($country_iso);

        $images = [];

        $client = new DFSClient(
            config('dataforseo.login'),
            config('dataforseo.password'),
            config('dataforseo.timeout'),
            config('dataforseo.api_version'),
            config('dataforseo.url'),
        );

        // You will receive SERP data specific to the indicated keyword, search engine, and location parameters
        $serp_model = new SettingSerpLiveAdvanced();

        $serp_model->setSe('google');
        $serp_model->setSeType('images');
        $serp_model->setKeyword($keyword);
        $serp_model->setLocationName($country_name);
        $serp_model->setDepth(100);
        $serp_model->setLanguageCode('en');
        $serp_res = $serp_model->getAsJson();

        // try {
        $serp_obj = json_decode($serp_res, false, 512, JSON_THROW_ON_ERROR);

        //dd($serp_obj);

        if ($serp_obj?->status_code == 20000) {
            $json_file_name = config('platform.dataset.news.images_serp.file_prefix').str_slug($keyword).'-'.epoch_now_timestamp().'.json';

            $upload_status = OSSUploader::uploadJson(
                config('platform.dataset.news.images_serp.driver'),
                config('platform.dataset.news.images_serp.path'),
                $json_file_name,
                $serp_obj);

            if ($upload_status) {
                $news_serp_result = new NewsSerpResult();
                $news_serp_result->serp_provider = 'dfs';
                $news_serp_result->serp_se = 'google';
                $news_serp_result->serp_se_type = 'images';
                $news_serp_result->serp_keyword = $keyword;
                $news_serp_result->serp_country_iso = strtoupper($country_iso);
                $news_serp_result->serp_cost = $serp_obj?->cost;
                $news_serp_result->result_count = $serp_obj?->tasks[0]?->result[0]?->items_count;
                $news_serp_result->filename = $json_file_name;
                $news_serp_result->status = 'initial';

                if ($news_serp_result->save()) {

                    $serp_items = $serp_obj?->tasks[0]?->result[0]?->items;

                    //dd($serp_items);

                    foreach ($serp_items as $item) {
                        if ($item->type == 'images_search') {
                            //dd($item);
                            $images[] = $item->source_url;

                            if (count($images) > 20) {
                                break;
                            }
                        }

                    }
                }

            //return $news_serp_result;
            } else {
                throw new Exception('Uploading failed', 1);
            }
        } else {
            throw new Exception('Data failed', 1);
        }
        // } catch (Exception $e) {
        //     return null;
        // }

        $numImagesInCanvas = 2;

        if ($numImagesInCanvas > count($images)) {
            $numImagesInCanvas = count($images);
        }

        $canvasWidth = 720;
        $canvasHeight = 405;

        $canvas = Image::canvas($canvasWidth, $canvasHeight);

        // Add Images
        $imageWidth = $canvasWidth / $numImagesInCanvas;

        // Process and place each image
        $xOffset = 0;  // Horizontal offset to place each image
        for ($i = 0; $i < count($images); $i++) {
            $url = $images[$i];

            try {
                $imageResponse = Http::timeout(300)->withHeaders([
                    'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
                ])->get($url);

                $imageContent = $imageResponse->body();

                $image = Image::make($imageContent)
                    ->resize(null, $canvasHeight, function ($constraint) {
                        $constraint->aspectRatio();
                    })
                    ->resizeCanvas($imageWidth, $canvasHeight, 'center', false, [255, 255, 255, 0]);
                //->blur(6)

                $canvas->insert($image, 'top-left', $xOffset, 0);
                $xOffset += $imageWidth;
            } catch (Exception $e) {
                continue;
            }
        }

        ///

        $fontSize = 28;
        $articleTypeFontSize = 24;
        $padding = 15;

        $fontPath = resource_path('fonts/Inter/Inter-Black.ttf');

        // Split title into words and reconstruct lines
        $words = explode(' ', $title);
        $lines = [''];
        $currentLineIndex = 0;

        foreach ($words as $word) {
            $potentialLine = $lines[$currentLineIndex] ? $lines[$currentLineIndex].' '.$word : $word;

            $box = imagettfbbox($fontSize, 0, $fontPath, $potentialLine);
            $textWidth = abs($box[2] - $box[0]);

            if ($textWidth < $canvasWidth * 0.9) {
                $lines[$currentLineIndex] = $potentialLine;
            } else {
                $currentLineIndex++;
                $lines[$currentLineIndex] = $word;
            }
        }

        // Calculate the dimensions of the article_type text
        $articleTypeBox = imagettfbbox($articleTypeFontSize, 0, $fontPath, $article_type);
        $articleTypeWidth = abs($articleTypeBox[2] - $articleTypeBox[0]);
        $articleTypeHeight = abs($articleTypeBox[7] - $articleTypeBox[1]);

        // Define the start Y position for the article type overlay
        $articleOverlayStartY = $canvasHeight - ($fontSize * count($lines)) - ($articleTypeHeight + 4 * $padding);

        // Create the blue overlay for the article type
        $overlayWidth = $articleTypeWidth + 2 * $padding;
        $canvas->rectangle(20, $articleOverlayStartY, 10 + $overlayWidth, $articleOverlayStartY + $articleTypeHeight + 2 * $padding, function ($draw) {
            $draw->background([255, 255, 255, 0.8]);
        });

        // Overlay the article_type text within its overlay, centered horizontally and vertically
        $textStartX = 20 + ($overlayWidth - $articleTypeWidth) / 2;  // Center the text horizontally
        $canvas->text(strtoupper($article_type), $textStartX, $articleOverlayStartY + ($articleTypeHeight + 2 * $padding) / 2, function ($font) use ($articleTypeFontSize, $fontPath) {
            $font->file($fontPath);
            $font->size($articleTypeFontSize);
            $font->color('#0000FF');
            $font->align('left');
            $font->valign('middle'); // This ensures the text is vertically centered within the overlay
        });

        // Create the blue overlay for the title
        $titleOverlayStartY = $articleOverlayStartY + $articleTypeHeight + 2 * $padding;

        $canvas->rectangle(0, $titleOverlayStartY, $canvasWidth, $canvasHeight, function ($draw) {
            $draw->background([0, 0, 255, 0.5]);
        });

        // Draw each line for the title
        $yPosition = $titleOverlayStartY + $padding;
        foreach ($lines as $line) {
            $canvas->text($line, $canvasWidth / 2, $yPosition, function ($font) use ($fontSize, $fontPath) {
                $font->file($fontPath);
                $font->size($fontSize);
                $font->color('#FFFFFF');
                $font->align('center');
                $font->valign('top');
            });
            $yPosition += $fontSize + $padding;
        }

        $epoch_now_timestamp = epoch_now_timestamp();

        $filename = $post->slug.'-'.$epoch_now_timestamp.'.jpg';

        $ok = OSSUploader::uploadFile('r2', 'post_images/', $filename, (string) $canvas->stream('jpeg'));

        // LQIP
        // Clone the main image for LQIP version
        $lqipImage = clone $canvas;

        // Apply blur
        $lqipImage->blur(5); // Adjust to the desired blur level

        // Pixelate the image
        $lqipImage->pixelate(30); // Adjust this value based on the desired pixelation level

        // Encode the image to a low-quality JPG
        $lqipImage->encode('webp', 5);

        // LQIP filename
        $lqip_filename = $post->slug.'-'.$epoch_now_timestamp.'_lqip.webp';

        // Upload the LQIP version using OSSUploader
        $lqip_ok = OSSUploader::uploadFile('r2', 'post_images/', $lqip_filename, (string) $lqipImage->stream('webp'));

        if ($ok && $lqip_ok) {

            $post->featured_image = 'post_images/'.$filename;
            $post->status = 'publish';
            $post->save();

            PublishIndexPostJob::dispatch($post)->onQueue('default')->onConnection('default');

            return $post;
        }

        return null;
    }
}
