<?php
add_action('init', 'alt_index_verificar_tabela_indexacao');
add_action('wp_ajax_alt_index_reindexar_ajax', 'alt_index_reindexar_ajax_handler');

/**
 * =============================
 * CRIAÇÃO DE TABELAS
 * =============================
 */
function alt_index_verificar_tabela_indexacao() {
    if (!function_exists('alt_busca_similaridade_ativada') || !alt_busca_similaridade_ativada()) {
        return;
    }

    global $wpdb;

    $tabela_index = alt_nome_tabela_veiculos_indexacao();
    
    $existe_index = $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(1) FROM information_schema.tables WHERE table_schema = %s AND table_name = %s",
        DB_NAME,
        $tabela_index
    ));
    if (!$existe_index) {
        alt_index_criar_tabela_veiculos();
        alt_reindexar_todos_veiculos();
    }
}
function alt_nome_tabela_veiculos_indexacao() {
    global $wpdb;
    return $wpdb->prefix . 'alt_index_veiculos';
}


/**
 * Cria a tabela principal de índice de veículos
 */
function alt_index_criar_tabela_veiculos() {
    global $wpdb;
    
    $table_name = alt_nome_tabela_veiculos_indexacao();
    $charset_collate = $wpdb->get_charset_collate();
    
    // Criação da tabela de indexação
    $sql = "CREATE TABLE $table_name (
        id BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        post_id BIGINT(20) UNSIGNED NOT NULL,
        word VARCHAR(255) NOT NULL,
        phonetic_code VARCHAR(10) NOT NULL,
        word_length SMALLINT(5) UNSIGNED NOT NULL,
        UNIQUE KEY unique_index (post_id, word(200))
    ) $charset_collate;";
    
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}


/**
 * =============================
 * FUNÇÕES AUXILIARES DE INDEXACAO
 * =============================
 */

/**
 * Atualiza a indexação de palavras para um post do tipo "vehicle".
 *
 * @param int $post_id ID do post que será indexado.
 */
function alt_atualiza_indexacao_de_palavras($post_id) {
    if (get_post_type($post_id) !== 'veiculos' || !alt_busca_similaridade_ativada()) {
        return;
    }

    global $wpdb;
    $table_name = alt_nome_tabela_veiculos_indexacao();

    // Remove os índices existentes para evitar duplicatas
    $wpdb->delete($table_name, ['post_id' => $post_id], ['%d']);

    // Extrai o post_title e divide em palavras
    $post_title = strtolower(get_the_title($post_id));
    $words = preg_split('/\s+/', preg_replace('/[^a-z0-9]/', ' ', $post_title));

    // Remove duplicatas do array de palavras
    $words = array_unique($words);

    foreach ($words as $word) {
        if (strlen($word) > 2) {
            $wpdb->insert(
                $table_name,
                [
                    'post_id' => $post_id,
                    'word' => $word,
                    'phonetic_code' => soundex($word),
                    'word_length' => strlen($word),
                ],
                ['%d', '%s', '%s', '%d']
            );
        }
    }
}
add_action('save_post', 'alt_atualiza_indexacao_de_palavras');

/**
 * Remove a indexação de palavras quando um veículo é excluído
 *
 * @param int $post_id ID do post que será excluído
 */
function alt_remove_indexacao_de_palavras($post_id) {
    if (get_post_type($post_id) !== 'veiculos' || !alt_busca_similaridade_ativada()) {
        return;
    }

    global $wpdb;
    $table_name = alt_nome_tabela_veiculos_indexacao();
    
    // Remove todos os índices do veículo
    $wpdb->delete(
        $table_name,
        ['post_id' => $post_id],
        ['%d']
    );
}
add_action('before_delete_post', 'alt_remove_indexacao_de_palavras');

/**
 * =============================
 * FUNÇÕES AUXILIARES DE CLASSIFICACAO POR SIMILARIDADE
 * =============================
 */

 /**
 * Classifica os resultados por relevância.
 *
 * @param array $results Lista de IDs de posts.
 * @param string $search_query Termo digitado pelo usuário.
 * @return array IDs ordenados por relevância.
 */
function alt_rank_resultados_por_relevancia($results, $search_query) {
    $words = preg_split('/\s+/', strtolower($search_query));
    $ranked = [];

    foreach ($results as $result_id) {
        $rank = 0;

        foreach ($words as $word) {
            $post_title = strtolower(get_the_title($result_id));
            if (similar_text($word, $post_title, $percent) && $percent > 80) {
                $rank += 10; // Alta similaridade
            } elseif (levenshtein($word, $post_title) <= 2) {
                $rank += 5; // Pequena distância de edição
            } else {
                $rank += 1; // Menor relevância
            }
        }

        $ranked[$result_id] = $rank;
    }

    arsort($ranked); // Ordenar por relevância
    return array_keys($ranked);
}


 /**
 * =============================
 * FUNÇÕES AUXILIARES DE BUSCA
 * =============================
 */

 /**
 * Calcula a distância de edição entre duas palavras usando PHP.
 *
 * @param string $word1 Primeira palavra.
 * @param string $word2 Segunda palavra.
 * @return int Distância de edição.
 */
