<?php
/**
 * MYAIO Schema Field Extractor API.
 *
 * Returns extracted schema fields for one requested page URL.
 * This endpoint only reads data and never deploys JSON-LD or edits page content.
 */

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

require_once plugin_dir_path( __FILE__ ) . '../includes/sac-utils.php';

add_action(
	'rest_api_init',
	function () {
		register_rest_route(
			'myaio/v1',
			'/schema-field-extract',
			array(
				'methods'             => 'POST',
				'callback'            => 'myaio_sfe_extract_schema_fields',
				'permission_callback' => 'myaio_sac_rest_permission_check',
				'args'                => array(
					'url'  => array(
						'required'          => true,
						'sanitize_callback' => 'esc_url_raw',
					),
					'type' => array(
						'required'          => true,
						'sanitize_callback' => 'sanitize_text_field',
					),
				),
			)
		);
	}
);

function myaio_sfe_extract_schema_fields( WP_REST_Request $request ) {
	$url  = esc_url_raw( (string) $request->get_param( 'url' ) );
	$type = strtolower( sanitize_key( (string) $request->get_param( 'type' ) ) );

	$type_map = array(
		'home'        => 'home',
		'homepage'    => 'home',
		'website'     => 'home',
		'service'     => 'service',
		'blog'        => 'blog_post',
		'blog_post'   => 'blog_post',
		'blog-post'   => 'blog_post',
		'post'        => 'blog_post',
		'article'     => 'blog_post',
	);

	if ( empty( $url ) || ! wp_http_validate_url( $url ) ) {
		return new WP_REST_Response(
			array(
				'success' => false,
				'error'   => 'invalid_url',
				'message' => 'A valid page URL is required.',
			),
			400
		);
	}

	if ( ! isset( $type_map[ $type ] ) ) {
		return new WP_REST_Response(
			array(
				'success' => false,
				'error'   => 'invalid_type',
				'message' => 'Type must be one of: home, service, blog_post.',
			),
			400
		);
	}

	$type    = $type_map[ $type ];
	$post_id = myaio_sfe_url_to_post_id_safe( $url );

	if ( $post_id > 0 && 'publish' !== get_post_status( $post_id ) ) {
		return new WP_REST_Response(
			array(
				'success'     => false,
				'error'       => 'page_unpublished',
				'message'     => 'This page is unpublished.',
				'remove_page' => true,
			),
			410
		);
	}

	$remote = myaio_sfe_fetch_html( $url );
	if ( is_wp_error( $remote ) ) {
		return new WP_REST_Response(
			array(
				'success' => false,
				'error'   => 'extraction_timeout',
				'message' => 'Extraction timeout. Please retry.',
			),
			504
		);
	}

	if ( ! empty( $remote['status'] ) && 404 === (int) $remote['status'] ) {
		return new WP_REST_Response(
			array(
				'success'     => false,
				'error'       => 'page_unpublished',
				'message'     => 'This page is unpublished.',
				'remove_page' => true,
			),
			410
		);
	}

	$html = isset( $remote['html'] ) ? (string) $remote['html'] : '';
	$ctx  = array(
		'url'     => $url,
		'html'    => $html,
		'post_id' => $post_id,
	);

	if ( 'home' === $type ) {
		$result = myaio_sfe_extract_home_fields( $ctx );
	} elseif ( 'service' === $type ) {
		$result = myaio_sfe_extract_service_fields( $ctx );
	} else {
		$result = myaio_sfe_extract_blog_post_fields( $ctx );
	}

	$result['success']      = true;
	$result['type']         = $type;
	$result['page_url']     = $url;
	$result['post_id']      = $post_id;
	$result['can_deploy']   = empty( $result['missing_fields'] );
	$result['deploy_block'] = ! empty( $result['missing_fields'] );
	$result['notice']       = empty( $result['missing_fields'] ) ? '' : 'Required fields are missing.';

	return rest_ensure_response( $result );
}

function myaio_sfe_url_to_post_id_safe( $url ) {
	$post_id = url_to_postid( $url );
	return $post_id ? absint( $post_id ) : 0;
}

