<?php
/**
 * 404 logger + dedup. Aggregates 404 hits per URL path and tracks last referrer.
 *
 * @package Brainwerk SEO Suite
 */

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

class Seoforge_Not_Found {

    public static function register( Seoforge_Loader $loader ) {
        if ( ! Seoforge_Settings::get( 'log_404_enabled', true ) ) {
            return;
        }
        $loader->add_action( 'template_redirect', __CLASS__, 'maybe_log', 5 );
        $loader->add_action( 'seoforge_cleanup_visits', __CLASS__, 'cleanup' );
    }

    public static function maybe_log() {
        if ( ! is_404() ) {
            return;
        }
        global $wpdb;
        $tbl  = Seoforge_Utils::table( '404' );
        $blog = Seoforge_Utils::current_blog_id();
        $path = Seoforge_Utils::url_path( home_url( Seoforge_Utils::safe_request_uri() ) );
        $now  = current_time( 'mysql', 1 );
        $ref  = Seoforge_Utils::safe_referrer();
        $ua   = Seoforge_Utils::safe_user_agent();

        $wpdb->query( $wpdb->prepare(
            "INSERT INTO %i ( blog_id, url_path, hits, last_referrer, last_user_agent, last_seen, first_seen )
             VALUES ( %d, %s, 1, %s, %s, %s, %s )
             ON DUPLICATE KEY UPDATE hits = hits + 1, last_seen = VALUES(last_seen), last_referrer = VALUES(last_referrer), last_user_agent = VALUES(last_user_agent)",
            $tbl, $blog, $path, $ref, $ua, $now, $now
        ) );
    }

    /**
     * Cleanup cron — scoped to one blog (defaults to the current one) so a
     * Multisite cleanup never touches another site's rows — see
     * Seoforge_Tools::cleanup_now().
     */
    public static function cleanup( $blog_id = null ) {
        global $wpdb;
        $blog_id = null === $blog_id ? Seoforge_Utils::current_blog_id() : (int) $blog_id;
        $days = max( 7, (int) Seoforge_Settings::get( 'log_404_retention_days', 90 ) );
        $cutoff = gmdate( 'Y-m-d H:i:s', time() - DAY_IN_SECONDS * $days );
        $wpdb->query( $wpdb->prepare( "DELETE FROM %i WHERE blog_id = %d AND last_seen < %s", Seoforge_Utils::table( '404' ), $blog_id, $cutoff ) );
    }

    public static function recent( $limit = 100, $resolved = null ) {
        global $wpdb;
        $tbl  = Seoforge_Utils::table( '404' );
        $blog = Seoforge_Utils::current_blog_id();
        if ( null !== $resolved ) {
            return $wpdb->get_results( $wpdb->prepare(
                "SELECT * FROM %i WHERE blog_id = %d AND is_resolved = %d ORDER BY last_seen DESC LIMIT %d",
                $tbl,
                $blog,
                $resolved ? 1 : 0,
                (int) $limit
            ), ARRAY_A );
        }
        return $wpdb->get_results( $wpdb->prepare(
            "SELECT * FROM %i WHERE blog_id = %d ORDER BY last_seen DESC LIMIT %d",
            $tbl,
            $blog,
            (int) $limit
        ), ARRAY_A );
    }

    public static function mark_resolved( $id, $resolved = true ) {
        global $wpdb;
        // Scope to the current blog so a subsite admin cannot flip another
        // subsite's 404 row to resolved by guessing its id (Multisite isolation).
        return (bool) $wpdb->update(
            Seoforge_Utils::table( '404' ),
            array( 'is_resolved' => $resolved ? 1 : 0 ),
            array( 'id' => (int) $id, 'blog_id' => Seoforge_Utils::current_blog_id() )
        );
    }
}
