<?php

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

trait Niwa_AI_Tools_WP_Extras {

    /* ==================================================================
     *  READ-ONLY TOOL 1: list_custom_post_types
     * ================================================================== */

    /**
     * List all registered custom post types with metadata.
     */
    public function execute_list_custom_post_types( $args ) {
        /* All public post types (includes built-in like post, page). */
        $public_types = get_post_types( array( 'public' => true ), 'objects' );

        /* Custom-only (excludes built-in). */
        $custom_types = get_post_types( array( '_builtin' => false ), 'objects' );

        $result = array();

        foreach ( $public_types as $type_obj ) {
            $slug = $type_obj->name;

            /* Supports. */
            $supports = array();
            $all_features = array(
                'title', 'editor', 'author', 'thumbnail', 'excerpt',
                'trackbacks', 'custom-fields', 'comments', 'revisions',
                'page-attributes', 'post-formats',
            );
            foreach ( $all_features as $feature ) {
                if ( post_type_supports( $slug, $feature ) ) {
                    $supports[] = $feature;
                }
            }

            /* Taxonomies. */
            $taxonomies = get_object_taxonomies( $slug, 'names' );

            /* Post count. */
            $counts_obj = wp_count_posts( $slug );
            $count = array();
            if ( is_object( $counts_obj ) ) {
                foreach ( get_object_vars( $counts_obj ) as $status => $num ) {
                    $num = intval( $num );
                    if ( $num > 0 ) {
                        $count[ $status ] = $num;
                    }
                }
            }

            $result[] = array(
                'name'         => $slug,
                'label'        => $type_obj->label,
                'description'  => (string) $type_obj->description,
                'public'       => (bool) $type_obj->public,
                'hierarchical' => (bool) $type_obj->hierarchical,
                'has_archive'  => (bool) $type_obj->has_archive,
                'is_builtin'   => ! isset( $custom_types[ $slug ] ),
                'supports'     => $supports,
                'taxonomies'   => is_array( $taxonomies ) ? array_values( $taxonomies ) : array(),
                'count'        => $count,
            );
        }

        return array(
            'success'      => true,
            'total'        => count( $result ),
            'post_types'   => $result,
        );
    }

    /* ==================================================================
     *  READ-ONLY TOOL 2: get_media_file
     * ================================================================== */

    /**
     * Get a single media file's metadata and URL for a specific size.
     */
    public function execute_get_media_file( $args ) {
        $media_id = isset( $args['media_id'] ) ? intval( $args['media_id'] ) : 0;
        if ( $media_id <= 0 ) {
            return array( 'success' => false, 'error' => 'media_id je obavezan.' );
        }

        $post = get_post( $media_id );
        if ( ! $post || 'attachment' !== $post->post_type ) {
            return array( 'success' => false, 'error' => 'Media attachment (ID: ' . $media_id . ') nije pronadjen ili nije attachment tip.' );
        }

        $valid_sizes = array( 'thumbnail', 'medium', 'large', 'full' );
        $size = isset( $args['size'] ) && in_array( (string) $args['size'], $valid_sizes, true )
            ? (string) $args['size']
            : 'full';

        /* Get URL and dimensions for the requested size. */
        $src = wp_get_attachment_image_src( $media_id, $size );

        $url    = null;
        $width  = null;
        $height = null;

        if ( is_array( $src ) && ! empty( $src[0] ) ) {
            $url    = $src[0];
            $width  = intval( $src[1] );
            $height = intval( $src[2] );
        } else {
            /* Fallback for non-image attachments. */
            $url = wp_get_attachment_url( $media_id );
        }

        /* File size. */
        $file_path = get_attached_file( $media_id );
        $file_size = '';
        if ( $file_path && file_exists( $file_path ) ) {
            $bytes = @filesize( $file_path );
            if ( false !== $bytes ) {
                $file_size = size_format( $bytes );
            }
        }

        /* Filename. */
        $filename = $file_path ? wp_basename( $file_path ) : '';

        return array(
            'success' => true,
            'media'   => array(
                'id'        => $media_id,
                'filename'  => $filename,
                'mime_type' => $post->post_mime_type,
                'url'       => $url,
                'size'      => $size,
                'width'     => $width,
                'height'    => $height,
                'file_size' => $file_size,
            ),
        );
    }

