<?php

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

trait Niwa_AI_Tools_Media_Management {

    /* ==================================================================
     *  MEDIA MANAGEMENT — Shared helper
     * ================================================================== */

    /**
     * Format an attachment post into a structured media item array.
     *
     * @param WP_Post $post The attachment post object.
     * @param bool    $full Whether to include extended details (sizes, file_path, parent).
     * @return array
     */
    private function format_media_item( $post, $full = false ) {
        $metadata  = wp_get_attachment_metadata( $post->ID );
        $file_path = get_attached_file( $post->ID );
        $author    = get_userdata( $post->post_author );

        $item = array(
            'id'          => intval( $post->ID ),
            'title'       => $post->post_title,
            'filename'    => wp_basename( $file_path ? $file_path : '' ),
            'mime_type'   => $post->post_mime_type,
            'url'         => wp_get_attachment_url( $post->ID ),
            'alt_text'    => (string) get_post_meta( $post->ID, '_wp_attachment_image_alt', true ),
            'caption'     => $post->post_excerpt,
            'description' => $post->post_content,
            'date'        => $post->post_date,
            'author'      => array(
                'id'   => intval( $post->post_author ),
                'name' => $author ? $author->display_name : '',
            ),
        );

        /* Image dimensions from metadata. */
        $item['width']  = is_array( $metadata ) && isset( $metadata['width'] ) ? intval( $metadata['width'] ) : null;
        $item['height'] = is_array( $metadata ) && isset( $metadata['height'] ) ? intval( $metadata['height'] ) : null;

        /* Human-readable file size. */
        $item['file_size'] = '';
        if ( $file_path && file_exists( $file_path ) ) {
            $bytes = @filesize( $file_path );
            if ( false !== $bytes ) {
                $item['file_size'] = size_format( $bytes );
            }
        }

        if ( $full ) {
            $item['modified'] = $post->post_modified;

            /* Relative file path within uploads. */
            $upload_dir = wp_get_upload_dir();
            if ( $file_path && ! empty( $upload_dir['basedir'] ) && 0 === strpos( $file_path, $upload_dir['basedir'] ) ) {
                $item['file_path'] = ltrim( str_replace( $upload_dir['basedir'], '', $file_path ), '/\\' );
            } else {
                $item['file_path'] = $file_path ? wp_basename( $file_path ) : '';
            }

            /* Parent post if attached. */
            if ( $post->post_parent > 0 ) {
                $parent_post = get_post( $post->post_parent );
                $item['parent_post'] = array(
                    'id'    => intval( $post->post_parent ),
                    'title' => $parent_post ? $parent_post->post_title : '',
                );
            } else {
                $item['parent_post'] = null;
            }

            /* Image sizes with URLs. */
            $item['sizes'] = array();
            if ( is_array( $metadata ) && ! empty( $metadata['sizes'] ) && 0 === strpos( $post->post_mime_type, 'image/' ) ) {
                $available_sizes = array( 'thumbnail', 'medium', 'medium_large', 'large' );
                foreach ( $available_sizes as $size_name ) {
                    if ( isset( $metadata['sizes'][ $size_name ] ) ) {
                        $src = wp_get_attachment_image_src( $post->ID, $size_name );
                        if ( $src ) {
                            $item['sizes'][ $size_name ] = array(
                                'url'    => $src[0],
                                'width'  => intval( $src[1] ),
                                'height' => intval( $src[2] ),
                            );
                        }
                    }
                }
            }
        }

        return $item;
    }

    /* ==================================================================
     *  SEARCH MEDIA — Read-only (execute only, no preview needed)
     * ================================================================== */

