<?php
/**
 * Start_post tool: create a draft post and a server-side session buffer.
 *
 * @package AgenticWP
 */

namespace Agentic_WP;

use Agentic_WP\Error_Handler;

defined( 'ABSPATH' ) || exit;

/**
 * Start post tool for creating draft posts and session buffers.
 *
 * @since 1.0.0
 */
class Tool_Start_Post {
	/**
	 * Returns the OpenAI tool schema for starting a post.
	 *
	 * @since 1.0.0
	 *
	 * @return array Tool schema definition.
	 */
	public static function schema(): array {
		return array(
			'type'        => 'function',
			'name'        => 'start_post',
			'description' => 'Start a new post builder session. Returns post_id and session_id.',
			'strict'      => true,
			'parameters'  => array(
				'type'                 => 'object',
				'properties'           => array(
					'title'     => array(
						'type'        => 'string',
						'description' => 'Initial post title.',
					),
					'post_type' => array(
						'type'        => 'string',
						'description' => 'Post type to create (e.g., post, page, product, event). Must be a registered post type that supports content editing.',
					),
				),
				'required'             => array( 'title', 'post_type' ),
				'additionalProperties' => false,
			),
		);
	}

	/**
	 * Executes the start post tool.
	 *
	 * @since 1.0.0
	 *
	 * @param array $args Tool arguments containing title and post_type.
	 * @return string JSON response or error message.
	 */
	public static function run( array $args ): string {
		if ( ! function_exists( 'wp_insert_post' ) ) {
			return 'ERROR: wp_unavailable';
		}
		$title     = isset( $args['title'] ) && is_string( $args['title'] ) ? sanitize_text_field( $args['title'] ) : '(Draft)';
		$post_type = 'post';
		if ( isset( $args['post_type'] ) && is_string( $args['post_type'] ) ) {
			$maybe = sanitize_key( $args['post_type'] );
			if ( self::validate_post_type( $maybe ) ) {
				$post_type = $maybe;
			} else {
				return 'ERROR: invalid_post_type';
			}
		}

		$post_type_obj = get_post_type_object( $post_type );
		if ( ! $post_type_obj || ! current_user_can( $post_type_obj->cap->create_posts ) ) {
			return 'ERROR: insufficient_permissions';
		}

		$post_id = wp_insert_post(
			array(
				'post_type'   => $post_type,
				'post_status' => 'draft',
				'post_title'  => $title,
			),
			true
		);
		if ( is_wp_error( $post_id ) ) {
			Error_Handler::log_error(
				'tool_start_post',
				$post_id,
				array(
					'post_type' => $post_type,
					'title'     => $title,
				)
			);
			return 'ERROR: post_create_failed';
		}

		if ( ! $post_id ) {
			Error_Handler::log_error(
				'tool_start_post',
				'wp_insert_post returned 0',
				array(
					'post_type' => $post_type,
					'title'     => $title,
				)
			);
			return 'ERROR: post_create_failed';
		}

		$session = self::create_session( (int) $post_id, (string) $post_type );

		$json = wp_json_encode(
			array(
				'post_id'    => (int) $post_id,
				'post_type'  => (string) $post_type,
				'session_id' => (string) $session['session_id'],
				'status'     => 'draft',
			)
		);

		if ( false === $json ) {
			return 'ERROR: json_encoding_failed';
		}

		return $json;
	}

	/**
	 * Generates transient key for session ID.
	 *
	 * @since 1.0.0
	 *
	 * @param string $sid Session ID.
	 * @return string Transient key.
	 */
	public static function tkey( string $sid ): string {
		return 'agenticwp_post_session_' . preg_replace( '/[^a-zA-Z0-9_-]/', '', $sid );
	}

	/**
	 * Creates a post editing session.
	 *
	 * @since 1.0.0
	 *
	 * @param int    $post_id   Post ID.
	 * @param string $post_type Post type.
	 * @return array Session data with session_id and session keys.
	 */
	private static function create_session( int $post_id, string $post_type ): array {
		$session_id = function_exists( 'wp_generate_uuid4' ) ? wp_generate_uuid4() : wp_unique_id( 'agenticwp_' );
		$timeout    = max( 5, (int) Settings::get_session_timeout_min() ) * MINUTE_IN_SECONDS;

		$session_data = array(
			'post_id'     => $post_id,
			'post_type'   => $post_type,
			'created_at'  => time(),
			'bytes_total' => 0,
			'content'     => '',
		);

		set_transient( self::tkey( $session_id ), $session_data, $timeout );

		return array(
			'session_id' => $session_id,
			'session'    => $session_data,
		);
	}

	/**
	 * Validates post type for content editing.
	 *
	 * @since 1.0.0
	 *
	 * @param mixed $post_type Post type to validate.
	 * @return bool True if valid, false otherwise.
	 */
	private static function validate_post_type( $post_type ) {
		$post_type_obj = get_post_type_object( $post_type );
		if ( ! $post_type_obj ) {
			return false;
		}

		if ( ! post_type_supports( $post_type, 'editor' ) ) {
			return false;
		}

		$excluded = array( 'attachment', 'revision', 'nav_menu_item', 'custom_css', 'customize_changeset' );
		if ( in_array( $post_type, $excluded, true ) ) {
			return false;
		}

		return current_user_can( $post_type_obj->cap->create_posts );
	}
}
