<?php
/**
 * Wally Monitor - AJAX Handlers
 *
 * Centraliza todos os endpoints AJAX do plugin.
 *
 * @package    WallyMonitor
 * @subpackage Includes
 * @since      1.1.0
 */

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

class Wally_Ajax {

    /**
     * Inicializa hooks AJAX
     */
    public static function init() {
        $instance = new self();

        add_action( 'wp_ajax_wally_get_site_urls', array( $instance, 'get_site_urls' ) );
        add_action( 'wp_ajax_wally_analyze_url', array( $instance, 'analyze_url' ) );
        add_action( 'wp_ajax_wally_save_full_report', array( $instance, 'save_full_report' ) );
        add_action( 'wp_ajax_wally_save_editor_report', array( $instance, 'save_editor_report' ) );
        add_action( 'wp_ajax_wally_process_content', array( $instance, 'process_content' ) );
        add_action( 'wp_ajax_wally_refresh_seo_metabox', array( $instance, 'refresh_seo_metabox' ) );
    }

    /**
     * Retorna URLs do site para análise completa
     */
    public function get_site_urls() {
        check_ajax_referer( 'wally-monitor-nonce', 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( __( 'Permissão negada.', 'wally-monitor' ) );
        }

        $settings = get_option( 'wally_monitor_settings', array(
            'post_types'   => array( 'post', 'page' ),
            'include_home' => true,
            'max_urls'     => 100,
        ) );

        $post_types = ! empty( $settings['post_types'] ) ? $settings['post_types'] : array( 'post', 'page' );
        $max_urls   = isset( $settings['max_urls'] ) ? intval( $settings['max_urls'] ) : 100;

        $posts = get_posts( array(
            'post_type'      => $post_types,
            'posts_per_page' => $max_urls,
            'post_status'    => 'publish',
        ) );

        $urls = array();
        foreach ( $posts as $post ) {
            $urls[] = get_permalink( $post->ID );
        }

        if ( ! empty( $settings['include_home'] ) ) {
            array_unshift( $urls, home_url( '/' ) );
        }

        wp_send_json_success( array_unique( $urls ) );
    }

    /**
     * Analisa uma URL individual (fetch HTML server-side)
     */
    public function analyze_url() {
        check_ajax_referer( 'wally-monitor-nonce', 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( __( 'Permissão insuficiente.', 'wally-monitor' ), 403 );
        }

        if ( ! isset( $_POST['url'] ) ) {
            wp_send_json_error( __( 'URL não fornecida.', 'wally-monitor' ) );
        }

        $url = esc_url_raw( wp_unslash( $_POST['url'] ) );

        // SSRF protection — validate URL before fetching
        $url_check = wally_monitor_validate_url( $url );
        if ( is_wp_error( $url_check ) ) {
            wp_send_json_error( $url_check->get_error_message() );
        }

        $response = wp_remote_get( $url, array(
            'timeout'   => 30,
            'sslverify' => apply_filters( 'wally_monitor_sslverify', true ),
        ) );

        if ( is_wp_error( $response ) ) {
            /* translators: %s: error message from wp_remote_get */
            wp_send_json_error( sprintf( __( 'Falha ao buscar a URL: %s', 'wally-monitor' ), $response->get_error_message() ) );
        }

        $body = wp_remote_retrieve_body( $response );
        // Cache temporário (5 min) — evita armazenamento permanente de HTML em wp_options.
        set_transient( 'wally_scan_' . md5( $url ), $body, 5 * MINUTE_IN_SECONDS );

        wp_send_json_success( array( 'html' => $body ) );
    }

    /**
     * Salva relatório completo do site scan
     */
    public function save_full_report() {
        check_ajax_referer( 'wally-monitor-nonce', 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( __( 'Permissão negada.', 'wally-monitor' ) );
        }

        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        $report_json = isset( $_POST['report'] ) ? wp_unslash( $_POST['report'] ) : '';

        if ( empty( $report_json ) || ! is_string( $report_json ) ) {
            wp_send_json_error( __( 'Nenhum dado de relatório fornecido.', 'wally-monitor' ) );
        }

        $report_data = json_decode( $report_json, true );
        if ( json_last_error() !== JSON_ERROR_NONE ) {
            /* translators: %s: JSON decoding error message */
            wp_send_json_error( sprintf( __( 'Erro ao decodificar JSON: %s', 'wally-monitor' ), json_last_error_msg() ) );
        }

        // Valida e sanitiza
        $validation = Wally_Sanitizer::validate_report_structure( $report_data );
        if ( is_wp_error( $validation ) ) {
            wp_send_json_error( $validation->get_error_message() );
        }
        $report_data = Wally_Sanitizer::sanitize_report_data( $report_data );

        // Metadata
        $report_data['timestamp'] = current_time( 'mysql' );
        $report_data['user_id']   = get_current_user_id();

        // Salva compatibilidade
        update_option( 'wally_monitor_full_report', $report_data, false );

        // Salva no banco de dados via classe centralizada
        $db  = Wally_Database::get_instance();
        $url = isset( $report_data['url'] ) ? esc_url_raw( $report_data['url'] ) : '';

        $score            = isset( $report_data['summary']['score'] ) ? intval( $report_data['summary']['score'] ) : 0;
        $total_violations = isset( $report_data['summary']['totalProblems'] ) ? intval( $report_data['summary']['totalProblems'] ) : 0;

        $db->insert_report( $url, $report_data, $score, $total_violations );
        $db->update_history_summary( $report_data, $url );

        wp_send_json_success( array(
            'message' => __( 'Relatório salvo.', 'wally-monitor' ),
            'url'     => $url,
            'score'   => $score,
        ) );
    }

