<?php

namespace FSPoster\App\AI\Helpers;

use Exception;
use FSPoster\App\Providers\Helpers\Helper;
use RuntimeException;

class AIHelper
{
    /**
     * @throws Exception
     */
    public static function createImageAttachmentFromUrl(string $provider, string $url): int
    {
        require_once(ABSPATH . 'wp-admin/includes/image.php');
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        require_once(ABSPATH . 'wp-admin/includes/media.php');

        $tmpFile = download_url($url);
        $mime = Helper::mimeContentType($tmpFile);

        $filename = $provider . '-' . Helper::generateUUID() . '.' . explode('/', $mime)[1];

        if (is_wp_error($tmpFile)) {
            throw new Exception($tmpFile->get_error_message());
        }

        $attached = media_handle_sideload(array('name' => $filename, 'tmp_name' => $tmpFile));

        if (is_wp_error($attached)) {
            throw new Exception($attached->get_error_message());
        }

        if (file_exists($tmpFile)) {
            unlink($tmpFile);
        }

        add_post_meta($attached, 'fsp_ai_generated_image', 1, true);

        return $attached;
    }

    /**
     * @throws Exception
     */
    public static function createImageAttachmentFromBase64(string $provider, string $base64Data): int
    {
        require_once(ABSPATH . 'wp-admin/includes/image.php');
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        require_once(ABSPATH . 'wp-admin/includes/media.php');

        $decoded = base64_decode($base64Data);

        if ($decoded === false) {
            throw new RuntimeException(fsp__('Failed to decode base64 image data'));
        }

        $mime = self::detectImageMimeFromBytes($decoded);
        $extension = self::getImageExtensionFromMime($mime);
        $filename = $provider . '-' . Helper::generateUUID() . '.' . $extension;
        $tmpFile = wp_tempnam($filename);

        if ($tmpFile === false) {
            throw new RuntimeException(fsp__('Failed to create temporary image file'));
        }

        if (file_put_contents($tmpFile, $decoded) === false) {
            if (file_exists($tmpFile)) {
                unlink($tmpFile);
            }

            throw new RuntimeException(fsp__('Failed to write image data to temporary file'));
        }

        $attached = media_handle_sideload([ 'name' => $filename, 'tmp_name' => $tmpFile ]);

        if (is_wp_error($attached)) {
            if (file_exists($tmpFile)) {
                unlink($tmpFile);
            }

            throw new Exception($attached->get_error_message());
        }

        if (file_exists($tmpFile)) {
            unlink($tmpFile);
        }

        add_post_meta($attached, 'fsp_ai_generated_image', 1, true);

        return $attached;
    }

    private static function detectImageMimeFromBytes(string $bytes): string
    {
        if (function_exists('getimagesizefromstring')) {
            $imageInfo = @getimagesizefromstring($bytes);

            if (! empty($imageInfo['mime'])) {
                return $imageInfo['mime'];
            }
        }

        if (function_exists('finfo_open')) {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);

            if ($finfo !== false) {
                $mime = @finfo_buffer($finfo, $bytes);
                finfo_close($finfo);

                if (! empty($mime)) {
                    return $mime;
                }
            }
        }

        throw new RuntimeException(fsp__('Unsupported image data'));
    }

    private static function getImageExtensionFromMime(string $mime): string
    {
        $extensions = [
            'image/png'  => 'png',
            'image/jpeg' => 'jpg',
            'image/webp' => 'webp',
            'image/gif'  => 'gif',
            'image/bmp'  => 'bmp',
            'image/tiff' => 'tiff',
        ];

        if (! isset($extensions[$mime])) {
            throw new RuntimeException(fsp__('Unsupported image data'));
        }

        return $extensions[$mime];
    }
}
