<?php

namespace SEOAIC\rest_api;

use Exception;
use SEOAIC\helpers\ImageHelpers;
use SEOAIC\posts_mass_actions\ThumbnailsGenerate;
use SEOAIC\rest_api\http_resources\Result;
use SEOAIC\SEOAIC_SETTINGS;
use WP_REST_Request;
use WP_REST_Response;

class EditorBlocks
{
    private $seoaic;

    public function __construct($seoaic)
    {
        $this->seoaic = $seoaic;

        $this->initEndpoints();
        $this->initFilters();
    }

    private function initEndpoints()
    {
        add_action('rest_api_init', function () {
            register_rest_route('seoaic/v1', '/blocks/generate-image/generate-images', [
                'methods' => 'POST',
                'callback' => [$this, 'generateImages'],
                'permission_callback' => function () {
                    return current_user_can('edit_posts');
                },
                'args' => [
                    'prompt' => [
                        'validate_callback' => function($param, $request, $key) {
                            return is_string($param);
                        }
                    ],
                ],
            ]);

            register_rest_route('seoaic/v1', '/blocks/generate-image/generate-alt-text', [
                'methods' => 'POST',
                'callback' => [$this, 'generateAltText'],
                'permission_callback' => function () {
                    return current_user_can('edit_posts');
                },
                'args' => [
                    'prompt' => [
                        'validate_callback' => function($param, $request, $key) {
                            return is_string($param);
                        }
                    ],
                ],
            ]);

            register_rest_route('seoaic/v1', '/blocks/generate-image/save-image', [
                'methods' => 'POST',
                'callback' => [$this, 'saveImage'],
                'permission_callback' => function () {
                    return current_user_can('edit_posts');
                },
                'args' => [
                    'url' => [
                        'validate_callback' => function($param, $request, $key) {
                            return is_string($param);
                        }
                    ],
                ],
            ]);
        });
    }

    private function initFilters()
    {
        // enable upload for webp image files.
        add_filter('mime_types', [$this, 'webpUploadMimes']);

        // enable preview / thumbnail for webp image files.
        add_filter('file_is_displayable_image', [$this, 'webpIsDisplayable'], 10, 2);

        // multisite webp support
        add_filter('site_option_upload_filetypes', [$this, 'multisiteWebpSupport']);
    }


    public function webpUploadMimes($existing_mimes) {
        $existing_mimes['webp'] = 'image/webp';

        return $existing_mimes;
    }

    public function webpIsDisplayable($result, $path)
    {
        if ($result === false) {
            $displayable_image_types = array( IMAGETYPE_WEBP );
            $info = @getimagesize( $path );

            if (empty($info)) {
                $result = false;
            } elseif (!in_array($info[2], $displayable_image_types)) {
                $result = false;
            } else {
                $result = true;
            }
        }

        return $result;
    }

    public function multisiteWebpSupport($filetypes)
    {
        $filetypes = explode(' ', $filetypes);

        if (!in_array('webp', $filetypes, true)) {
            $filetypes[] = 'webp';
        }

        return implode(' ', $filetypes);
    }


    public function generateImages(WP_REST_Request $request)
    {
        try {
            $jsonParams = $request->get_json_params();
            $userPrompt = !empty($jsonParams['user_prompt']) ? $jsonParams['user_prompt'] : '';
            $style = !empty($jsonParams['style']) ? $jsonParams['style'] : '';
            $width = !empty($jsonParams['width'])
                ? (int)$jsonParams['width']
                : ThumbnailsGenerate::DEFAULT_THUMBNAIL_WIDTH;
            $height = !empty($jsonParams['height'])
                ? (int)$jsonParams['height']
                : ThumbnailsGenerate::DEFAULT_THUMBNAIL_HEIGHT;

            if (empty($userPrompt)) {
                throw new Exception("Empty prompt");
            }

            $data = [
                "prompt" => $userPrompt,
                "thumbnail_generator" => "flux",
                'image_style' => $style ?? SEOAIC_SETTINGS::getImageGenerateStyle(),
                "removable" => true
            ];

            if (checkSizeOfImage($width, $height)) {
                $data['width'] = $width;
                $data['height'] = $height;
            }

            $response = $this->seoaic->curl->initWithReturn('/api/ai/images', $data, true);

            if (
                !empty($response['status'])
                && "success" == $response['status']
                && !empty($response['image_url'])
            ) {
                $imagePrompt = !empty($response['image_prompt']) ? $response['image_prompt'] : '';
                $title = !empty($response['image_title']) ? $response['image_title'] : '';
                $filename = !empty($response['image_filename']) ? $response['image_filename'] : '';

                return new WP_REST_Response(Result::success(__FUNCTION__, esc_html__('OK', 'seoaic'), [
                    'image' => [
                        // all array items set here can be used in the saveImage() function
                        'url'           => $response['image_url'],
                        'image_prompt'  => $imagePrompt,
                        'title'         => $title,
                        'user_prompt'   => $userPrompt,
                        'filename'      => $filename,
                    ],
                ]));
            } elseif (!empty($response['message'])) {
                throw new Exception(esc_html($response['message']));
            }

        } catch (Exception $e) {
            return new WP_REST_Response(Result::error(__FUNCTION__, esc_html__('Error: ', 'seoaic') . $e->getMessage()));
        }

        return new WP_REST_Response(Result::error(__FUNCTION__, esc_html__('Image generation failed', 'seoaic')));
    }

    public function generateAltText(WP_REST_Request $request)
    {
        try {
            $jsonParams = $request->get_json_params();
            $image = !empty($jsonParams['image']) ? $jsonParams['image'] : null;
            $prompt = !empty($image['image_prompt']) ? $image['image_prompt'] : '';

            if (empty($prompt)) {
                throw new Exception("Empty prompt");
            }

            $response = $this->seoaic->curl->initWithReturn('/api/ai/images/alt', [
                "prompt" => $prompt,
            ], true);

            if (
                !empty($response['status'])
                && "success" == $response['status']
                && !empty($response['image_alt'])
            ) {
                return new WP_REST_Response(Result::success(__FUNCTION__, esc_html__('OK', 'seoaic'), [
                    'alt' => trim(trim($response['image_alt'], '"')),
                ]));
            }

        } catch (Exception $e) {
            return new WP_REST_Response(Result::error(__FUNCTION__, esc_html__('Error: ', 'seoaic') . $e->getMessage()));
        }

        return new WP_REST_Response(Result::error(__FUNCTION__, esc_html__('Image alt generation failed', 'seoaic')));
    }

    public function saveImage(WP_REST_Request $request)
    {
        try {
            $jsonParams = $request->get_json_params();
            // $image contains all array items from the generateImages() function response
            $image = !empty($jsonParams['image']) ? $jsonParams['image'] : null;

            if (empty($image['url'])) {
                throw new Exception("Empty URL");
            }

            $result = ImageHelpers::uploadFromURL(
                $image['url'],
                [
                    'post_title'        => $image['title'],
                    'readable_filename' => $image['filename'],
                ]
            );

            if ($result) {
                return new WP_REST_Response(Result::success(__FUNCTION__, esc_html__('OK', 'seoaic'), $result));
            }

        } catch (Exception $e) {
            return new WP_REST_Response(Result::error(__FUNCTION__, esc_html__('Error: ', 'seoaic') . $e->getMessage()));
        }

        return new WP_REST_Response(Result::error(__FUNCTION__, esc_html__('Image not saved', 'seoaic')));
    }
}
