<?php
/**
 * Backlink Agent — SearchShifter Authority
 *
 * Discovers → verifies → logs AI-visible backlinks
 * with evidence attachments.
 *
 * Uses M5 Backlink Framework for database storage:
 *  - ss_log_backlink (hook)
 *  - SS_Backlinks::add_evidence
 *
 * Authority-only module.
 */

if (! defined('__DIR__')) {
    // noop for linting — ABSPATH check below is the actual gate.
}

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

/** AUTHORITY PLAN ONLY */
if (function_exists('ss_is_authority') && ! ss_is_authority()) {
    return;
}

if (!class_exists('SS_Backlink_Agent')) :

class SS_Backlink_Agent {

    const DIR = WP_CONTENT_DIR . '/uploads/searchshifter/backlinks';

    /**
     * Instance holder
     * @var SS_Backlink_Agent|null
     */
    protected static $instance = null;

    /**
     * Create and return the singleton instance.
     * Called by SS_Setup via init() or will auto-init when file included (if desired).
     */
    public static function init() {
        if ( self::$instance === null ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Static menu callback shim for setups that register a menu using
     * ['SS_Backlink_Agent', 'render_admin_page'].
     */
    public static function render_admin_page() {
        $inst = self::init();
        $inst->page_html();
    }

    public function __construct() {
        // Only attach admin menu when in WP Admin
        if ( is_admin() ) {
            add_action('admin_menu', [$this, 'admin_page']);
        }

        // AJAX (authenticated)
        add_action('wp_ajax_ss_backlink_scan', [$this, 'ajax_scan']);

        // Cron hook
        add_action('ss_backlink_scan_cron', [$this, 'run_scan']);
        if ( ! wp_next_scheduled('ss_backlink_scan_cron') ) {
            wp_schedule_event( time(), 'hourly', 'ss_backlink_scan_cron' );
        }

        add_action('wp_ajax_ss_backlink_evidence', [$this, 'ajax_evidence']);


        // Ensure data dir exists
        if ( ! file_exists( self::DIR ) ) {
            wp_mkdir_p( self::DIR );
        }
    }

    /** ------------------------------------
     * ADMIN: register submenu
     * ------------------------------------*/
    public function admin_page() {
        // parent slug may differ — adjust to your plugin main slug
        add_submenu_page(
            'searchshifter-main',
            'Backlink Agent',
            'Backlink Agent',
            'manage_options',
            'ss-backlink-agent',
            [$this, 'page_html']
        );
    }

    /** ------------------------------------
     * Admin page HTML
     * ------------------------------------*/
    public function page_html() {
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( esc_html__( 'Permission denied', 'searchshifter' ) );
        }
        $nonce = wp_create_nonce('ss_backlink_scan');
        $evidence_nonce = wp_create_nonce('searchshifter_ajax_evidence');
        ?>
        <div class="wrap">
            <h1>Backlink Agent</h1>
            <p>Discover → verify → log AI-visible backlinks with evidence.</p>

            <p>
                <button id="ss_bl_btn" class="button button-primary">Run Backlink Scan</button>
                <span id="ss_bl_spinner" style="display:none;margin-left:10px;">Running…</span>
            </p>
            <div id="ss_bl_summary" class="ss-card"></div>
            <table class="widefat striped" id="ss_bl_table" style="display:none">
            <thead>
                <tr>
                <th>Source</th>
                <th>Anchor Text</th>
                <th>AI Visibility</th>
                <th>Evidence</th>
                </tr>
            </thead>
            <tbody></tbody>
            </table>

            <div id="ss_bl_modal" style="display:none;">
                <div class="ss-modal-inner">
                    <h3>Backlink Evidence</h3>
                    <div id="ss_bl_modal_content"></div>
                    <p style="margin-top:15px;">
                        <button class="button" id="ss_bl_modal_close">Close</button>
                    </p>
                </div>
            </div>

            <style>
            #ss_bl_modal{
                position:fixed;
                inset:0;
                background:rgba(0,0,0,.5);
                z-index:9999;
            }
            .ss-modal-inner{
                background:#fff;
                max-width:600px;
                margin:10% auto;
                padding:20px;
                border-radius:8px;
            }
            </style>

            <script>
            (function($){
                $('#ss_bl_btn').on('click', function(){
                    $('#ss_bl_out').text('');
                    $('#ss_bl_spinner').show();
                    $.post(ajaxurl, {
                        action: 'ss_backlink_scan',
                        _nonce: '<?php echo esc_js($nonce); ?>'
                    }, function(res){
                        $('#ss_bl_spinner').hide();
                       if (!res.success || !res.data.ok) {
                        $('#ss_bl_summary').html('<p>Scan failed</p>');
                        return;
                        }

                        const data = res.data;

                        // Summary
                        $('#ss_bl_summary').html(`
                        <h3>Backlink Scan Summary</h3>
                        <p><strong>Domain:</strong> ${data.domain}</p>
                        <p><strong>Backlinks Found:</strong> ${data.found}</p>
                        <p><strong>Status:</strong> ✅ Authority signals detected</p>
                        <p style="color:#555;margin-top:8px">
                            These backlinks help AI systems recognize your brand.
                        </p>
                        `);

                        // Table
                        const tbody = $('#ss_bl_table tbody');
                        tbody.empty();

                        data.results.forEach(r => {
                            tbody.append(`
                            <tr>
                            <td><a href="${r.source}" target="_blank">${r.source}</a></td>
                            <td>${r.anchor}</td>
                            <td>✅ Yes</td>
                            <td>
                                <button 
                                class="button ss-bl-view"
                                data-source="${r.source}"
                                data-anchor="${r.anchor}">
                                View
                                </button>
                            </td>
                            </tr>
                            `);

                        });

                        $('#ss_bl_table').show();

                    }).fail(function(xhr){
                        $('#ss_bl_spinner').hide();
                        var txt = 'Request failed: ' + (xhr.responseText || xhr.statusText || 'Unknown');
                        $('#ss_bl_out').text(txt);
                    });
                });

                $(document).on('click', '.ss-bl-view', function(){

                const source = $(this).data('source');
                const anchor = $(this).data('anchor');

                $('#ss_bl_modal').show();
                $('#ss_bl_modal_content').html('<p>Loading evidence…</p>');

                $.post(ajaxurl, {
                    action: 'ss_backlink_evidence',
                    source: source,
                    anchor: anchor,
                    nonce: '<?php echo esc_js($evidence_nonce); ?>'
                }, function(res){

                    if (!res.success) {
                        $('#ss_bl_modal_content').html('<p>Evidence not found</p>');
                        return;
                    }

                    const e = res.data;

                    $('#ss_bl_modal_content').html(`
                        <p><strong>Source:</strong> <a href="${e.source}" target="_blank">${e.source}</a></p>
                        <p><strong>Status:</strong> ${e.verified ? '✅ AI-visible' : '❌ Not detected'}</p>

                        <h4>Why this matters</h4>
                        <p>This page contains a public reference to your brand.  
                        AI systems treat this as an authority signal.</p>

                        <h4>Detected reference</h4>
                        <blockquote>${e.anchor}</blockquote>
                    `);
                });
            });

            $('#ss_bl_modal_close').on('click', function(){
                $('#ss_bl_modal').hide();
            });

            })(jQuery);
            </script>
        </div>
        <?php
    }

