<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Redirects Detection API Endpoint
 * GET /wp-json/myaio/v1/redirects
 *
 * Auth:
 * - Header: x-api-key
 * - Or query/body: key
 * - Or query/body: api_key
 *
 * Validation logic is centralized in includes/sac-utils.php:
 * - myaio_sac_rest_permission_check()
 */

add_action(
	'rest_api_init',
	function () {
		register_rest_route(
			'myaio/v1',
			'/redirects',
			array(
				'methods'             => 'GET',
				'callback'            => 'myaio_sac_redirects_scan',
				'permission_callback' => function ( WP_REST_Request $request ) {
					if ( function_exists( 'myaio_sac_rest_permission_check' ) ) {
						return myaio_sac_rest_permission_check( $request );
					}
					return new WP_Error(
						'unauthorized',
						'Auth utilities not loaded',
						array( 'status' => 401 )
					);
				},
			)
		);
	}
);

/**
 * Scan site URLs for redirects without relying on set_time_limit().
 *
 * @param WP_REST_Request $request Request.
 * @return WP_REST_Response
 */
function myaio_sac_redirects_scan( WP_REST_Request $request ) {

	$http_timeout = 30;
	$max_chain    = 8;

	// Backward compatible URL source:
	// 1) old function used by previous modules
	// 2) fallback to the new shared helper in sac-utils.php
	if ( function_exists( 'myaio_sac_get_all_crawlable_urls' ) ) {
		$urls = myaio_sac_get_all_crawlable_urls();
	} elseif ( function_exists( 'myaio_sac_get_all_site_urls' ) ) {
		$urls = myaio_sac_get_all_site_urls();
	} else {
		return rest_ensure_response(
			array(
				'error' => 'No crawlable URL provider found (myaio_sac_get_all_crawlable_urls / myaio_sac_get_all_site_urls)',
			)
		);
	}

	if ( ! is_array( $urls ) ) {
		return rest_ensure_response(
			array(
				'error' => 'Crawlable URL provider did not return an array',
			)
		);
	}

	$results         = array();
	$total_redirects = 0;

	foreach ( $urls as $url_data ) {
		$page_url = '';
		if ( is_array( $url_data ) && isset( $url_data['url'] ) ) {
			$page_url = (string) $url_data['url'];
		}

		$page_url = esc_url_raw( $page_url );
		if ( '' === $page_url ) {
			continue;
		}

		$type     = ( is_array( $url_data ) && isset( $url_data['type'] ) ) ? sanitize_text_field( (string) $url_data['type'] ) : '';
		$category = ( is_array( $url_data ) && isset( $url_data['category'] ) ) ? sanitize_text_field( (string) $url_data['category'] ) : '';

		// First hop (NO auto-follow).
		$first = wp_remote_get(
			$page_url,
			array(
				'timeout'     => $http_timeout,
				'redirection' => 0,
				'headers'     => array(
					'User-Agent' => 'WP Redirect Scanner/1.0',
				),
			)
		);

		if ( is_wp_error( $first ) ) {
			$results[] = array(
				'url'      => $page_url,
				'type'     => $type,
				'category' => $category,
				'error'    => $first->get_error_message(),
			);
			continue;
		}

		$status  = (int) wp_remote_retrieve_response_code( $first );
		$headers = wp_remote_retrieve_headers( $first );

		$location = '';
		if ( is_array( $headers ) && isset( $headers['location'] ) ) {
			$location = $headers['location'];
		} elseif ( is_object( $headers ) && isset( $headers->location ) ) {
			$location = $headers->location;
		}

		// Normalize location (can be array in some cases).
		if ( is_array( $location ) ) {
			$location = reset( $location );
		}
		$location = is_string( $location ) ? trim( $location ) : '';

		$is_redirect = ( $status >= 300 && $status < 400 && '' !== $location );

		$item = array(
			'url'         => $page_url,
			'type'        => $type,
			'category'    => $category,
			'status'      => $status,
			'is_redirect' => $is_redirect,
			'location'    => $is_redirect ? $location : '',
		);

		if ( $is_redirect ) {
			$total_redirects++;

			$chain   = array();
			$current = $page_url;

			for ( $i = 0; $i < $max_chain; $i++ ) {
				$hop = wp_remote_get(
					$current,
					array(
						'timeout'     => $http_timeout,
						'redirection' => 0,
						'headers'     => array(
							'User-Agent' => 'WP Redirect Scanner/1.0',
						),
					)
				);

				if ( is_wp_error( $hop ) ) {
					$chain[] = array(
						'from'   => $current,
						'status' => 'error',
						'to'     => '',
						'error'  => $hop->get_error_message(),
					);
					break;
				}

				$hop_status  = (int) wp_remote_retrieve_response_code( $hop );
				$hop_headers = wp_remote_retrieve_headers( $hop );

				$hop_location = '';
				if ( is_array( $hop_headers ) && isset( $hop_headers['location'] ) ) {
					$hop_location = $hop_headers['location'];
				} elseif ( is_object( $hop_headers ) && isset( $hop_headers->location ) ) {
					$hop_location = $hop_headers->location;
				}

				if ( is_array( $hop_location ) ) {
					$hop_location = reset( $hop_location );
				}
				$hop_location = is_string( $hop_location ) ? trim( $hop_location ) : '';

				$hop_is_redirect = ( $hop_status >= 300 && $hop_status < 400 && '' !== $hop_location );

				$next = $hop_is_redirect ? myaio_sac_resolve_url( $current, $hop_location ) : '';

				$chain[] = array(
					'from'   => $current,
					'status' => $hop_status,
					'to'     => $next,
				);

				if ( ! $hop_is_redirect ) {
					break;
				}

				// Loop guard.
				if ( $next === $current || '' === $next ) {
					break;
				}

				$current = $next;
			}

			$item['redirect_chain'] = $chain;
			$item['final_url']      = $current;
		}

		$results[] = $item;
	}

	$redirect_urls = array();
	foreach ( $results as $r ) {
		if ( is_array( $r ) && ! empty( $r['is_redirect'] ) ) {
			$redirect_urls[] = $r;
		}
	}

	return rest_ensure_response(
		array(
			'summary'       => array(
				'total_pages_scanned' => count( $urls ),
				'total_urls_returned' => count( $results ),
				'total_redirecting'   => $total_redirects,
			),
			'all_urls'      => $results,
			'redirect_urls' => $redirect_urls,
		)
	);
}

