<?php
/**
 * Unauthenticated REST endpoints for cross-site discovery and public team metadata.
 *
 * @package clanbite
 */

namespace Kernowdev\Clanbite;

defined( 'ABSPATH' ) || exit;


use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

/**
 * Registers read-only routes under `clanbite/v1` that do not require a logged-in user.
 */
final class Public_Rest {

	/**
	 * Register routes on `rest_api_init`.
	 *
	 * @return void
	 */
	public static function register_routes(): void {
		register_rest_route(
			'clanbite/v1',
			'/discovery',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => array( self::class, 'handle_discovery' ),
				'permission_callback' => '__return_true',
			)
		);

		register_rest_route(
			'clanbite/v1',
			'/site-sync-public-key',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => array( Cross_Site_Match_Sync::class, 'rest_site_sync_public_key' ),
				'permission_callback' => '__return_true',
			)
		);

		register_rest_route(
			'clanbite/v1',
			'/public-team',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => array( self::class, 'handle_public_team' ),
				'permission_callback' => '__return_true',
				'args'                => array(
					'slug' => array(
						'description'       => __( 'Team post slug (`cp_team` post_name).', 'clanbite' ),
						'type'              => 'string',
						'required'          => false,
						'sanitize_callback' => 'sanitize_title',
					),
					'url'  => array(
						'description'       => __( 'Full URL to a team profile page on a Clanbite site.', 'clanbite' ),
						'type'              => 'string',
						'required'          => false,
						'sanitize_callback' => 'esc_url_raw',
					),
				),
			)
		);
	}

	/**
	 * Discovery payload so remote sites can detect Clanbite and a compatible API version.
	 *
	 * @param WP_REST_Request $request Request (unused).
	 * @return WP_REST_Response
	 */
	public static function handle_discovery( WP_REST_Request $request ) {
		unset( $request );

		return new WP_REST_Response( self::build_discovery_payload(), 200 );
	}

	/**
	 * Build the Clanbite discovery payload (also used by the Abilities API).
	 *
	 * @return array<string, mixed>
	 */
	public static function build_discovery_payload(): array {
		$discovery = array(
			'clanbite' => true,
			'name'       => 'Clanbite',
			'version'    => Main::VERSION,
		);

		if ( function_exists( 'sodium_crypto_sign_keypair' ) ) {
			$discovery['match_sync'] = array(
				'ed25519'          => true,
				'public_key_route' => 'clanbite/v1/site-sync-public-key',
			);
		}

		return $discovery;
	}

	/**
	 * Return basic public data for a published team by slug or by parsing a profile URL.
	 *
	 * @param WP_REST_Request $request Request.
	 * @return WP_REST_Response|WP_Error
	 */
	public static function handle_public_team( WP_REST_Request $request ) {
		$result = self::get_public_team_data_by_slug_or_url(
			(string) $request->get_param( 'slug' ),
			(string) $request->get_param( 'url' )
		);

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

		return new WP_REST_Response( $result, 200 );
	}

	/**
	 * Resolve public team metadata by slug or absolute team profile URL.
	 *
	 * @param string $slug Requested `cp_team` post_name (may be empty when `url` is set).
	 * @param string $url  Full team profile URL (optional).
	 * @return array<string, mixed>|\WP_Error
	 */
	public static function get_public_team_data_by_slug_or_url( string $slug, string $url ) {
		if ( '' === $slug && '' !== $url ) {
			$parsed = function_exists( 'clanbite_parse_team_profile_url' ) ? clanbite_parse_team_profile_url( $url ) : null;
			if ( is_array( $parsed ) && ! empty( $parsed['slug'] ) ) {
				$slug = (string) $parsed['slug'];
			}
		}

		$slug = sanitize_title( $slug );
		if ( '' === $slug ) {
			return new WP_Error(
				'clanbite_public_team_missing_slug',
				__( 'A team slug or profile URL is required.', 'clanbite' ),
				array( 'status' => 400 )
			);
		}

		$posts = get_posts(
			array(
				'name'                   => $slug,
				'post_type'              => 'clanbite_team',
				'post_status'            => 'publish',
				'posts_per_page'         => 1,
				'no_found_rows'          => true,
				'update_post_meta_cache' => true,
				'update_post_term_cache' => false,
			)
		);

		$post = isset( $posts[0] ) && $posts[0] instanceof \WP_Post ? $posts[0] : null;
		if ( ! $post ) {
			return new WP_Error(
				'clanbite_public_team_not_found',
				__( 'Team not found.', 'clanbite' ),
				array( 'status' => 404 )
			);
		}

		$team_id  = (int) $post->ID;
		$logo_url = function_exists( 'clanbite_teams_get_display_team_avatar' )
			? clanbite_teams_get_display_team_avatar( $team_id, false, '', 'public_rest', 'medium' )
			: '';
		if ( '' === $logo_url && has_post_thumbnail( $team_id ) ) {
			$logo_url = (string) get_the_post_thumbnail_url( $team_id, 'medium' );
		}
		if ( '' === $logo_url && function_exists( 'clanbite_teams_get_default_avatar_url' ) ) {
			$logo_url = clanbite_teams_get_default_avatar_url( $team_id );
		}

		$motto   = '';
		$team_en = function_exists( 'clanbite_get_team' ) ? clanbite_get_team( $team_id ) : null;
		if ( $team_en && method_exists( $team_en, 'get_motto' ) ) {
			$motto = (string) $team_en->get_motto();
		}

		$country = '';
		if ( $team_en && method_exists( $team_en, 'get_country' ) ) {
			$country = (string) $team_en->get_country();
		} elseif ( '' !== (string) get_post_meta( $team_id, 'cp_team_country', true ) ) {
			$country = (string) get_post_meta( $team_id, 'cp_team_country', true );
		}

		$data = array(
			'id'          => $team_id,
			'title'       => get_the_title( $post ),
			'slug'        => $post->post_name,
			'permalink'   => get_permalink( $post ),
			'logoUrl'     => $logo_url,
			'motto'       => $motto,
			'country'     => $country,
			'description' => wp_strip_all_tags( (string) $post->post_excerpt ),
		);

		/**
		 * Filter the public team payload exposed to other Clanbite sites.
		 *
		 * @param array   $data Response data.
		 * @param WP_Post $post Team post.
		 */
		return (array) apply_filters( 'clanbite_public_team_response', $data, $post );
	}
}
