<?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');
        global $wpdb;

        $table = $wpdb->prefix . 'ss_backlinks';

       // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
$existing_backlinks = $wpdb->get_results(
    "SELECT * FROM {$table} ORDER BY id DESC LIMIT 10"
);
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared

        $has_data = ! empty( $existing_backlinks );
        $last_scan = get_option('ss_backlink_last_scan');
        $verified_count = 0;
        $not_verified   = 0;

        foreach ( $existing_backlinks as $b ) {

            if ( ! empty( $b->visible_to_ai ) ) {
                $verified_count++;
            } else {
                $not_verified++;
            }
        }
        ?>
        
        <div class="wrap">
            <h1>Backlink Agent</h1>
            <p style="max-width:900px;color:#555;">
                Backlink Agent helps you discover external websites, social profiles, and mentions that reference your brand online. These references may improve how AI systems and search engines recognize your authority and visibility.
            </p>
            <p>Discover → verify → log AI-visible backlinks with evidence.</p>
            <?php if ( ! $has_data ) : ?>

            <div class="notice notice-info" style="padding:20px;margin:20px 0;">
                
                <h2 style="margin-top:0;">Welcome to Backlink Agent</h2>

                <p>
                    This tool scans external websites to discover backlinks,
                    brand mentions, and AI authority signals connected to your website.
                </p>

                <ul style="margin-left:20px;list-style:disc;">
                    <li>Detect AI-visible backlinks</li>
                    <li>Verify authority references</li>
                    <li>Track brand mentions across the web</li>
                    <li>Store backlink evidence and scan history</li>
                </ul>

                <p>
                    <strong>No backlink scan data found yet.</strong><br>
                    Click "Run First Scan" to start discovering backlinks.
                </p>

            </div>

            <?php endif; ?>
            <p>
                <button id="ss_bl_btn" class="button button-primary">
                    <?php echo $has_data ? 'Run Fresh Scan' : 'Run First Scan'; ?>
                </button>
                <span id="ss_bl_spinner" style="display:none;margin-left:10px;">Running…</span>
            </p>

            <?php if ($last_scan): ?>
                <p style="color:#666;">
                    Last scan: <?php echo esc_html($last_scan); ?>
                </p>
            <?php endif; ?>
            <div id="ss_bl_summary" class="ss-card" style="display:none;"></div>
            <div class="ss-bl-stats">

                <div class="ss-card">
                    <h2><?php echo count($existing_backlinks); ?></h2>
                    <p>Total Backlinks</p>
                </div>

                <div class="ss-card">
                    <h2><?php echo esc_html( absint( $verified_count ) ); ?></h2>
                    <p>AI Visible</p>
                </div>

                <div class="ss-card">
                    <h2><?php echo esc_html( absint( $not_verified ) ); ?></h2>
                    <p>Not Verified</p>
                </div>

            </div>

            <p style="margin:10px 0;color:#666;">
                Showing current  <?php echo count($existing_backlinks); ?> backlinks
            </p>
            <table class="widefat striped" id="ss_bl_table"
                style="<?php echo $has_data ? '' : 'display:none'; ?>">
            <thead>
                <tr>
                <th>Source</th>
                <th>Anchor Text</th>
                <th>AI Verified</th>
                <th>Evidence</th>
                </tr>
            </thead>
            <tbody>

                <?php if ( $has_data ) : ?>

                    <?php foreach ( $existing_backlinks as $r ) : ?>

                        <tr>

                            <td>
                                <a href="<?php echo esc_url( $r->source_url ); ?>" target="_blank">
                                    <?php echo esc_html( $r->source_url ); ?>
                                </a>
                            </td>

                            <td>
                                <?php echo esc_html( $r->anchor_text ); ?>
                            </td>

                            <td>
                                <?php echo $r->visible_to_ai ? '🟢 Verified' : '🔴 Not Verified'; ?>
                            </td>

                            <td>
                                <button
                                    class="button ss-bl-view"
                                    data-source="<?php echo esc_attr( $r->source_url ); ?>"
                                    data-anchor="<?php echo esc_attr( $r->anchor_text ); ?>"
                                    data-verified="<?php echo esc_attr( $r->visible_to_ai ); ?>">
                                    View
                                </button>
                            </td>

                        </tr>

                    <?php endforeach; ?>

                <?php endif; ?>

                </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-stats{
                display:flex;
                gap:20px;
                margin:20px 0;
                flex-wrap:wrap;
            }

            .ss-card{
                background:#fff;
                border:1px solid #ddd;
                border-radius:10px;
                padding:20px;
                min-width:180px;
                box-shadow:0 1px 3px rgba(0,0,0,.05);
            }

            .ss-card h2{
                margin:0;
                font-size:28px;
            }

            .ss-card p{
                margin:5px 0 0;
                color:#666;
            }
            #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;
                        }

                        if (res.success) {

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

                            $('#ss_bl_summary').html(`
                                <div class="notice notice-success inline" style="padding:12px;">
                                    <p style="margin:0;">
                                        ✅ Backlink scan completed successfully.
                                        Latest backlink data has been updated.
                                    </p>
                                </div>
                            `);

                            setTimeout(function(){
                                location.reload();
                            }, 1200);
                        }
                    }).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');
                const verified = parseInt($(this).data('verified'));

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

                $('#ss_bl_modal_content').html(`
                    <p><strong>Source:</strong> 
                        <a href="${source}" target="_blank">${source}</a>
                    </p>

                    <p><strong>Status:</strong> 
                        ${verified ? '✅ AI-visible' : '❌ Not detected'}
                    </p>

                    <h4>Why this matters</h4>

                    <p>
                    ${verified 
                    ? 'This backlink was successfully detected and may help AI systems recognize your brand authority and online presence.'
                    : 'The backlink reference could not be verified by the system. This may happen if the page is blocked, dynamically loaded, restricted, or the reference is no longer accessible.'
                    }
                    </p>

                    <h4>Detected reference</h4>

                    <blockquote>${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 );
        }

        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'];
    }

    global $wpdb;

    $table = $wpdb->prefix . 'ss_backlinks';
    $evidence_table = $wpdb->prefix . 'ss_backlink_evidence';

    // clear old scan data
    // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
$wpdb->query( "TRUNCATE TABLE {$evidence_table}" );
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
   // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
$wpdb->query( "TRUNCATE TABLE {$table}" );
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared

    if (!empty($response['results']) && class_exists('SS_Backlinks')) {

        foreach ($response['results'] as $row) {

            $target   = home_url('/');
            $source   = $row['source'] ?? '';
            $anchor   = $row['anchor'] ?? '';
            $verified = !empty($row['verified']) ? 1 : 0;

            if (!$source) {
                continue;
            }

            $id = SS_Backlinks::record_backlink(
                $target,
                $source,
                [
                    'anchor_text'   => $anchor,
                    'visible_to_ai' => $verified
                ]
            );

            if ($id) {
                $this->save_evidence($id, $row);
            }
        }
    }

    update_option(
            'ss_backlink_last_scan',
            current_time('mysql')
        );

        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;