/**
 * Resolve redirect location to an absolute URL.
 *
 * @param string $base Base URL.
 * @param string $location Location header.
 * @return string
 */
function myaio_sac_resolve_url( $base, $location ) {
	$base     = (string) $base;
	$location = (string) $location;

	if ( preg_match( '/^https?:\/\//i', $location ) ) {
		return $location;
	}

	if ( 0 === strpos( $location, '//' ) ) {
		$scheme = wp_parse_url( $base, PHP_URL_SCHEME );
		$scheme = $scheme ? $scheme : 'https';
		return $scheme . ':' . $location;
	}

	$base_parts = wp_parse_url( $base );
	if ( ! is_array( $base_parts ) || empty( $base_parts['host'] ) ) {
		return $location;
	}

	$scheme = ! empty( $base_parts['scheme'] ) ? $base_parts['scheme'] : 'https';
	$host   = $base_parts['host'];
	$port   = ! empty( $base_parts['port'] ) ? ':' . $base_parts['port'] : '';

	if ( 0 === strpos( $location, '/' ) ) {
		return $scheme . '://' . $host . $port . $location;
	}

	$path = ! empty( $base_parts['path'] ) ? $base_parts['path'] : '/';
	$dir  = preg_replace( '#/[^/]*$#', '/', $path );

	return $scheme . '://' . $host . $port . $dir . $location;
}