    /* ==================================================================
     *  WRITE TOOL 3: elementor_assign_global_color
     * ================================================================== */

    /**
     * Preview: elementor_assign_global_color
     */
    private function preview_elementor_assign_global_color( $args ) {
        if ( ! function_exists( 'is_plugin_active' ) ) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }
        if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
            return array( 'success' => false, 'error' => 'Elementor plugin nije aktivan.' );
        }

        $post_id        = isset( $args['post_id'] ) ? intval( $args['post_id'] ) : 0;
        $widget_id      = isset( $args['widget_id'] ) ? sanitize_text_field( trim( (string) $args['widget_id'] ) ) : '';
        $property        = isset( $args['property'] ) ? sanitize_text_field( trim( (string) $args['property'] ) ) : '';
        $global_color_id = isset( $args['global_color_id'] ) ? sanitize_text_field( trim( (string) $args['global_color_id'] ) ) : '';

        if ( $post_id <= 0 ) {
            return array( 'success' => false, 'error' => 'post_id je obavezan.' );
        }
        if ( '' === $widget_id ) {
            return array( 'success' => false, 'error' => 'widget_id je obavezan.' );
        }
        if ( '' === $property ) {
            return array( 'success' => false, 'error' => 'property je obavezan.' );
        }
        if ( '' === $global_color_id ) {
            return array( 'success' => false, 'error' => 'global_color_id je obavezan.' );
        }

        $valid_properties = array(
            'title_color', 'text_color', 'background_color',
            'button_background_color', 'button_text_color', 'border_color',
            'hover_color', 'icon_color', 'description_color', 'heading_color',
        );
        if ( ! in_array( $property, $valid_properties, true ) ) {
            return array(
                'success' => false,
                'error'   => 'Nevalidan property: "' . $property . '". Dozvoljeni: ' . implode( ', ', $valid_properties ) . '.',
            );
        }

        /* Validate Elementor post. */
        if ( ! $this->is_elementor_post( $post_id ) ) {
            return array( 'success' => false, 'error' => 'Post (ID: ' . $post_id . ') ne koristi Elementor builder.' );
        }

        $data = $this->get_elementor_data( $post_id );
        if ( null === $data ) {
            return array( 'success' => false, 'error' => '_elementor_data je prazan ili neispravan za post ID ' . $post_id . '.' );
        }

        /* Find widget. */
        $found = $this->find_element_by_id_in_tree( $data, $widget_id );
        if ( null === $found ) {
            return array( 'success' => false, 'error' => 'Widget (ID: ' . $widget_id . ') nije pronadjen u Elementor strukturi.' );
        }

        /* Validate global_color_id exists in active kit. */
        $kit_id = intval( get_option( 'elementor_active_kit', 0 ) );
        if ( $kit_id <= 0 ) {
            return array( 'success' => false, 'error' => 'Aktivan Elementor kit nije pronadjen.' );
        }

        $page_settings = get_post_meta( $kit_id, '_elementor_page_settings', true );
        if ( ! is_array( $page_settings ) ) {
            return array( 'success' => false, 'error' => 'Elementor kit page_settings nisu dostupne.' );
        }

        $color_found = false;
        $color_title = '';
        $color_value = '';
        $color_pools = array( 'system_colors', 'custom_colors' );

        foreach ( $color_pools as $pool ) {
            if ( ! isset( $page_settings[ $pool ] ) || ! is_array( $page_settings[ $pool ] ) ) {
                continue;
            }
            foreach ( $page_settings[ $pool ] as $color ) {
                if ( ! is_array( $color ) ) {
                    continue;
                }
                $cid = isset( $color['_id'] ) ? (string) $color['_id'] : '';
                if ( $cid === $global_color_id ) {
                    $color_found = true;
                    $color_title = isset( $color['title'] ) ? (string) $color['title'] : '';
                    $color_value = isset( $color['color'] ) ? (string) $color['color'] : '';
                    break 2;
                }
            }
        }

        if ( ! $color_found ) {
            return array(
                'success' => false,
                'error'   => 'Global color ID "' . $global_color_id . '" nije pronadjen u aktivnom Elementor kit-u (ID: ' . $kit_id . '). Koristi elementor_get_active_kit da vidis dostupne boje.',
            );
        }

        $post = get_post( $post_id );

        $summary = 'Dodeljivanje globalne boje "' . $color_title . '" (' . $color_value . ') za property "' . $property . '" na widget-u (ID: ' . $widget_id . ') na stranici "' . ( $post ? $post->post_title : $post_id ) . '".';

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'elementor_assign_global_color',
                'label'            => 'Dodeli globalnu boju Elementor widget-u',
                'summary'          => $summary,
                'rollback_plan'    => 'Vraca prethodne settings widget-a.',
                'rollback_support' => 'full',
                'targets'          => array(
                    array(
                        'post_id'        => $post_id,
                        'post_title'     => $post ? $post->post_title : '',
                        'widget_id'      => $widget_id,
                        'property'       => $property,
                        'global_color_id' => $global_color_id,
                        'color_title'    => $color_title,
                        'color_value'    => $color_value,
                    ),
                ),
                'args'             => array(
                    'post_id'        => $post_id,
                    'widget_id'      => $widget_id,
                    'property'       => $property,
                    'global_color_id' => $global_color_id,
                ),
            ),
        );
    }

    /**
     * Execute: elementor_assign_global_color
     */
    private function execute_elementor_assign_global_color_action( $action ) {
        $args            = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $post_id         = intval( isset( $args['post_id'] ) ? $args['post_id'] : 0 );
        $widget_id       = sanitize_text_field( isset( $args['widget_id'] ) ? (string) $args['widget_id'] : '' );
        $property        = sanitize_text_field( isset( $args['property'] ) ? (string) $args['property'] : '' );
        $global_color_id = sanitize_text_field( isset( $args['global_color_id'] ) ? (string) $args['global_color_id'] : '' );

        if ( $post_id <= 0 || '' === $widget_id || '' === $property || '' === $global_color_id ) {
            return array( 'success' => false, 'error' => 'Nedovoljno podataka za elementor_assign_global_color.' );
        }

        $data = $this->get_elementor_data( $post_id );
        if ( null === $data ) {
            return array( 'success' => false, 'error' => '_elementor_data je prazan ili neispravan.' );
        }

        $found = $this->find_element_by_id_in_tree( $data, $widget_id );
        if ( null === $found ) {
            return array( 'success' => false, 'error' => 'Widget (ID: ' . $widget_id . ') nije pronadjen.' );
        }

        /* Capture previous settings for rollback. */
        $previous_settings = isset( $found['element']['settings'] ) && is_array( $found['element']['settings'] )
            ? $found['element']['settings']
            : array();

        $globals_value = 'globals/colors?id=' . $global_color_id;

        $updated = $this->update_element_in_tree( $data, $widget_id, function ( &$element ) use ( $property, $globals_value ) {
            if ( ! isset( $element['settings'] ) || ! is_array( $element['settings'] ) ) {
                $element['settings'] = array();
            }

            /* Remove direct color property if it exists (so global takes priority). */
            if ( isset( $element['settings'][ $property ] ) ) {
                unset( $element['settings'][ $property ] );
            }

            /* Set __globals__ reference. */
            if ( ! isset( $element['settings']['__globals__'] ) || ! is_array( $element['settings']['__globals__'] ) ) {
                $element['settings']['__globals__'] = array();
            }
            $element['settings']['__globals__'][ $property ] = $globals_value;
        } );

        if ( ! $updated ) {
            return array( 'success' => false, 'error' => 'Global color assignment u stablu nije uspeo.' );
        }

        $this->save_elementor_data( $post_id, $data );

        return array(
            'success'          => true,
            'summary'          => 'Globalna boja (ID: ' . $global_color_id . ') dodeljena za property "' . $property . '" na widget-u (ID: ' . $widget_id . ') na postu ' . $post_id . '.',
            'data'             => array(
                'post_id'        => $post_id,
                'widget_id'      => $widget_id,
                'property'       => $property,
                'global_color_id' => $global_color_id,
                'globals_value'  => $globals_value,
            ),
            'executed_actions' => array(
                array(
                    'type'      => 'elementor_assign_global_color',
                    'post_id'   => $post_id,
                    'widget_id' => $widget_id,
                    'property'  => $property,
                ),
            ),
            'rollback_entries' => array(
                array(
                    'type'              => 'elementor_widget_restore',
                    'post_id'           => $post_id,
                    'widget_id'         => $widget_id,
                    'previous_settings' => $previous_settings,
                ),
            ),
        );
    }

    /* ==================================================================
     *  READ-ONLY TOOL 4: wp_search_posts (backup/fallback)
     * ================================================================== */

    /**
     * Backup search tool — search WordPress posts by title, status, type
     * with pagination. Use when more specific tools are unavailable.
     */
    public function execute_wp_search_posts( $args ) {
        $search    = isset( $args['search'] ) ? sanitize_text_field( trim( (string) $args['search'] ) ) : '';
        $post_type = isset( $args['post_type'] ) ? sanitize_text_field( trim( (string) $args['post_type'] ) ) : 'post';
        $per_page  = isset( $args['per_page'] ) ? max( 1, min( 50, intval( $args['per_page'] ) ) ) : 10;
        $page      = isset( $args['page'] ) ? max( 1, intval( $args['page'] ) ) : 1;

        $valid_statuses = array( 'publish', 'draft', 'pending', 'private', 'trash', 'any' );
        $status = isset( $args['status'] ) && in_array( (string) $args['status'], $valid_statuses, true )
            ? (string) $args['status']
            : 'publish';

        $valid_orderbys = array( 'date', 'title', 'modified', 'id' );
        $orderby = isset( $args['orderby'] ) && in_array( strtolower( (string) $args['orderby'] ), $valid_orderbys, true )
            ? strtolower( (string) $args['orderby'] )
            : 'date';

        $order = isset( $args['order'] ) && in_array( strtolower( (string) $args['order'] ), array( 'asc', 'desc' ), true )
            ? strtoupper( (string) $args['order'] )
            : 'DESC';

        /* Validate that the post type is registered. */
        if ( ! post_type_exists( $post_type ) ) {
            return array( 'success' => false, 'error' => 'Post type "' . $post_type . '" nije registrovan.' );
        }

        $query_args = array(
            'post_type'      => $post_type,
            'post_status'    => 'any' === $status ? array( 'publish', 'draft', 'pending', 'private' ) : $status,
            'posts_per_page' => $per_page,
            'paged'          => $page,
            'orderby'        => 'id' === $orderby ? 'ID' : $orderby,
            'order'          => $order,
        );

        if ( '' !== $search ) {
            $query_args['s'] = $search;
        }

        /* Category filter (by term ID). */
        $category = isset( $args['category'] ) ? intval( $args['category'] ) : 0;
        if ( $category > 0 ) {
            $query_args['cat'] = $category;
        }

        /* Tag filter (by slug). */
        $tag = isset( $args['tag'] ) ? sanitize_text_field( trim( (string) $args['tag'] ) ) : '';
        if ( '' !== $tag ) {
            $query_args['tag'] = $tag;
        }

        $posts  = get_posts( $query_args );
        $result = array();

        foreach ( $posts as $post ) {
            $author_id  = intval( $post->post_author );
            $author     = get_userdata( $author_id );
            $thumb_id   = get_post_thumbnail_id( $post->ID );

            /* Excerpt: first 200 chars of excerpt or stripped content. */
            $excerpt_source = '' !== $post->post_excerpt ? $post->post_excerpt : $post->post_content;
            $plain          = wp_strip_all_tags( $excerpt_source );
            $excerpt        = mb_strlen( $plain ) > 200 ? mb_substr( $plain, 0, 200 ) . '...' : $plain;

            /* Categories. */
            $categories = array();
            $cat_terms  = wp_get_post_categories( $post->ID, array( 'fields' => 'names' ) );
            if ( is_array( $cat_terms ) ) {
                $categories = $cat_terms;
            }

            /* Tags. */
            $tags      = array();
            $tag_terms = wp_get_post_tags( $post->ID, array( 'fields' => 'names' ) );
            if ( is_array( $tag_terms ) ) {
                $tags = $tag_terms;
            }

            /* Featured image URL. */
            $featured_image_url = null;
            if ( $thumb_id ) {
                $featured_image_url = wp_get_attachment_url( $thumb_id );
            }

            $result[] = array(
                'id'                 => $post->ID,
                'title'              => $post->post_title,
                'status'             => $post->post_status,
                'type'               => $post->post_type,
                'date'               => $post->post_date,
                'modified'           => $post->post_modified,
                'slug'               => $post->post_name,
                'excerpt'            => $excerpt,
                'author'             => array(
                    'id'   => $author_id,
                    'name' => $author ? $author->display_name : '',
                ),
                'link'               => get_permalink( $post->ID ),
                'categories'         => $categories,
                'tags'               => $tags,
                'featured_image_url' => $featured_image_url,
            );
        }

        return array(
            'success' => true,
            'count'   => count( $result ),
            'page'    => $page,
            'per_page' => $per_page,
            'posts'   => $result,
        );
    }

    /* ==================================================================
     *  READ-ONLY TOOL 5: wp_get_post (backup/fallback)
     * ================================================================== */

    /**
     * Backup tool — get a single WordPress post/page/CPT by ID with full
     * content. Use when more specific tools are unavailable.
     */
    public function execute_wp_get_post( $args ) {
        $post_id = isset( $args['post_id'] ) ? intval( $args['post_id'] ) : 0;
        if ( $post_id <= 0 ) {
            return array( 'success' => false, 'error' => 'post_id je obavezan.' );
        }

        $post = get_post( $post_id );
        if ( ! $post ) {
            return array( 'success' => false, 'error' => 'Post (ID: ' . $post_id . ') nije pronadjen.' );
        }

        $author_id = intval( $post->post_author );
        $author    = get_userdata( $author_id );
        $thumb_id  = get_post_thumbnail_id( $post->ID );

        /* Featured image. */
        $featured_image_url = null;
        if ( $thumb_id ) {
            $featured_image_url = wp_get_attachment_url( $thumb_id );
        }

        /* Categories. */
        $categories = array();
        $cat_terms  = wp_get_post_categories( $post->ID, array( 'fields' => 'names' ) );
        if ( is_array( $cat_terms ) ) {
            $categories = $cat_terms;
        }

        /* Tags. */
        $tags      = array();
        $tag_terms = wp_get_post_tags( $post->ID, array( 'fields' => 'names' ) );
        if ( is_array( $tag_terms ) ) {
            $tags = $tag_terms;
        }

        /* Custom fields (skip internal _prefixed keys). */
        $custom_fields  = array();
        $all_meta       = get_post_meta( $post->ID );
        if ( is_array( $all_meta ) ) {
            foreach ( $all_meta as $key => $values ) {
                /* Skip internal/private meta keys starting with underscore. */
                if ( 0 === strpos( $key, '_' ) ) {
                    continue;
                }
                /* Use first value for single-value fields, full array for multi-value. */
                if ( is_array( $values ) && 1 === count( $values ) ) {
                    $custom_fields[ $key ] = $values[0];
                } else {
                    $custom_fields[ $key ] = $values;
                }
            }
        }

        return array(
            'success' => true,
            'post'    => array(
                'id'                 => $post->ID,
                'title'              => $post->post_title,
                'content'            => $post->post_content,
                'excerpt'            => $post->post_excerpt,
                'status'             => $post->post_status,
                'type'               => $post->post_type,
                'date'               => $post->post_date,
                'modified'           => $post->post_modified,
                'slug'               => $post->post_name,
                'link'               => get_permalink( $post->ID ),
                'author'             => array(
                    'id'   => $author_id,
                    'name' => $author ? $author->display_name : '',
                ),
                'parent'             => intval( $post->post_parent ) > 0 ? intval( $post->post_parent ) : null,
                'featured_image_id'  => $thumb_id ? intval( $thumb_id ) : null,
                'featured_image_url' => $featured_image_url,
                'comment_status'     => $post->comment_status,
                'comment_count'      => intval( $post->comment_count ),
                'categories'         => $categories,
                'tags'               => $tags,
                'custom_fields'      => $custom_fields,
            ),
        );
    }
}
