<?php
/**
 * Author: Rymera Web Co.
 *
 * @package SAAI\Factories
 */

namespace SAAI\AI_Agents;

use SAAI\Abstracts\Abstract_AI_Agent;
use SAAI\Classes\Plan_Manager;
use SAAI\Factories\Vite_App;
use SAAI\Traits\Singleton_Trait;
use SAAI\Helpers\Helper;
use SAAI\REST\Image_Alt_Tags_AI_REST;
use SAAI\Classes\Notification;

/**
 * Image_Alt_Tags_AI_Agent class.
 *
 * @since 1.1.2
 */
class Image_Alt_Tags_AI extends Abstract_AI_Agent {

    use Singleton_Trait;

    /**
     * Holds the class instance object
     *
     * @since 1.1.2
     * @var Image_Alt_Tags_AI $instance object
     */
    protected static $instance;

    /**
     * Holds the settings data.
     *
     * @since 1.1.2
     * @var array Settings data.
     */
    protected $settings;

    /**
     * Constructor.
     *
     * @param mixed $data The prompt.
     */
    public function __construct( $data = null ) {

        $this->endpoint         = 'image-alt-tags';
        $this->ai_id            = "$this->endpoint-ai";
        $this->data             = $data;
        $this->default_settings = array(
            'enabled'        => $this->maybe_enable_by_default(),
            'default_fields' => array( 'alt' ),
        );

        // Initialize settings.
        $this->settings = $this->get_settings();
    }

    /**
     * Get optimized image URL for AI processing.
     *
     * Uses 'large' size to avoid exceeding 8MB limit, with fallback to 'medium' and full size.
     *
     * @since 1.1.2
     * @param int $attachment_id The attachment ID.
     * @return string|false The image URL on success, false if no image URL could be retrieved.
     */
    public function get_optimized_image_url( int $attachment_id ) {
        // Validate attachment ID.
        if ( ! $attachment_id || ! is_numeric( $attachment_id ) ) {
            return false;
        }

        // Verify it's actually an attachment.
        if ( 'attachment' !== get_post_type( $attachment_id ) ) {
            return false;
        }

        // Use 'large' size to avoid exceeding 8MB limit.
        $image_url = wp_get_attachment_image_url( $attachment_id, 'large' );

        if ( ! $image_url ) {
            // Fallback to medium size if large doesn't exist.
            $image_url = wp_get_attachment_image_url( $attachment_id, 'medium' );
        }

        if ( ! $image_url ) {
            // Final fallback to full size if no other sizes exist.
            $image_url = wp_get_attachment_url( $attachment_id );
        }

        return $image_url;
    }

    /**
     * Set the prompt data.
     *
     * @param mixed $data The data prompt to be sent.
     *
     * @return void
     */
    public function set_data( $data ) {
        foreach ( $data as $key => $value ) {
            if ( is_array( $value ) ) {
                $this->data[ $key ] = implode( ', ', $value );
            } else {
                $this->data[ $key ] = $value;
            }
        }
    }

    /**
     * Run the agent query.
     *
     * @param array $params The parameters.
     *
     * @return array|\WP_Error
     */
    public function run_agent_query( $params = array() ) {
        $attachment_id = (int) $params['attachment_id'] ?? 0;
        $image_url     = $params['image_url'] ?? '';

        if ( ! $attachment_id && ! $image_url ) {
            return new \WP_Error(
                'saai_missing_image_data',
                __( 'Missing image data. Please provide either attachment_id or image_url.', 'storeagent-ai-for-woocommerce' )
            );
        }

        // Get image data if we have an attachment ID.
        if ( $attachment_id ) {
            $image_url = $this->get_optimized_image_url( $attachment_id );
            if ( ! $image_url ) {
                return new \WP_Error(
                    'saai_invalid_attachment',
                    __( 'Invalid attachment ID.', 'storeagent-ai-for-woocommerce' )
                );
            }

            $params['image_url'] = $image_url;
        }

        // Prepare data for the AI agent.
        $this->set_data( $params );

        $ai_response = $this->send_prompt();

        if ( is_wp_error( $ai_response ) ) {
            return new \WP_Error(
                'saai_image_alt_generation_failed',
                sprintf(
                    // translators: %s: error message.
                    __( 'AI query failed: %s', 'storeagent-ai-for-woocommerce' ),
                    $ai_response->get_error_message()
                )
            );
        }

        return $ai_response;
    }

