<?php

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

trait Niwa_AI_Tools_Bloging {

	/* ==================================================================
	 *  SEARCH STOCK IMAGES — Read-only
	 * ================================================================== */

	/**
	 * Preview: search_stock_images
	 *
	 * @param array $args Tool arguments.
	 * @return array
	 */
	private function preview_search_stock_images( $args ) {
		$query = isset( $args['query'] ) ? sanitize_text_field( trim( (string) $args['query'] ) ) : '';
		if ( '' === $query ) {
			return array( 'success' => false, 'error' => 'Parametar query je obavezan za pretragu stock slika.' );
		}

		$source = isset( $args['source'] ) && in_array( (string) $args['source'], array( 'auto', 'pexels', 'unsplash', 'lummi' ), true )
			? (string) $args['source']
			: 'auto';

		$orientation = isset( $args['orientation'] ) && in_array( (string) $args['orientation'], array( 'landscape', 'portrait', 'square' ), true )
			? (string) $args['orientation']
			: 'landscape';

		$count = isset( $args['count'] ) ? max( 1, min( 10, intval( $args['count'] ) ) ) : 5;

		return array(
			'success' => true,
			'action'  => array(
				'type'             => 'search_stock_images',
				'label'            => 'Pretraga stock slika',
				'summary'          => 'Pretraga stock slika za "' . $query . '" (izvor: ' . $source . ', orijentacija: ' . $orientation . ', broj: ' . $count . ').',
				'rollback_plan'    => 'Read-only operacija, rollback nije potreban.',
				'rollback_support' => 'none',
				'targets'          => array(),
				'args'             => array(
					'query'       => $query,
					'source'      => $source,
					'orientation' => $orientation,
					'count'       => $count,
				),
			),
		);
	}

	/**
	 * Execute: search_stock_images
	 *
	 * @param array $action Action data from preview.
	 * @return array
	 */
	private function execute_search_stock_images_action( $action ) {
		$args = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();

		$query       = isset( $args['query'] ) ? sanitize_text_field( trim( (string) $args['query'] ) ) : '';
		$source      = isset( $args['source'] ) ? (string) $args['source'] : 'auto';
		$orientation = isset( $args['orientation'] ) ? (string) $args['orientation'] : 'landscape';
		$count       = isset( $args['count'] ) ? max( 1, min( 10, intval( $args['count'] ) ) ) : 5;

		if ( '' === $query ) {
			return array( 'success' => false, 'error' => 'Query parametar je prazan.' );
		}

		/* Determine source order based on routing. */
		$source_order = $this->determine_stock_image_source_order( $source );

		$images = array();

		foreach ( $source_order as $src ) {
			$results = $this->fetch_stock_images_from_source( $src, $query, $orientation, $count );
			if ( ! empty( $results ) ) {
				$images = $results;
				break;
			}
		}

		return array(
			'success'          => true,
			'summary'          => 'Pronadjeno ' . count( $images ) . ' stock slika za "' . $query . '".',
			'data'             => array(
				'query'       => $query,
				'source_used' => ! empty( $images ) && isset( $images[0]['source'] ) ? $images[0]['source'] : 'none',
				'count'       => count( $images ),
				'images'      => $images,
			),
			'executed_actions' => array(
				array(
					'type' => 'search_stock_images',
				),
			),
			'rollback_entries' => array(),
		);
	}

	/* ------------------------------------------------------------------
	 *  Smart routing: determine source order
	 * ------------------------------------------------------------------ */

	/**
	 * Determine the source order from the explicit source selector.
	 *
	 * @param string $source Requested source (auto, pexels, unsplash, lummi).
	 * @return array Ordered list of sources to try.
	 */
	private function determine_stock_image_source_order( $source ) {
		if ( 'pexels' === $source ) {
			return array( 'pexels', 'unsplash', 'lummi' );
		}
		if ( 'unsplash' === $source ) {
			return array( 'unsplash', 'pexels', 'lummi' );
		}
		if ( 'lummi' === $source ) {
			return array( 'lummi', 'pexels', 'unsplash' );
		}

		/* Auto mode uses a stable provider fallback order in every language. */
		return array( 'pexels', 'unsplash', 'lummi' );
	}

	/* ------------------------------------------------------------------
	 *  Fetch images from a specific source
	 * ------------------------------------------------------------------ */

	/**
	 * Fetch stock images from a single source API.
	 *
	 * @param string $source      Source name (pexels, unsplash, lummi).
	 * @param string $query       Search query.
	 * @param string $orientation Orientation filter.
	 * @param int    $count       Number of results.
	 * @return array Array of formatted image results.
	 */
	private function fetch_stock_images_from_source( $source, $query, $orientation, $count ) {
		switch ( $source ) {
			case 'pexels':
				return $this->fetch_pexels_images( $query, $orientation, $count );
			case 'unsplash':
				return $this->fetch_unsplash_images( $query, $orientation, $count );
			case 'lummi':
				return $this->fetch_lummi_images( $query, $orientation, $count );
			default:
				return array();
		}
	}