function myaio_sfe_fetch_html( $url ) {
	$response = wp_remote_get(
		$url,
		array(
			'timeout'     => 15,
			'redirection' => 3,
			'user-agent'  => 'MYAIO Schema Field Extractor/' . get_bloginfo( 'version' ),
		)
	);

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

	return array(
		'status' => (int) wp_remote_retrieve_response_code( $response ),
		'html'   => (string) wp_remote_retrieve_body( $response ),
	);
}

function myaio_sfe_extract_home_fields( $ctx ) {
	$site_url    = home_url( '/' );
	$site_name   = get_bloginfo( 'name' );
	$description = myaio_sfe_meta_description( $ctx['html'], $ctx['post_id'] );
	$logo        = myaio_sfe_site_logo( $ctx['html'] );
	$social      = myaio_sfe_social_profiles( $ctx['html'] );

	$fields = array(
		'site_name'        => $site_name,
		'site_url'         => $site_url,
		'site_logo'        => $logo,
		'social_profiles'  => $social,
		'site_description' => $description,
	);

	$schema = array(
		'@context' => 'https://schema.org',
		'@graph'   => array(
			array(
				'@type'       => 'Organization',
				'@id'         => trailingslashit( $site_url ) . '#organization',
				'name'        => $site_name,
				'url'         => $site_url,
				'logo'        => array( '@type' => 'ImageObject', 'url' => $logo ),
				'sameAs'      => $social,
				'description' => $description,
			),
			array(
				'@type'       => 'WebSite',
				'@id'         => trailingslashit( $site_url ) . '#website',
				'url'         => $site_url,
				'name'        => $site_name,
				'description' => $description,
				'publisher'   => array( '@id' => trailingslashit( $site_url ) . '#organization' ),
			),
		),
	);

	return myaio_sfe_build_result( $fields, $schema, array( 'site_name', 'site_url', 'site_logo', 'social_profiles', 'site_description' ) );
}

function myaio_sfe_extract_service_fields( $ctx ) {
	$site_url    = home_url( '/' );
	$site_name   = get_bloginfo( 'name' );
	$description = myaio_sfe_meta_description( $ctx['html'], $ctx['post_id'] );
	$name        = myaio_sfe_meta_title( $ctx['html'], $ctx['post_id'] );
	$logo        = myaio_sfe_site_logo( $ctx['html'] );
	$area_served = myaio_sfe_area_served();

	$fields = array(
		'service_name'          => $name,
		'service_description'   => $description,
		'provider_organization' => $site_name,
		'provider_logo'         => $logo,
		'area_served'           => $area_served,
		'page_url'              => $ctx['url'],
	);

	$schema = array(
		'@context'   => 'https://schema.org',
		'@type'      => 'Service',
		'@id'        => trailingslashit( $ctx['url'] ) . '#service',
		'name'       => $name,
		'description'=> $description,
		'url'        => $ctx['url'],
		'provider'   => array(
			'@type' => 'Organization',
			'name'  => $site_name,
			'url'   => $site_url,
			'logo'  => array( '@type' => 'ImageObject', 'url' => $logo ),
		),
		'areaServed' => array( '@type' => 'Place', 'name' => $area_served ),
	);

	return myaio_sfe_build_result( $fields, $schema, array( 'service_name', 'service_description', 'provider_organization', 'provider_logo', 'area_served', 'page_url' ) );
}