    /** ------------------------------------
     * AJAX endpoint
     * ------------------------------------*/
    public function ajax_scan() {
        if ( ! current_user_can('manage_options') ) {
            wp_send_json_error(['error' => 'Permission denied'], 403);
        }

        if ( ! check_ajax_referer('ss_backlink_scan', '_nonce', false) ) {
            wp_send_json_error(['error' => 'Invalid nonce'], 400);
        }

        $res = $this->run_scan();

        if ( is_wp_error($res) ) {
            wp_send_json_error(['error' => $res->get_error_message()], 500);
        }

        wp_send_json_success($res);
    }


    public function ajax_evidence() {

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( 'Permission denied', 403 );
        }

        // ✅ NONCE CHECK (MANDATORY)
        if (
            ! isset( $_POST['nonce'] ) ||
            ! wp_verify_nonce(
                sanitize_text_field( wp_unslash( $_POST['nonce'] ) ),
                'searchshifter_ajax_evidence'
            )
        ) {
            wp_send_json_error( 'Invalid nonce', 403 );
        }

        // ✅ UNSLASH → SANITIZE
        $source = isset( $_POST['source'] )
            ? esc_url_raw( wp_unslash( $_POST['source'] ) )
            : '';

        $anchor = isset( $_POST['anchor'] )
            ? sanitize_text_field( wp_unslash( $_POST['anchor'] ) )
            : '';

        if ( ! $source || ! $anchor ) {
            wp_send_json_error( 'Missing data', 400 );
        }

        // Fetch page HTML
        $response = wp_remote_get( $source, [ 'timeout' => 15 ] );

        if ( is_wp_error( $response ) ) {
            wp_send_json_error( 'Request failed', 500 );
        }

        $html  = wp_remote_retrieve_body( $response );
        $found = false;

        if ( $html && stripos( $html, $anchor ) !== false ) {
            $found = true;
        }