	/* ------------------------------------------------------------------
	 *  Pexels API
	 * ------------------------------------------------------------------ */

	/**
	 * Fetch images from Pexels API.
	 *
	 * @param string $query       Search query.
	 * @param string $orientation Orientation filter.
	 * @param int    $count       Number of results.
	 * @return array
	 */
	private function fetch_pexels_images( $query, $orientation, $count ) {
		$settings = get_option( 'niwa_bloging_settings', array() );
		$api_key  = isset( $settings['pexels_key'] ) ? (string) $settings['pexels_key'] : '';
		if ( '' === $api_key ) {
			return array();
		}

		$url = add_query_arg(
			array(
				'query'       => rawurlencode( $query ),
				'orientation' => $orientation,
				'per_page'    => $count,
			),
			'https://api.pexels.com/v1/search'
		);

		$response = wp_remote_get(
			$url,
			array(
				'timeout' => 10,
				'headers' => array(
					'Authorization' => $api_key,
				),
			)
		);

		if ( is_wp_error( $response ) ) {
			return array();
		}

		$code = wp_remote_retrieve_response_code( $response );
		if ( 200 !== $code ) {
			return array();
		}

		$body = json_decode( wp_remote_retrieve_body( $response ), true );
		if ( ! is_array( $body ) || empty( $body['photos'] ) ) {
			return array();
		}

		$images = array();
		foreach ( $body['photos'] as $photo ) {
			$photographer_name = isset( $photo['photographer'] ) ? (string) $photo['photographer'] : 'Unknown';
			$photographer_url  = isset( $photo['photographer_url'] ) ? (string) $photo['photographer_url'] : '';
			$source_url        = isset( $photo['url'] ) ? (string) $photo['url'] : '';

			$images[] = array(
				'url'         => isset( $photo['src']['original'] ) ? (string) $photo['src']['original'] : '',
				'thumbnail'   => isset( $photo['src']['medium'] ) ? (string) $photo['src']['medium'] : '',
				'photographer' => $photographer_name,
				'alt'         => isset( $photo['alt'] ) ? (string) $photo['alt'] : $query,
				'source'      => 'pexels',
				'license'     => 'Pexels License (free for commercial use)',
				'attribution' => 'Photo by <a href="' . esc_url( $photographer_url ) . '">' . esc_html( $photographer_name ) . '</a> on <a href="' . esc_url( $source_url ) . '">Pexels</a>',
				'width'       => isset( $photo['width'] ) ? intval( $photo['width'] ) : null,
				'height'      => isset( $photo['height'] ) ? intval( $photo['height'] ) : null,
			);
		}

		return array_slice( $images, 0, $count );
	}

	/* ------------------------------------------------------------------
	 *  Unsplash API
	 * ------------------------------------------------------------------ */

	/**
	 * Fetch images from Unsplash API.
	 *
	 * @param string $query       Search query.
	 * @param string $orientation Orientation filter.
	 * @param int    $count       Number of results.
	 * @return array
	 */
	private function fetch_unsplash_images( $query, $orientation, $count ) {
		$settings = get_option( 'niwa_bloging_settings', array() );
		$api_key  = isset( $settings['unsplash_key'] ) ? (string) $settings['unsplash_key'] : '';
		if ( '' === $api_key ) {
			return array();
		}

		$url = add_query_arg(
			array(
				'query'       => rawurlencode( $query ),
				'orientation' => $orientation,
				'per_page'    => $count,
				'client_id'   => $api_key,
			),
			'https://api.unsplash.com/search/photos'
		);

		$response = wp_remote_get(
			$url,
			array(
				'timeout' => 10,
				'headers' => array(
					'Accept-Version' => 'v1',
				),
			)
		);

		if ( is_wp_error( $response ) ) {
			return array();
		}

		$code = wp_remote_retrieve_response_code( $response );
		if ( 200 !== $code ) {
			return array();
		}

		$body = json_decode( wp_remote_retrieve_body( $response ), true );
		if ( ! is_array( $body ) || empty( $body['results'] ) ) {
			return array();
		}

		$images = array();
		foreach ( $body['results'] as $photo ) {
			$user              = isset( $photo['user'] ) && is_array( $photo['user'] ) ? $photo['user'] : array();
			$photographer_name = isset( $user['name'] ) ? (string) $user['name'] : 'Unknown';
			$photographer_url  = isset( $user['links']['html'] ) ? (string) $user['links']['html'] : '';

			$images[] = array(
				'url'         => isset( $photo['urls']['full'] ) ? (string) $photo['urls']['full'] : '',
				'thumbnail'   => isset( $photo['urls']['small'] ) ? (string) $photo['urls']['small'] : '',
				'photographer' => $photographer_name,
				'alt'         => isset( $photo['alt_description'] ) && '' !== (string) $photo['alt_description']
					? (string) $photo['alt_description']
					: $query,
				'source'      => 'unsplash',
				'license'     => 'Unsplash License (free for commercial use)',
				'attribution' => 'Photo by <a href="' . esc_url( $photographer_url ) . '?utm_source=niwa_bloging&utm_medium=referral">' . esc_html( $photographer_name ) . '</a> on <a href="https://unsplash.com/?utm_source=niwa_bloging&utm_medium=referral">Unsplash</a>',
				'width'       => isset( $photo['width'] ) ? intval( $photo['width'] ) : null,
				'height'      => isset( $photo['height'] ) ? intval( $photo['height'] ) : null,
			);
		}

		return array_slice( $images, 0, $count );
	}