function myaio_sfe_extract_blog_post_fields( $ctx ) {
	$post_id   = absint( $ctx['post_id'] );
	$headline  = myaio_sfe_meta_title( $ctx['html'], $post_id );
	$image     = myaio_sfe_post_image( $ctx['html'], $post_id );
	$published = $post_id ? get_the_date( 'c', $post_id ) : myaio_sfe_meta_attr( $ctx['html'], 'article:published_time' );
	$modified  = $post_id ? get_the_modified_date( 'c', $post_id ) : myaio_sfe_meta_attr( $ctx['html'], 'article:modified_time' );
	$author    = $post_id ? get_the_author_meta( 'display_name', (int) get_post_field( 'post_author', $post_id ) ) : myaio_sfe_meta_name( $ctx['html'], 'author' );
	$site_name = get_bloginfo( 'name' );
	$logo      = myaio_sfe_site_logo( $ctx['html'] );

	$fields = array(
		'headline'               => $headline,
		'image'                  => $image,
		'date_published'         => $published,
		'date_modified'          => $modified,
		'author'                 => $author,
		'publisher_organization' => $site_name,
		'publisher_logo'         => $logo,
		'page_url'               => $ctx['url'],
	);

	$schema = array(
		'@context'      => 'https://schema.org',
		'@type'         => 'BlogPosting',
		'@id'           => trailingslashit( $ctx['url'] ) . '#blogposting',
		'url'           => $ctx['url'],
		'headline'      => $headline,
		'image'         => array( '@type' => 'ImageObject', 'url' => $image ),
		'datePublished' => $published,
		'dateModified'  => $modified,
		'author'        => array( '@type' => 'Person', 'name' => $author ),
		'publisher'     => array(
			'@type' => 'Organization',
			'name'  => $site_name,
			'logo'  => array( '@type' => 'ImageObject', 'url' => $logo ),
		),
	);

	return myaio_sfe_build_result( $fields, $schema, array( 'headline', 'image', 'date_published', 'date_modified', 'author', 'publisher_organization', 'publisher_logo', 'page_url' ) );
}

function myaio_sfe_build_result( $fields, $schema, $required ) {
	$missing = array();
	foreach ( $required as $key ) {
		$value = isset( $fields[ $key ] ) ? $fields[ $key ] : '';
		if ( is_array( $value ) ) {
			if ( empty( $value ) ) {
				$missing[] = $key;
			}
		} elseif ( '' === trim( (string) $value ) ) {
			$missing[] = $key;
		}
	}

	return array(
		'fields'         => $fields,
		'missing_fields' => $missing,
		'preview_schema' => $schema,
		'json_ld'        => wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ),
	);
}

function myaio_sfe_meta_title( $html, $post_id = 0 ) {
	if ( $post_id ) {
		$title = get_post_meta( $post_id, '_yoast_wpseo_title', true );
		if ( empty( $title ) ) {
			$title = get_post_meta( $post_id, 'rank_math_title', true );
		}
		if ( empty( $title ) ) {
			$title = get_the_title( $post_id );
		}
		if ( ! empty( $title ) ) {
			return wp_strip_all_tags( (string) $title );
		}
	}

	$og = myaio_sfe_meta_attr( $html, 'og:title' );
	if ( $og ) {
		return $og;
	}

	if ( preg_match( '/<title[^>]*>(.*?)<\/title>/is', $html, $m ) ) {
		return trim( wp_strip_all_tags( html_entity_decode( $m[1], ENT_QUOTES, get_bloginfo( 'charset' ) ) ) );
	}

	return '';
}

function myaio_sfe_meta_description( $html, $post_id = 0 ) {
	if ( $post_id ) {
		$desc = get_post_meta( $post_id, '_yoast_wpseo_metadesc', true );
		if ( empty( $desc ) ) {
			$desc = get_post_meta( $post_id, 'rank_math_description', true );
		}
		if ( empty( $desc ) ) {
			$desc = get_the_excerpt( $post_id );
		}
		if ( ! empty( $desc ) ) {
			return trim( wp_strip_all_tags( (string) $desc ) );
		}
	}

	$desc = myaio_sfe_meta_name( $html, 'description' );
	if ( ! $desc ) {
		$desc = myaio_sfe_meta_attr( $html, 'og:description' );
	}
	return $desc;
}

function myaio_sfe_meta_name( $html, $name ) {
	$pattern = '/<meta[^>]+name=["\']' . preg_quote( $name, '/' ) . '["\'][^>]+content=["\']([^"\']*)["\'][^>]*>/i';
	if ( preg_match( $pattern, $html, $m ) ) {
		return trim( wp_strip_all_tags( html_entity_decode( $m[1], ENT_QUOTES, get_bloginfo( 'charset' ) ) ) );
	}
	return '';
}