function alt_calcula_distancia_levenshtein($word1, $word2) {
    return levenshtein($word1, $word2);
}

 /**
 * Realiza busca por similaridade usando fonética e distância de edição.
 *
 * @param string $search_query Termo digitado pelo usuário.
 * @return array Lista de IDs de posts correspondentes.
 */
function alt_busca_veiculos_tolerancia_similaridade($search_query) {
    global $wpdb;
    $table_name = alt_nome_tabela_veiculos_indexacao();

    $words = preg_split('/\s+/', strtolower($search_query)); // Dividir termos em palavras
    $result_scores = [];

    $similarity_threshold = 0.25; // Reduzir para capturar mais palavras
    $distance_threshold = 6;    // Permitir maior distância

    foreach ($words as $word) {
        $word = preg_replace('/[^a-z0-9]/', '', $word); // Limpar a palavra
        if (strlen($word) > 1) {
            $similar_posts = $wpdb->get_results(
                $wpdb->prepare(
                    "SELECT post_id, word 
                     FROM $table_name 
                     WHERE phonetic_code = SOUNDEX(%s) 
                     OR word LIKE %s",
                    $word,
                    '%' . $wpdb->esc_like($word) . '%'
                )
            );
            
            foreach ($similar_posts as $post) {
                $similarity = similar_text($word, $post->word) / max(strlen($word), strlen($post->word));
                $distance = levenshtein($word, $post->word);

                if ($similarity >= $similarity_threshold || $distance <= $distance_threshold) {
                    if (!isset($result_scores[$post->post_id])) {
                        $result_scores[$post->post_id] = 0;
                    }
                    // Pontuação ajustada para palavras mais próximas
                    $result_scores[$post->post_id] += ($similarity * 30) + max(0, 10 - $distance);
                }
            }
        }
    }
    
    // Ordenar por pontuação total
    arsort($result_scores);

    $final_ids = [];
    foreach ($result_scores as $post_id => $score) {
        $post_title = $wpdb->get_var($wpdb->prepare("SELECT post_title FROM {$wpdb->posts} WHERE ID = %d", $post_id));

        if ($post_title) {
            $distance = levenshtein(strtolower($search_query), strtolower($post_title));
            if ($distance <= 15 || $score > 10) {
                $final_ids[] = $post_id;
            }
        }
    }

    return array_unique($final_ids);
}

/**
 * Realiza uma busca de veículos por similaridade com base na query fornecida.
 *
 * Esta função utiliza a função alt_busca_veiculos_tolerancia_similaridade para obter
 * os IDs dos veículos similares e, em seguida, busca os posts correspondentes.
 *
 * @param string $search_query A query de busca fornecida pelo usuário.
 * @return array Uma lista de objetos WP_Post representando os veículos encontrados.
 */
function alt_busca_veiculos_similaridade($search_query) {
    if (!alt_busca_similaridade_ativada()) {
        [];
    }
    $veiculos_ids = alt_busca_veiculos_tolerancia_similaridade($search_query);
    if (!empty($veiculos_ids)) {
        $args = [
            'post_type'   => 'veiculos',
            'post_status' => 'publish',
            'post__in'    => $veiculos_ids,
            'orderby'     => 'post__in',
        ];

        $query = new WP_Query($args);
        return $query->posts;
    }

    return [];
}

/**
 * Reindexar todos os veículos
 *
 * Esta função limpa a tabela de indexação e reindexar todos os veículos.
 * Ela trunca a tabela existente, busca todos os posts do tipo 'veiculos',
 * e então chama a função de indexação para cada veículo individualmente.
 *
 * @return int O número total de veículos reindexados.
 */

function alt_reindexar_todos_veiculos() {
    if (!alt_busca_similaridade_ativada()) {
        0;
    }
    global $wpdb;

    $table_name = alt_nome_tabela_veiculos_indexacao();
    $wpdb->query("TRUNCATE TABLE $table_name");

    $veiculos = get_posts(['post_type' => 'veiculos', 'numberposts' => -1]);

    foreach ($veiculos as $veiculo) {
        alt_atualiza_indexacao_de_palavras($veiculo->ID);
    }

    return count($veiculos);
}

// Registra o endpoint AJAX
add_action('wp_ajax_nopriv_alt_index_reindexar_ajax', 'alt_index_reindexar_ajax_handler');

/**
 * Manipula a solicitação AJAX para reindexar todos os veículos.
 *
 * Esta função é chamada quando uma solicitação AJAX é feita para reindexar
 * todos os veículos. Ela verifica o nonce para segurança, chama a função
 * de reindexação e envia uma resposta JSON com o resultado da operação.
 */

function alt_index_reindexar_ajax_handler() {
    check_ajax_referer('alt_index_nonce', 'nonce');

    try {
        $resultado = alt_reindexar_todos_veiculos();

        if ($resultado > 0) {
            wp_send_json_success(sprintf(
                'Indexação concluída com sucesso! %d veículos foram indexados.',
                $resultado
            ));
        } else {
            wp_send_json_error(sprintf(
                'Erro ao indexar veículos: %s',
                $resultado
            ));
        }
    } catch (Exception $e) {
        wp_send_json_error(sprintf(
            'Erro ao indexar veículos: %s',
            $e->getMessage()
        ));
    }
}