    /**
     * Save the object data.
     *
     * @param int   $attachment_id The attachment ID.
     * @param array $data The data to save.
     *
     * @return bool|\WP_Error
     */
    public function save_object_data( $attachment_id, $data ) {
        $update_data = array(
            'ID' => $attachment_id,
        );

        // Alt text is stored in post meta, not post_excerpt.
        if ( isset( $data['alt_text'] ) && ! empty( $data['alt_text'] ) ) {
            update_post_meta( $attachment_id, '_wp_attachment_image_alt', sanitize_text_field( $data['alt_text'] ) );
        }

        if ( isset( $data['caption'] ) && ! empty( $data['caption'] ) ) {
            $update_data['post_excerpt'] = wp_kses_post( $data['caption'] );
        }

        if ( isset( $data['title'] ) && ! empty( $data['title'] ) ) {
            $update_data['post_title'] = sanitize_text_field( $data['title'] );
        }

        if ( isset( $data['description'] ) && ! empty( $data['description'] ) ) {
            $update_data['post_content'] = wp_kses_post( $data['description'] );
        }

        // Only update post if we have fields to update (more than just ID).
        if ( count( $update_data ) > 1 ) {
            $result = wp_update_post( $update_data );
            if ( is_wp_error( $result ) ) {
                return $result;
            }
        }

        return true;
    }

    /**
     * Display the generate AI alt tags button.
     *
     * @param int $attachment_id The attachment ID.
     * @return void
     */
    public function display_generate_ai_alt_tags_button( $attachment_id ) {
        if ( ! wp_attachment_is_image( $attachment_id ) ) {
            return;
        }

        Helper::locate_admin_template( 'image-alt-tags-button.php', true, array( 'attachment_id' => $attachment_id ) );
    }

    /**
     * Enqueue the image alt tags admin scripts.
     *
     * @since 1.1.2
     * @return void
     */
    public function enqueue_image_alt_tags_admin_scripts() {
        // Don't load scripts if agent is disabled.
        if ( ! $this->is_enabled() ) {
            return;
        }

        global $current_screen;

        // Only load on media library, attachment edit screens, and post editor screens where media can be inserted.
        if ( ! isset( $current_screen->id ) ) {
            return;
        }

        // List of screens where media library is available.
        $allowed_screens = array(
            'upload',      // Media library list view.
            'attachment',  // Single attachment edit page.
            'post',        // Post editor.
            'page',        // Page editor.
            'product',     // WooCommerce product editor.
        );

        $is_allowed = false;

        foreach ( $allowed_screens as $screen ) {
            if ( strpos( $current_screen->id, $screen ) === 0 || $current_screen->id === $screen ) {
                $is_allowed = true;
                break;
            }
        }

        if ( ! $is_allowed ) {
            return;
        }

        $settings = $this->get_settings();

        // Only enqueue if media scripts are available (WP/WooCommerce usually loads them on product pages).
        // Don't force-load on every page.
        if ( 'upload' === $current_screen->id || 'attachment' === $current_screen->id ) {
            wp_enqueue_media();
        }

        $image_alt_tags = new Vite_App(
            'saai-image-alt-tags',
            'src/vanilla/admin/image-alt-tags/index.ts',
            array( 'jquery', 'wp-i18n' ),
            array_merge(
                array(
                    'imageAltTagsRestUrl' => Image_Alt_Tags_AI_REST::instance()->api_url,
                    'wpNonce'             => wp_create_nonce( 'wp_rest' ),
                    'pluginUrl'           => SAAI_PLUGIN_URL,
                    'defaultFields'       => isset( $settings['default_fields'] ) ? $settings['default_fields'] : array( 'alt' ),
                ),
                Plan_Manager::get_credit_usage_l10n()
            ),
            'saaiObj',
            array()
        );
        $image_alt_tags->enqueue();
    }

    /**
     * Get the image alt tags form.
     *
     * @return void
     */
    public function ajax_get_image_alt_tags_form() {
        if ( ! wp_verify_nonce( sanitize_key( $_POST['nonce'] ?? '' ), 'saai_get_image_alt_tags_form' ) || ! current_user_can( 'manage_options' ) ) {
            wp_die( 'Invalid nonce' );
        }

        $attachment_id = intval( $_POST['attachment_id'] ?? 0 );
        $attachment    = get_post( $attachment_id );

        if ( ! $attachment || 'attachment' !== $attachment->post_type || ! wp_attachment_is_image( $attachment ) ) {
            wp_die( 'Invalid attachment' );
        }

        $image_url   = $this->get_optimized_image_url( $attachment_id );
        $current_alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true );

        $data = array(
            'image_url'   => $image_url,
            'current_alt' => $current_alt,
            'attachment'  => $attachment,
        );