function myaio_sfe_meta_attr( $html, $property ) {
	$pattern = '/<meta[^>]+(?:property|name)=["\']' . preg_quote( $property, '/' ) . '["\'][^>]+content=["\']([^"\']*)["\'][^>]*>/i';
	if ( preg_match( $pattern, $html, $m ) ) {
		return esc_url_raw( $m[1] ) === $m[1] ? esc_url_raw( $m[1] ) : trim( wp_strip_all_tags( html_entity_decode( $m[1], ENT_QUOTES, get_bloginfo( 'charset' ) ) ) );
	}
	return '';
}

function myaio_sfe_site_logo( $html ) {
	$custom_logo_id = get_theme_mod( 'custom_logo' );
	if ( $custom_logo_id ) {
		$src = wp_get_attachment_image_url( $custom_logo_id, 'full' );
		if ( $src ) {
			return esc_url_raw( $src );
		}
	}

	$site_icon = get_site_icon_url();
	if ( $site_icon ) {
		return esc_url_raw( $site_icon );
	}

	$og = myaio_sfe_meta_attr( $html, 'og:logo' );
	if ( $og ) {
		return esc_url_raw( $og );
	}

	if ( preg_match( '/<header[\s\S]*?<img[^>]+src=["\']([^"\']+)["\'][^>]*>/i', $html, $m ) ) {
		return esc_url_raw( myaio_sfe_abs_url( $m[1] ) );
	}

	return '';
}

function myaio_sfe_post_image( $html, $post_id ) {
	if ( $post_id && has_post_thumbnail( $post_id ) ) {
		$src = get_the_post_thumbnail_url( $post_id, 'full' );
		if ( $src ) {
			return esc_url_raw( $src );
		}
	}

	$og = myaio_sfe_meta_attr( $html, 'og:image' );
	if ( $og ) {
		return esc_url_raw( myaio_sfe_abs_url( $og ) );
	}

	if ( preg_match( '/<article[\s\S]*?<img[^>]+src=["\']([^"\']+)["\'][^>]*>/i', $html, $m ) ) {
		return esc_url_raw( myaio_sfe_abs_url( $m[1] ) );
	}

	return '';
}

function myaio_sfe_social_profiles( $html ) {
	$profiles = array();
	$domains  = array( 'facebook.com', 'linkedin.com', 'twitter.com', 'x.com', 'instagram.com', 'youtube.com', 'tiktok.com', 'pinterest.com' );

	if ( preg_match_all( '/<a[^>]+href=["\']([^"\']+)["\'][^>]*>/i', $html, $matches ) ) {
		foreach ( $matches[1] as $href ) {
			$href = esc_url_raw( myaio_sfe_abs_url( $href ) );
			foreach ( $domains as $domain ) {
				if ( false !== stripos( $href, $domain ) ) {
					$profiles[] = $href;
					break;
				}
			}
		}
	}

	return array_values( array_unique( array_filter( $profiles ) ) );
}

function myaio_sfe_area_served() {
	$option_keys = array( 'myaio_area_served', 'myaio_business_country', 'myaio_knowledge_graph_area_served' );
	foreach ( $option_keys as $key ) {
		$value = get_option( $key, '' );
		if ( is_string( $value ) && '' !== trim( $value ) ) {
			return sanitize_text_field( $value );
		}
	}
	return wp_parse_url( home_url( '/' ), PHP_URL_HOST );
}

function myaio_sfe_abs_url( $maybe_url ) {
	$maybe_url = trim( (string) $maybe_url );
	if ( '' === $maybe_url ) {
		return '';
	}
	if ( 0 === strpos( $maybe_url, '//' ) ) {
		return is_ssl() ? 'https:' . $maybe_url : 'http:' . $maybe_url;
	}
	if ( preg_match( '#^https?://#i', $maybe_url ) ) {
		return $maybe_url;
	}
	return esc_url_raw( home_url( '/' . ltrim( $maybe_url, '/' ) ) );
}