	/* ------------------------------------------------------------------
	 *  Lummi API
	 * ------------------------------------------------------------------ */

	/**
	 * Fetch images from Lummi AI API.
	 *
	 * @param string $query       Search query.
	 * @param string $orientation Orientation filter.
	 * @param int    $count       Number of results.
	 * @return array
	 */
	private function fetch_lummi_images( $query, $orientation, $count ) {
		$settings = get_option( 'niwa_bloging_settings', array() );
		$api_key  = isset( $settings['lummi_key'] ) ? (string) $settings['lummi_key'] : '';
		if ( '' === $api_key ) {
			return array();
		}

		$url = add_query_arg(
			array(
				'query'       => rawurlencode( $query ),
				'orientation' => $orientation,
				'per_page'    => $count,
			),
			'https://api.lummi.ai/v1/search'
		);

		$response = wp_remote_get(
			$url,
			array(
				'timeout' => 10,
				'headers' => array(
					'Authorization' => 'Bearer ' . $api_key,
				),
			)
		);

		if ( is_wp_error( $response ) ) {
			return array();
		}

		$code = wp_remote_retrieve_response_code( $response );
		if ( 200 !== $code ) {
			return array();
		}

		$body = json_decode( wp_remote_retrieve_body( $response ), true );
		if ( ! is_array( $body ) || empty( $body['images'] ) ) {
			return array();
		}

		$images = array();
		foreach ( $body['images'] as $photo ) {
			$images[] = array(
				'url'         => isset( $photo['url'] ) ? (string) $photo['url'] : '',
				'thumbnail'   => isset( $photo['thumbnail'] ) ? (string) $photo['thumbnail'] : ( isset( $photo['url'] ) ? (string) $photo['url'] : '' ),
				'photographer' => 'Lummi AI',
				'alt'         => isset( $photo['alt'] ) && '' !== (string) $photo['alt']
					? (string) $photo['alt']
					: $query,
				'source'      => 'lummi',
				'license'     => 'Lummi AI License (free for commercial use)',
				'attribution' => 'Image from <a href="https://www.lummi.ai">Lummi AI</a>',
				'width'       => isset( $photo['width'] ) ? intval( $photo['width'] ) : null,
				'height'      => isset( $photo['height'] ) ? intval( $photo['height'] ) : null,
			);
		}

		return array_slice( $images, 0, $count );
	}

	/* ==================================================================
	 *  SCAN SITE FOR LINKING — Read-only
	 * ================================================================== */

	/**
	 * Preview: scan_site_for_linking
	 *
	 * @param array $args Tool arguments.
	 * @return array
	 */
	private function preview_scan_site_for_linking( $args ) {
		$post_content = isset( $args['post_content'] ) ? trim( (string) $args['post_content'] ) : '';
		if ( '' === $post_content ) {
			return array( 'success' => false, 'error' => 'Parametar post_content je obavezan za skeniranje linkova.' );
		}

		$post_title       = isset( $args['post_title'] ) ? sanitize_text_field( trim( (string) $args['post_title'] ) ) : '';
		$post_slug        = isset( $args['post_slug'] ) ? sanitize_text_field( trim( (string) $args['post_slug'] ) ) : '';
		$max_suggestions  = isset( $args['max_suggestions'] ) ? max( 1, min( 10, intval( $args['max_suggestions'] ) ) ) : 5;
		$priority_paths   = isset( $args['priority_paths'] ) && is_array( $args['priority_paths'] )
			? array_map( 'sanitize_text_field', $args['priority_paths'] )
			: array();

		$summary_parts = array( 'Skeniranje sajta za interne linkove' );
		if ( '' !== $post_title ) {
			$summary_parts[] = 'za post: "' . $post_title . '"';
		}
		$summary_parts[] = '(maks. ' . $max_suggestions . ' predloga)';

		return array(
			'success' => true,
			'action'  => array(
				'type'             => 'scan_site_for_linking',
				'label'            => 'Skeniranje sajta za interne linkove',
				'summary'          => implode( ' ', $summary_parts ),
				'rollback_plan'    => 'Read-only operacija, rollback nije potreban.',
				'rollback_support' => 'none',
				'targets'          => array(),
				'args'             => array(
					'post_content'    => $post_content,
					'post_title'      => $post_title,
					'post_slug'       => $post_slug,
					'max_suggestions' => $max_suggestions,
					'priority_paths'  => $priority_paths,
				),
			),
		);
	}