    /**
     * Salva relatório do editor (análise de post individual)
     */
    public function save_editor_report() {
        check_ajax_referer( 'wally-monitor-nonce', 'nonce' );

        if ( ! current_user_can( 'edit_posts' ) ) {
            wp_send_json_error( __( 'Permissão negada.', 'wally-monitor' ) );
        }

        $post_id = isset( $_POST['post_id'] ) ? intval( wp_unslash( $_POST['post_id'] ) ) : 0;
        if ( ! $post_id ) {
            wp_send_json_error( __( 'Post ID inválido.', 'wally-monitor' ) );
        }

        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        $report_json = isset( $_POST['report'] ) ? wp_unslash( $_POST['report'] ) : '';

        if ( empty( $report_json ) || ! is_string( $report_json ) ) {
            wp_send_json_error( __( 'Nenhum dado de relatório fornecido.', 'wally-monitor' ) );
        }

        $report_data = json_decode( $report_json, true );
        if ( json_last_error() !== JSON_ERROR_NONE ) {
            /* translators: %s: JSON decoding error message */
            wp_send_json_error( sprintf( __( 'Erro ao decodificar JSON: %s', 'wally-monitor' ), json_last_error_msg() ) );
        }

        $validation = Wally_Sanitizer::validate_report_structure( $report_data );
        if ( is_wp_error( $validation ) ) {
            wp_send_json_error( $validation->get_error_message() );
        }
        $report_data = Wally_Sanitizer::sanitize_report_data( $report_data );

        // URL do post
        $url = get_permalink( $post_id );
        if ( ! $url ) {
            $url = add_query_arg( 'p', $post_id, home_url( '/' ) );
        }
        $url = esc_url_raw( $url );

        $report_data['url']       = $url;
        $report_data['post_id']   = $post_id;
        $report_data['timestamp'] = current_time( 'mysql' );
        $report_data['user_id']   = get_current_user_id();

        // Usa classe de banco centralizada
        $db = Wally_Database::get_instance();

        // Remove relatório antigo para esta URL (mantém apenas o mais recente)
        $db->delete_reports_by_url( $url );

        $score            = isset( $report_data['summary']['score'] ) ? intval( $report_data['summary']['score'] ) : 0;
        $total_violations = isset( $report_data['summary']['totalProblems'] ) ? intval( $report_data['summary']['totalProblems'] ) : 0;

        $db->insert_report( $url, $report_data, $score, $total_violations );

        wp_send_json_success( array(
            'message' => __( 'Relatório do editor salvo.', 'wally-monitor' ),
            'url'     => $url,
            'score'   => $score,
            'post_id' => $post_id,
        ) );
    }

    /**
     * Processa conteúdo do editor (expande shortcodes)
     */
    public function process_content() {
        if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wally-monitor-nonce' ) ) {
            wp_send_json_error( __( 'Nonce inválido.', 'wally-monitor' ) );
            return;
        }

        if ( ! current_user_can( 'edit_posts' ) ) {
            wp_send_json_error( __( 'Permissão negada.', 'wally-monitor' ) );
            return;
        }

        $content = isset( $_POST['content'] ) ? wp_kses_post( wp_unslash( $_POST['content'] ) ) : '';

        if ( empty( $content ) ) {
            wp_send_json_error( __( 'Conteúdo vazio.', 'wally-monitor' ) );
            return;
        }

        // Processa shortcodes
        $content = do_shortcode( $content );

        // Aplica filtros do WordPress
        remove_filter( 'the_content', 'wpautop' );
        remove_filter( 'the_content', 'wptexturize' );

        // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
        $content = apply_filters( 'the_content', $content );

        add_filter( 'the_content', 'wpautop' );
        add_filter( 'the_content', 'wptexturize' );

        wp_send_json_success( $content );
    }

    /**
     * Atualiza meta box SEO via AJAX
     */
    public function refresh_seo_metabox() {
        check_ajax_referer( 'wally-monitor-nonce', 'nonce' );

        $post_id = isset( $_POST['post_id'] ) ? intval( wp_unslash( $_POST['post_id'] ) ) : 0;
        if ( ! $post_id ) {
            wp_send_json_error( __( 'Post ID inválido', 'wally-monitor' ) );
        }

        $post = get_post( $post_id );
        if ( ! $post ) {
            wp_send_json_error( __( 'Post não encontrado', 'wally-monitor' ) );
        }

        ob_start();
        $seo_integration = new Wally_SEO_Integration();
        $seo_integration->render_seo_meta_box( $post );
        $html = ob_get_clean();

        wp_send_json_success( array( 'html' => $html ) );
    }
}