        extract( $data ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract

        $template_path_dir = SAAI_PLUGIN_DIR_PATH . 'templates/admin/';

        include $template_path_dir . 'image-alt-tags-form/form-header.php';
        include $template_path_dir . 'image-alt-tags-form/form-content.php';
        include $template_path_dir . 'image-alt-tags-form/form-footer.php';

        // Add script to initialize the modal functionality.
        ?>
        <script>
        (function($) {
            $(document).ready(function() {
                if (window.saaiImageAltTagsInitialized) return;
                window.saaiImageAltTagsInitialized = true;

                // Initialize the image alt tags functionality
                if (typeof initImageAltTags === 'function') {
                    initImageAltTags();
                }
            });
        })(jQuery);
        </script>
        <?php

        wp_die();
    }

    /**
     * Add custom field to media modal.
     *
     * @param array   $form_fields An array of attachment form fields.
     * @param WP_Post $post        The attachment post object.
     * @return array Modified form fields.
     */
    public function add_media_modal_field( $form_fields, $post ) {
        if ( ! wp_attachment_is_image( $post->ID ) ) {
            return $form_fields;
        }

        $button_html = '<div class="saai-image-alt-tags-button-move">
            <div class="saai-image-alt-tags-button" style="margin-bottom: 10px;">
                <button type="button" class="saai-button saai-button-main saai-button-left-icon saai-generate-alt-tags-button" data-attachment-id="' . esc_attr( $post->ID ) . '">
                    <img src="' . esc_url( SAAI_PLUGIN_URL . 'static/images/ai-icon.svg' ) . '" alt="AI Icon" style="width: 16px; height: 16px;">
                    <span class="saai-button-text">' . esc_html__( 'Generate with AI', 'storeagent-ai-for-woocommerce' ) . '</span>
                </button>
            </div>
        </div>';

        // Insert button right before the image_alt field.
        $new_form_fields = array();
        $button_added    = false;

        foreach ( $form_fields as $key => $field ) {
            // Add button before the Alternative Text field.
            if ( 'image_alt' === $key && ! $button_added ) {
                $new_form_fields['saai_generate_alt_tags'] = array(
                    'label'         => '',
                    'input'         => 'html',
                    'html'          => $button_html,
                    'show_in_edit'  => true,
                    'show_in_modal' => true,
                );
                $button_added                              = true;
            }
            $new_form_fields[ $key ] = $field;
        }

        // If image_alt field doesn't exist, add button at the beginning.
        if ( ! $button_added ) {
            $new_form_fields = array_merge(
                array(
                    'saai_generate_alt_tags' => array(
                        'label'         => '',
                        'input'         => 'html',
                        'html'          => $button_html,
                        'show_in_edit'  => true,
                        'show_in_modal' => true,
                    ),
                ),
                $new_form_fields
            );
        }

        return $new_form_fields;
    }

    /**
     * Run hooks related to the AI agent.
     *
     * @return void
     */
    public function run() {
        if ( ! $this->is_enabled() ) {
            return;
        }

        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_image_alt_tags_admin_scripts' ) );
        add_action( 'admin_footer', array( $this, 'render_modal_template' ) );
        add_filter( 'attachment_fields_to_edit', array( $this, 'add_media_modal_field' ), 10, 2 );
    }

    /**
     * Render the modal template on admin footer
     *
     * @return void
     */
    public function render_modal_template() {
        // Don't render modal if agent is disabled.
        if ( ! $this->is_enabled() ) {
            return;
        }

        global $current_screen;

        // Only load on media library, attachment edit screens, and post editor screens where media can be inserted.
        if ( ! isset( $current_screen->id ) ) {
            return;
        }

        // List of screens where media library is available.
        $allowed_screens = array(
            'upload',      // Media library list view.
            'attachment',  // Single attachment edit page.
            'post',        // Post editor.
            'page',        // Page editor.
            'product',     // WooCommerce product editor.
        );

        $is_allowed = false;

        foreach ( $allowed_screens as $screen ) {
            if ( strpos( $current_screen->id, $screen ) === 0 || $current_screen->id === $screen ) {
                $is_allowed = true;
                break;
            }
        }

        if ( ! $is_allowed ) {
            return;
        }

        // Set default values for the template.
        $attachment_id = 0;
        $image_url     = '';
        $current_alt   = '';

        $template_path_dir = SAAI_PLUGIN_DIR_PATH . 'templates/admin/';
        include $template_path_dir . 'image-alt-tags-form/form-header.php';
        include $template_path_dir . 'image-alt-tags-form/form-footer.php';
    }

    /**
     * Maybe enable the AI agent by default.
     *
     * @since 1.1.2
     * @return string
     */
    public function maybe_enable_by_default() {
        return 'yes';
    }

    /**
     * Enable the AI agent and schedule tasks.
     *
     * @since 1.1.2
     * @return bool True if the agent was enabled successfully, false otherwise.
     */
    public function enable() {
        $result = parent::enable();
        return $result;
    }
}