	/**
	 * Execute: scan_site_for_linking
	 *
	 * @param array $action Action data from preview.
	 * @return array
	 */
	private function execute_scan_site_for_linking_action( $action ) {
		$args = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();

		$post_content     = isset( $args['post_content'] ) ? trim( (string) $args['post_content'] ) : '';
		$post_title       = isset( $args['post_title'] ) ? sanitize_text_field( trim( (string) $args['post_title'] ) ) : '';
		$post_slug        = isset( $args['post_slug'] ) ? sanitize_text_field( trim( (string) $args['post_slug'] ) ) : '';
		$max_suggestions  = isset( $args['max_suggestions'] ) ? max( 1, min( 10, intval( $args['max_suggestions'] ) ) ) : 5;
		$priority_paths   = isset( $args['priority_paths'] ) && is_array( $args['priority_paths'] )
			? array_map( 'sanitize_text_field', $args['priority_paths'] )
			: array();

		if ( '' === $post_content ) {
			return array( 'success' => false, 'error' => 'post_content je prazan.' );
		}

		$content_map = $this->get_site_content_map_for_linking();
		$analysis    = ( new Niwa_AI_Blog_Quality_Gate() )->analyze_links(
			$post_content,
			$post_title,
			$post_slug,
			$content_map,
			$priority_paths,
			$max_suggestions
		);

		return array(
			'success'          => true,
			'summary'          => 'Pronadjeno ' . count( $analysis['suggestions'] ) . ' predloga za interne linkove i ' . count( $analysis['broken'] ) . ' pokvarenih linkova.',
			'data'             => array(
				'suggestions'   => $analysis['suggestions'],
				'selected_links' => $analysis['selected'],
				'broken_links'  => $analysis['broken'],
			),
			'executed_actions' => array(
				array(
					'type' => 'scan_site_for_linking',
				),
			),
			'rollback_entries' => array(),
		);
	}

	/* ------------------------------------------------------------------
	 *  Linking helpers
	 * ------------------------------------------------------------------ */

	/**
	 * Get all published content as a flat content map, with transient cache.
	 *
	 * @return array Array of items with keys: path, title, slug, type.
	 */
	private function get_site_content_map_for_linking() {
		$cache_key = Niwa_AI_Blog_Quality_Gate::CONTENT_MAP_TRANSIENT;
		$cached    = get_transient( $cache_key );

		if ( false !== $cached && is_array( $cached ) ) {
			return $cached;
		}

		$post_types = array( 'post', 'page' );
		if ( post_type_exists( 'product' ) ) {
			$post_types[] = 'product';
		}

		$content_map = array();
		$offset      = 0;
		$batch_size  = 100;

		while ( true ) {
			$posts = get_posts(
				array(
					'post_type'      => $post_types,
					'post_status'    => 'publish',
					'posts_per_page' => $batch_size,
					'offset'         => $offset,
					'orderby'        => 'date',
					'order'          => 'DESC',
					'no_found_rows'  => true,
					'fields'         => 'all',
				)
			);

			if ( empty( $posts ) ) {
				break;
			}

			foreach ( $posts as $post ) {
				$permalink = get_permalink( $post->ID );
				$path      = wp_parse_url( $permalink, PHP_URL_PATH );
				$path      = '/' . ltrim( (string) $path, '/' );
				$path      = '/' === $path ? '/' : rtrim( $path, '/' ) . '/';

				$content_map[] = array(
					'post_id' => intval( $post->ID ),
					'url'     => $permalink,
					'path'    => $path,
					'title'   => $post->post_title,
					'slug'    => $post->post_name,
					'type'    => $post->post_type,
					'focus_keyword' => (string) get_post_meta( $post->ID, Niwa_AI_Blog_Quality_Gate::META_FOCUS_KEYWORD, true ),
				);
			}

			$offset += $batch_size;

			if ( count( $posts ) < $batch_size ) {
				break;
			}
		}

		/* Cache for 1 hour. */
		set_transient( $cache_key, $content_map, HOUR_IN_SECONDS );

		return $content_map;
	}

}