        wp_send_json_success( [
            'source'   => $source,
            'anchor'   => $anchor,
            'verified' => $found,
            'snippet'  => $found
                ? wp_trim_words( wp_strip_all_tags( $html ), 40 )
                : null,
        ] );
    }



    /** ------------------------------------
     * MAIN pipeline
     * ------------------------------------*/
    public function run_scan() {

        $response = SS_API::authority_request(
            '/api/authority/backlinks/scan',
            []
        );

        if (is_wp_error($response)) {
            return ['error' => $response->get_error_message()];
        }

        if (!is_array($response) || empty($response['ok'])) {
            return ['error' => 'Invalid response from Authority API'];
        }

        // Just return what hub sends
        return $response;
    }


    /** ------------------------------------
     * Discover via SerpAPI (link:)
     * ------------------------------------*/
    private function discover($domain, $key) {
        $url = "https://serpapi.com/search.json?engine=google&q=" . rawurlencode("link:{$domain}") . "&api_key=" . rawurlencode($key);
        $json = $this->get_json($url);

        if (!$json || empty($json['organic_results'])) {
            return [];
        }

        $output = [];

        foreach ($json['organic_results'] as $r) {
            $source = isset($r['link']) ? $r['link'] : '';
            $anchor = isset($r['title']) ? $r['title'] : '';
            $output[] = [
                'source' => $source,
                'anchor' => $anchor,
                'target' => "https://{$domain}/"
            ];
        }

        return $output;
    }

    /** ------------------------------------
     * Verify link present on source page
     * ------------------------------------*/
    private function verify($row) {
        $row = (array) $row;
        $row['verified'] = false;
        $row['html_snippet'] = '';

        if ( empty($row['source']) || empty($row['target']) ) {
            return $row;
        }

        $html = $this->get($row['source']);
        if ( $html ) {
            $row['verified'] = ( stripos($html, $row['target']) !== false );
            $row['html_snippet'] = $row['verified']
                ? wp_trim_words( wp_strip_all_tags(substr($html, 0, 1200)), 60, '...' )
                : '';

        }

        return $row;
    }

    /** ------------------------------------
     * Save evidence (filesystem + optional DB evidence table)
     * ------------------------------------*/
    private function save_evidence($id, $row) {
        if ( ! $id ) return;

        $folder = trailingslashit( self::DIR ) . intval($id);
        wp_mkdir_p( $folder );

        // Save JSON evidenc
        file_put_contents("$folder/evidence.json", wp_json_encode($row, JSON_PRETTY_PRINT));

        // Screenshot via URLBox/Urlbox/Urlbox-like service if configured
        $shot = false;
        $shot_path = "$folder/screenshot.png";
        if ( defined('SS_URLBOX_KEY') && SS_URLBOX_KEY ) {
            $shot = $this->screenshot($row['source']);
            if ($shot) {
                file_put_contents($shot_path, $shot);
            }
        }

        // Add evidence into DB via SS_Backlinks helper if available
        if ( class_exists('SS_Backlinks') && method_exists('SS_Backlinks', 'add_evidence') ) {
            try {
                SS_Backlinks::add_evidence($id, 'verification', $row);
            } catch (Throwable $e) {
               
            }
        }
    }

    /** ------------------------------------
     * HTTP helpers
     * ------------------------------------*/
    private function get($url) {
        if ( empty($url) ) return null;
        $r = wp_remote_get($url, ['timeout' => 20, 'headers' => ['User-Agent' => 'SearchShifter-BacklinkAgent/1.0']]);
        if ( is_wp_error($r) ) {
            return null;
        }
        return wp_remote_retrieve_body($r);
    }

    private function get_json($url) {
        $body = $this->get($url);
        if ( ! $body ) return null;
        $json = json_decode($body, true);
        if ( json_last_error() !== JSON_ERROR_NONE ) {
            return null;
        }
        return $json;
    }

    /** ------------------------------------
     * Screenshot via Urlbox (optional)
     * ------------------------------------*/
    private function screenshot($url) {
        if ( ! defined('SS_URLBOX_KEY') || ! SS_URLBOX_KEY ) return false;
        $api = "https://api.urlbox.io/v1/" . rawurlencode(SS_URLBOX_KEY) . "/png?url=" . rawurlencode($url) . "&full_page=true";
        $r = wp_remote_get($api, ['timeout' => 30]);
        if ( is_wp_error($r) ) {
            return false;
        }
        return wp_remote_retrieve_body($r);
    }

} // end class

// Auto-init if setup doesn't call init() explicitly
SS_Backlink_Agent::init();

endif;