    /**
     * Search media library with filtering and pagination.
     */
    public function execute_search_media( $args ) {
        $search     = isset( $args['search'] ) ? sanitize_text_field( trim( (string) $args['search'] ) ) : '';
        $media_type = isset( $args['media_type'] ) ? sanitize_text_field( trim( (string) $args['media_type'] ) ) : '';
        $mime_type  = isset( $args['mime_type'] ) ? sanitize_text_field( trim( (string) $args['mime_type'] ) ) : '';
        $author     = isset( $args['author'] ) ? intval( $args['author'] ) : 0;
        $parent     = isset( $args['parent'] ) ? intval( $args['parent'] ) : 0;
        $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;
        $orderby    = isset( $args['orderby'] ) && in_array( (string) $args['orderby'], array( 'date', 'title', 'modified' ), true )
            ? (string) $args['orderby']
            : 'date';
        $order      = isset( $args['order'] ) && in_array( strtolower( (string) $args['order'] ), array( 'asc', 'desc' ), true )
            ? strtoupper( (string) $args['order'] )
            : 'DESC';

        $query_args = array(
            'post_type'      => 'attachment',
            'post_status'    => 'inherit',
            'posts_per_page' => $per_page,
            'paged'          => $page,
            'orderby'        => $orderby,
            'order'          => $order,
            'no_found_rows'  => false,
        );

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

        /* media_type maps to broad MIME category. */
        $valid_media_types = array( 'image', 'video', 'audio', 'application' );
        if ( '' !== $media_type && in_array( $media_type, $valid_media_types, true ) ) {
            $query_args['post_mime_type'] = $media_type;
        }

        /* Specific MIME type overrides broad media_type. */
        if ( '' !== $mime_type ) {
            $query_args['post_mime_type'] = $mime_type;
        }

        if ( $author > 0 ) {
            $query_args['author'] = $author;
        }

        if ( $parent > 0 ) {
            $query_args['post_parent'] = $parent;
        }

        $query = new WP_Query( $query_args );
        $items = array();

        if ( ! empty( $query->posts ) ) {
            foreach ( $query->posts as $post ) {
                $items[] = $this->format_media_item( $post, false );
            }
        }

        return array(
            'success'     => true,
            'total'       => intval( $query->found_posts ),
            'total_pages' => intval( $query->max_num_pages ),
            'page'        => $page,
            'per_page'    => $per_page,
            'count'       => count( $items ),
            'items'       => $items,
        );
    }

    /* ==================================================================
     *  GET MEDIA DETAILS — Read-only (execute only, no preview needed)
     * ================================================================== */

    /**
     * Get full details of a single media attachment.
     */
    public function execute_get_media_details( $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.' );
        }

