<?php

namespace Waypoint\Agent\Rest\Handler;

use Waypoint\Agent\Helpers\Posts;

class Content {

	public function handle_post( \WP_REST_Request $request ): \WP_REST_Response {
		$external_id   = sanitize_text_field( (string) $request->get_param( 'external_id' ) );
		$title         = sanitize_text_field( (string) $request->get_param( 'title' ) );
		$slug          = sanitize_title( (string) $request->get_param( 'slug' ) );
		$content       = (string) $request->get_param( 'content' );
		$meta_desc     = sanitize_text_field( (string) ( $request->get_param( 'meta_description' ) ?? '' ) );
		$action_type   = sanitize_text_field( (string) ( $request->get_param( 'action_type' ) ?? 'new' ) );
		$improve_of_id = (int) ( $request->get_param( 'improve_of_post_id' ) ?? 0 );
		$expand_of_id  = (int) ( $request->get_param( 'expand_of_post_id' ) ?? 0 );
		$overwrite     = (bool) $request->get_param( 'overwrite' );
		$raw_status    = sanitize_text_field( (string) ( $request->get_param( 'status' ) ?? 'draft' ) );
		$post_status   = in_array( $raw_status, [ 'draft', 'publish', 'pending', 'private' ], true ) ? $raw_status : 'draft';

		$missing = [];
		foreach ( [ 'external_id' => $external_id, 'title' => $title, 'slug' => $slug, 'content' => $content ] as $key => $value ) {
			if ( '' === $value ) {
				$missing[] = $key;
			}
		}
		if ( ! empty( $missing ) ) {
			return rest_ensure_response( new \WP_Error(
				'rest_missing_callback_param',
				sprintf( 'Missing parameter(s): %s', implode( ', ', $missing ) ),
				[ 'status' => 400 ]
			) );
		}

		$existing = Posts::find_by_external_id( $external_id );
		if ( $existing ) {
			if ( ! $overwrite ) {
				return rest_ensure_response( [
					'post_id'     => $existing->ID,
					'status'      => 'existing',
					'external_id' => $external_id,
					'edit_url'    => get_edit_post_link( $existing->ID, 'raw' ),
				] );
			}
			wp_delete_post( $existing->ID, true );
		}

		// Block grammar contains Gutenberg comment markers and JSON. wp_kses_post
		// strips HTML comments and can destroy the block structure. This endpoint is
		// HMAC-only, so we temporarily remove KSES filters around insertion.
		kses_remove_filters();
		$post_id = wp_insert_post( [
			'post_title'   => $title,
			'post_name'    => $slug,
			'post_content' => $content,
			'post_status'  => $post_status,
			'post_type'    => 'page',
		], true );
		kses_init_filters();

		if ( is_wp_error( $post_id ) ) {
			return rest_ensure_response( new \WP_Error(
				'waypoint_agent_insert_failed',
				$post_id->get_error_message(),
				[ 'status' => 500 ]
			) );
		}

		update_post_meta( $post_id, '_waypoint_external_id', $external_id );
		update_post_meta( $post_id, '_waypoint_action_type', $action_type );

		if ( $improve_of_id > 0 ) {
			update_post_meta( $post_id, '_waypoint_improve_of', $improve_of_id );
		}
		if ( $expand_of_id > 0 ) {
			update_post_meta( $post_id, '_waypoint_expand_of', $expand_of_id );
		}
		if ( '' !== $meta_desc ) {
			update_post_meta( $post_id, 'rank_math_description', $meta_desc );
			update_post_meta( $post_id, '_yoast_wpseo_metadesc', $meta_desc );
		}

		return rest_ensure_response( [
			'post_id'     => $post_id,
			'status'      => 'created',
			'post_status' => $post_status,
			'external_id' => $external_id,
			'edit_url'    => get_edit_post_link( $post_id, 'raw' ),
		] );
	}

	public function handle_get( \WP_REST_Request $request ): \WP_REST_Response|\WP_Error {
		$external_id = rawurldecode( $request->get_param( 'external_id' ) );
		$post        = Posts::find_by_external_id( $external_id );

		if ( ! $post ) {
			return new \WP_Error(
				'waypoint_agent_not_found',
				sprintf( 'No post found for external_id: %s', $external_id ),
				[ 'status' => 404 ]
			);
		}

		return rest_ensure_response( [
			'post_id'     => $post->ID,
			'external_id' => $external_id,
			'title'       => get_the_title( $post->ID ),
			'slug'        => $post->post_name,
			'status'      => $post->post_status,
			'edit_url'    => get_edit_post_link( $post->ID, 'raw' ),
		] );
	}
}
