<?php
// File: modules/broken-links.php
// Broken Links Detection API Endpoint

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

// Shared helpers (API key validation + URL collectors if needed)
require_once plugin_dir_path(__FILE__) . '../includes/sac-utils.php';

add_action('rest_api_init', function () {
    register_rest_route('myaio/v1', '/broken-links', [
        'methods'             => WP_REST_Server::READABLE, // GET
        'callback'            => 'myaio_sac_broken_links_scan',
        'permission_callback' => 'myaio_sac_rest_permission_check',
    ]);
});

function myaio_sac_broken_links_scan( WP_REST_Request $request ) {

    // Keep EXACT unauthorized output
    $auth = myaio_sac_require_api_key_or_401($request);
    if ($auth !== true) return $auth;

    $urls           = function_exists('myaio_sac_get_all_crawlable_urls') ? myaio_sac_get_all_crawlable_urls() : [];
    $broken_summary = [];
    $total_broken   = 0;

    foreach ($urls as $url_data) {
        $page_url = $url_data['url'];
        $type     = $url_data['type'] ?? null;
        $category = $url_data['category'] ?? null;

        // Fetch page HTML (no custom timeout to avoid skipping long sites)
        $response = wp_remote_get($page_url, [
            'redirection' => 5,
        ]);

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

        $html = wp_remote_retrieve_body($response);
        if (empty($html)) {
            continue;
        }

        libxml_use_internal_errors(true);
        $dom = new DOMDocument();
        @$dom->loadHTML($html);

        $links        = $dom->getElementsByTagName('a');
        $broken_links = [];

        foreach ($links as $link) {
            $href = $link->getAttribute('href');

            if (
                empty($href) ||
                ! preg_match('/^https?:\/\//i', $href) ||
                ! filter_var($href, FILTER_VALIDATE_URL)
            ) {
                continue;
            }

            // Prefer HEAD; if blocked, fallback to small GET
            $head = wp_remote_head($href, [
                'redirection' => 3,
            ]);

            if (is_wp_error($head)) {
                // Fallback GET (some hosts block HEAD)
                $get = wp_remote_get($href, [
                    'redirection' => 3,
                    'headers'     => ['Range' => 'bytes=0-1023'],
                ]);

                if (is_wp_error($get)) {
                    $status = $get->get_error_message();
                    $broken_links[] = ['url' => $href, 'status' => $status];
                    $total_broken++;
                    continue;
                }

                $status = (int) wp_remote_retrieve_response_code($get);
                if ($status >= 400) {
                    $broken_links[] = ['url' => $href, 'status' => $status];
                    $total_broken++;
                }

                continue;
            }

            $status = (int) wp_remote_retrieve_response_code($head);

            if ($status >= 400) {
                $broken_links[] = [
                    'url'    => $href,
                    'status' => $status,
                ];
                $total_broken++;
            }
        }

        if (!empty($broken_links)) {
            $broken_summary[] = [
                'page_url'     => $page_url,
                'type'         => $type,
                'category'     => $category,
                'broken_links' => $broken_links,
            ];
        }
    }

    return rest_ensure_response([
        'summary' => [
            'total_pages_scanned'     => count($urls),
            'pages_with_broken_links' => count($broken_summary),
            'total_broken_links'      => $total_broken,
        ],
        'pages' => $broken_summary,
    ]);
}

/**
 * Fallback URL-gathering logic (only used if another module didn't already define it).
 * Output format matches what broken-links expects: url, type, category.
 */
if ( ! function_exists('myaio_sac_get_all_crawlable_urls') ) {
    function myaio_sac_get_all_crawlable_urls() {
        $urls = [];

        // Posts
        $posts = get_posts([
            'post_type'   => 'post',
            'post_status' => 'publish',
            'numberposts' => -1,
        ]);

        foreach ($posts as $post) {
            $categories = get_the_category($post->ID);
            $category_name = ($categories && !is_wp_error($categories)) ? $categories[0]->name : 'Uncategorized';

            $urls[] = [
                'url'      => get_permalink($post),
                'type'     => 'Post',
                'category' => $category_name,
            ];
        }

        // Pages
        $pages = get_posts([
            'post_type'   => 'page',
            'post_status' => 'publish',
            'numberposts' => -1,
        ]);

        foreach ($pages as $page) {
            $urls[] = [
                'url'      => get_permalink($page),
                'type'     => 'Page',
                'category' => null,
            ];
        }

        // Categories
        $cats = get_categories();
        foreach ($cats as $cat) {
            $urls[] = [
                'url'      => get_category_link($cat->term_id),
                'type'     => 'Category',
                'category' => $cat->name,
            ];
        }

        return $urls;
    }
}