        return array(
            'success' => true,
            'media'   => $this->format_media_item( $post, true ),
        );
    }

    /* ==================================================================
     *  UPDATE MEDIA METADATA — Write with rollback
     * ================================================================== */

    /**
     * Preview: update_media_metadata
     */
    private function preview_update_media_metadata( $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 za update metadata.' );
        }

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

        $title       = isset( $args['title'] ) ? sanitize_text_field( trim( (string) $args['title'] ) ) : null;
        $alt_text    = isset( $args['alt_text'] ) ? sanitize_text_field( trim( (string) $args['alt_text'] ) ) : null;
        $caption     = isset( $args['caption'] ) ? sanitize_text_field( trim( (string) $args['caption'] ) ) : null;
        $description = isset( $args['description'] ) ? wp_kses_post( trim( (string) $args['description'] ) ) : null;

        if ( null === $title && null === $alt_text && null === $caption && null === $description ) {
            return array( 'success' => false, 'error' => 'Barem jedno polje (title, alt_text, caption, description) mora biti zadato.' );
        }

        /* Capture current values for rollback. */
        $previous_title       = $post->post_title;
        $previous_alt_text    = (string) get_post_meta( $media_id, '_wp_attachment_image_alt', true );
        $previous_caption     = $post->post_excerpt;
        $previous_description = $post->post_content;

        /* Build summary. */
        $changes = array();
        if ( null !== $title ) {
            $changes[] = 'title: "' . $previous_title . '" -> "' . $title . '"';
        }
        if ( null !== $alt_text ) {
            $changes[] = 'alt_text: "' . $previous_alt_text . '" -> "' . $alt_text . '"';
        }
        if ( null !== $caption ) {
            $changes[] = 'caption';
        }
        if ( null !== $description ) {
            $changes[] = 'description';
        }

        $summary = 'Azuriranje metadata za media "' . $post->post_title . '" (ID: ' . $media_id . '). Promene: ' . implode( ', ', $changes ) . '.';

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'update_media_metadata',
                'label'            => 'Azuriraj media metadata',
                'summary'          => $summary,
                'rollback_plan'    => 'Vraca prethodne vrednosti title, alt_text, caption i description.',
                'rollback_support' => 'full',
                'targets'          => array(
                    array(
                        'media_id'   => $media_id,
                        'post_title' => $post->post_title,
                        'filename'   => wp_basename( get_attached_file( $media_id ) ?: '' ),
                    ),
                ),
                'args'             => array(
                    'media_id'             => $media_id,
                    'title'                => $title,
                    'alt_text'             => $alt_text,
                    'caption'              => $caption,
                    'description'          => $description,
                    'previous_title'       => $previous_title,
                    'previous_alt_text'    => $previous_alt_text,
                    'previous_caption'     => $previous_caption,
                    'previous_description' => $previous_description,
                ),
            ),
        );
    }

    /**
     * Validate: update_media_metadata
     */
    private function validate_update_media_metadata_action_args( $args ) {
        if ( empty( $args['media_id'] ) || intval( $args['media_id'] ) <= 0 ) {
            return array( 'success' => false, 'error' => 'media_id nedostaje za update metadata.' );
        }

        $has_field = (
            array_key_exists( 'title', $args ) && null !== $args['title'] ) ||
            ( array_key_exists( 'alt_text', $args ) && null !== $args['alt_text'] ) ||
            ( array_key_exists( 'caption', $args ) && null !== $args['caption'] ) ||
            ( array_key_exists( 'description', $args ) && null !== $args['description']
        );

        if ( ! $has_field ) {
            return array( 'success' => false, 'error' => 'Nijedna metadata promena nije zadata.' );
        }

        return array( 'success' => true );
    }

    /**
     * Execute: update_media_metadata
     */
    private function execute_update_media_metadata_action( $action ) {
        $args     = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $media_id = intval( $args['media_id'] );

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

        /* Build post update data. */
        $update_data = array( 'ID' => $media_id );
        $updated_fields = array();

        if ( array_key_exists( 'title', $args ) && null !== $args['title'] ) {
            $update_data['post_title'] = sanitize_text_field( (string) $args['title'] );
            $updated_fields[] = 'title';
        }
        if ( array_key_exists( 'caption', $args ) && null !== $args['caption'] ) {
            $update_data['post_excerpt'] = sanitize_text_field( (string) $args['caption'] );
            $updated_fields[] = 'caption';
        }
        if ( array_key_exists( 'description', $args ) && null !== $args['description'] ) {
            $update_data['post_content'] = wp_kses_post( (string) $args['description'] );
            $updated_fields[] = 'description';
        }

        /* Update post fields if any changed. */
        if ( count( $update_data ) > 1 ) {
            $updated = wp_update_post( $update_data, true );
            if ( is_wp_error( $updated ) ) {
                return array( 'success' => false, 'error' => 'Media metadata update nije uspeo: ' . $updated->get_error_message() );
            }
        }

        /* Update alt text via post meta. */
        if ( array_key_exists( 'alt_text', $args ) && null !== $args['alt_text'] ) {
            update_post_meta( $media_id, '_wp_attachment_image_alt', sanitize_text_field( (string) $args['alt_text'] ) );
            $updated_fields[] = 'alt_text';
        }

        /* Build rollback entry. */
        $rollback_entry = array(
            'type'                 => 'media_metadata_restore',
            'media_id'             => $media_id,
            'previous_title'       => isset( $args['previous_title'] ) ? (string) $args['previous_title'] : $post->post_title,
            'previous_alt_text'    => isset( $args['previous_alt_text'] ) ? (string) $args['previous_alt_text'] : (string) get_post_meta( $media_id, '_wp_attachment_image_alt', true ),
            'previous_caption'     => isset( $args['previous_caption'] ) ? (string) $args['previous_caption'] : $post->post_excerpt,
            'previous_description' => isset( $args['previous_description'] ) ? (string) $args['previous_description'] : $post->post_content,
        );

        return array(
            'success'          => true,
            'summary'          => 'Azurirani metadata za media "' . get_the_title( $media_id ) . '" (ID: ' . $media_id . '). Polja: ' . implode( ', ', $updated_fields ) . '.',
            'executed_actions' => array(
                array(
                    'type'           => 'update_media_metadata',
                    'media_id'       => $media_id,
                    'updated_fields' => $updated_fields,
                ),
            ),
            'rollback_entries' => array( $rollback_entry ),
        );
    }

    /* ==================================================================
     *  DELETE MEDIA — Destructive with conditional rollback
     * ================================================================== */

    /**
     * Preview: delete_media
     */
    private function preview_delete_media( $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 za brisanje.' );
        }

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

        $force    = isset( $args['force'] ) ? (bool) $args['force'] : false;
        $filename = wp_basename( get_attached_file( $media_id ) ?: '' );

        if ( $force ) {
            /* Permanent deletion — no rollback possible. */
            return array(
                'success' => true,
                'action'  => array(
                    'type'             => 'delete_media',
                    'label'            => 'Permanentno obrisi media attachment',
                    'summary'          => 'Permanentno brisanje media "' . $post->post_title . '" (' . $filename . ', ID: ' . $media_id . '). Fajl i DB zapis ce biti trajno uklonjeni.',
                    'rollback_plan'    => 'Permanentno brisanje je nepovratno. Rollback nije moguc.',
                    'rollback_support' => 'none',
                    'targets'          => array(
                        array(
                            'media_id'   => $media_id,
                            'post_title' => $post->post_title,
                            'filename'   => $filename,
                            'mime_type'  => $post->post_mime_type,
                        ),
                    ),
                    'args'             => array(
                        'media_id' => $media_id,
                        'force'    => true,
                    ),
                ),
            );
        }

        /* Soft delete — detach from parent. */
        $previous_parent_id = intval( $post->post_parent );
        $parent_label       = '';
        if ( $previous_parent_id > 0 ) {
            $parent_post  = get_post( $previous_parent_id );
            $parent_label = $parent_post ? ' (roditelj: "' . $parent_post->post_title . '", ID: ' . $previous_parent_id . ')' : ' (roditelj ID: ' . $previous_parent_id . ')';
        }

        $summary = 'Odvajanje media "' . $post->post_title . '" (' . $filename . ', ID: ' . $media_id . ') od roditeljskog posta' . $parent_label . '.';
        if ( 0 === $previous_parent_id ) {
            $summary = 'Media "' . $post->post_title . '" (' . $filename . ', ID: ' . $media_id . ') vec nema roditeljski post. Nema potrebe za odvajanjem.';
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'delete_media',
                'label'            => 'Odvoji media od roditeljskog posta',
                'summary'          => $summary,
                'rollback_plan'    => 'Ponovo povezuje media attachment sa prethodnim roditeljskim postom.',
                'rollback_support' => 'full',
                'targets'          => array(
                    array(
                        'media_id'           => $media_id,
                        'post_title'         => $post->post_title,
                        'filename'           => $filename,
                        'previous_parent_id' => $previous_parent_id,
                    ),
                ),
                'args'             => array(
                    'media_id'           => $media_id,
                    'force'              => false,
                    'previous_parent_id' => $previous_parent_id,
                ),
            ),
        );
    }

    /**
     * Validate: delete_media
     */
    private function validate_delete_media_action_args( $args ) {
        if ( empty( $args['media_id'] ) || intval( $args['media_id'] ) <= 0 ) {
            return array( 'success' => false, 'error' => 'media_id nedostaje za brisanje media.' );
        }
        return array( 'success' => true );
    }

    /**
     * Execute: delete_media
     */
    private function execute_delete_media_action( $action ) {
        $args     = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $media_id = intval( $args['media_id'] );
        $force    = isset( $args['force'] ) ? (bool) $args['force'] : false;

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

        $filename = wp_basename( get_attached_file( $media_id ) ?: '' );

        if ( $force ) {
            /* Permanent deletion — remove file and DB entry. */
            $deleted = wp_delete_attachment( $media_id, true );
            if ( false === $deleted || null === $deleted ) {
                return array( 'success' => false, 'error' => 'Permanentno brisanje media (ID: ' . $media_id . ') nije uspelo.' );
            }

            return array(
                'success'          => true,
                'summary'          => 'Permanentno obrisan media "' . $post->post_title . '" (' . $filename . ', ID: ' . $media_id . ').',
                'executed_actions' => array(
                    array(
                        'type'     => 'delete_media_permanent',
                        'media_id' => $media_id,
                    ),
                ),
                'rollback_entries' => array(),
            );
        }

        /* Soft delete — detach from parent. */
        $previous_parent_id = intval( $post->post_parent );

        $updated = wp_update_post(
            array(
                'ID'          => $media_id,
                'post_parent' => 0,
            ),
            true
        );

        if ( is_wp_error( $updated ) ) {
            return array( 'success' => false, 'error' => 'Odvajanje media od roditelja nije uspelo: ' . $updated->get_error_message() );
        }

        $rollback_entries = array();
        if ( $previous_parent_id > 0 ) {
            $rollback_entries[] = array(
                'type'               => 'media_reattach',
                'media_id'           => $media_id,
                'previous_parent_id' => $previous_parent_id,
            );
        }

        $summary = 'Media "' . $post->post_title . '" (' . $filename . ', ID: ' . $media_id . ') odvojen od roditeljskog posta (ID: ' . $previous_parent_id . ').';
        if ( 0 === $previous_parent_id ) {
            $summary = 'Media "' . $post->post_title . '" (' . $filename . ', ID: ' . $media_id . ') vec nije imao roditeljski post. Nista nije promenjeno.';
        }

        return array(
            'success'          => true,
            'summary'          => $summary,
            'executed_actions' => array(
                array(
                    'type'               => 'delete_media_detach',
                    'media_id'           => $media_id,
                    'previous_parent_id' => $previous_parent_id,
                ),
            ),
            'rollback_entries' => $rollback_entries,
        );
    }
}
