<?php

/**
 * Cria ou atualiza um evento no cron do WordPress para execução periódica.
 *
 * Esta função verifica se já existe um evento agendado com o hook especificado.
 * Se não existir, cria um novo evento. Se já existir, atualiza o evento existente
 * com a nova recorrência e timestamp.
 *
 * @param string $hook Nome do hook a ser executado.
 * @param string $recurrence Frequência de execução (hourly, daily, weekly).
 * @param int $timestamp Timestamp Unix para a primeira execução.
 * @return bool True se o evento foi agendado ou atualizado com sucesso, false caso contrário.
 */
function alt_criar_evento_cron() {
    $hook = 'alt_integracao_via_leitura_json';
    if (!wp_next_scheduled($hook) && alt_is_portal()) {
        wp_schedule_event(time(), 'alt_thirty_minutes', $hook);
        return true;
    }
    return false;
}

add_filter('cron_schedules', function($schedules) {
    $schedules['alt_thirty_minutes'] = array(
        'interval' => 1800,
        'display'  => __('Every 30 Minutes')
    );
    return $schedules;
});

// Registrando a ação para o hook do cron
add_action('alt_integracao_via_leitura_json', 'alt_integracao_via_leitura_json');

// Garantindo que o evento seja criado na inicialização do WordPress
add_action('init', 'alt_criar_evento_cron');

/**
 * Lista todas as lojas que possuem integração externa.
 *
 * Esta função busca e retorna todas as lojas publicadas que têm
 * um tipo de integração definido. Ela utiliza uma consulta personalizada
 * para filtrar os posts do tipo 'lojas' que possuem a meta 'alt_lojas_tipo_integracao'.
 *
 * @return void
 */

function alt_integracao_via_leitura_json() {
    try {
        $args = array(
            'post_type' => 'lojas',
            'post_status' => 'publish',
            'posts_per_page' => -1,
            'meta_query' => array(
                array(
                    'key' => 'alt_lojas_tipo_integracao',
                    'compare' => 'EXISTS',
                ),
            ),
        );

        $query = new WP_Query($args);

        

        if ($query->have_posts()) {
            while ($query->have_posts()) {
                $query->the_post();
                $loja_id = get_the_ID();
                $loja_user_id = get_post_field('post_author', get_the_ID());
                $url = get_post_meta(get_the_ID(), 'alt_lojas_json_url', true);

                if (!empty($url)) {
                    $result = alt_get_veiculos_json($loja_id, $loja_user_id, $url);
                    if ($result === false) {
                        error_log("Falha ao obter veículos para a loja ID: $loja_id");
                    }
                }
                
                error_log("URL vazia para a loja ID: $loja_id");
            }
        }

        wp_reset_postdata();
        return null; // Return null as the function is not expected to return an array
    } catch (Exception $e) {
        $message = 'Erro ao listar lojas com integração: ' . $e->getMessage();
        error_log($message);
        alt_enviar_mensagem_erro_slack($message);
        return null;
    }
}

/**
 * Retorna o nome da tabela de lista de veículos externos com o prefixo do WordPress
 * 
 * @return string Nome da tabela com prefixo
 */
function alt_name_table_lista_veiculos_externos() {
    global $wpdb;
    return $wpdb->prefix . 'alt_queue_lista_veiculos_externos';
}

/**
 * Retorna o nome da tabela de lista de lojas com o prefixo do WordPress
 * 
 * @return string Nome da tabela com prefixo
 */
function alt_name_table_lista_lojas() {
    global $wpdb;
    return $wpdb->prefix . 'alt_queue_lista_lojas';
}

/**
 * Obtém veículos de uma loja específica através de uma URL JSON.
 * 
 * Esta função busca dados de veículos de uma URL específica, verifica se houve
 * alterações desde a última busca usando um hash SHA-256, e retorna os dados
 * apenas se houver mudanças ou se for a primeira execução.
 * 
 * @param int $loja_user_id ID do usuário da loja para identificar a quem os veículos pertencem
 * @param string $url URL para buscar os dados JSON dos veículos
 * @return array|false Retorna um array com os dados dos veículos se houver alterações, ou false caso contrário
 */
function alt_get_veiculos_json($loja_id, $loja_user_id, $url) {
    try {
        if (empty($url)) {
            throw new Exception("URL vazia fornecida para alt_get_veiculos_json");
        }

        alt_check_table_queue_lista_lojas();
        alt_check_table_queue_lista_veiculos_externos();

        $response = wp_remote_get($url);
        if (is_wp_error($response)) {
            throw new Exception('Erro ao buscar JSON: ' . $response->get_error_message());
        }

        $json = wp_remote_retrieve_body($response);
        if (empty($json)) {
            throw new Exception('Resposta JSON vazia de ' . $url);
        }

        $hash_atual = hash('sha256', $json);
        if ($hash_atual === false) {
            throw new Exception('Falha ao gerar hash SHA-256');
        }

        $hash_armazenado = alt_get_hash_loja($loja_id);
        alt_insert_update_queue_lista_lojas($loja_id, $hash_atual);
        
        if ($hash_armazenado !== $hash_atual) {
            $lista_veiculos = json_decode($json, true);
            if (json_last_error() !== JSON_ERROR_NONE) {
                throw new Exception('Erro ao decodificar JSON: ' . json_last_error_msg());
            }

            $lista_ids = array_column($lista_veiculos['veiculos'], 'id');
            alt_remover_veiculos_externos_nao_listados($loja_id, $lista_ids);

            foreach ($lista_veiculos['veiculos'] as $veiculo) {
                if (!alt_processar_veiculo_externo($loja_id, $loja_user_id, $veiculo)) {
                    alt_atualizar_hash($loja_id, $hash_armazenado);
                    throw new Exception('Falha ao processar veículo: ' . $veiculo['id']);
                }
            }

            return true;
        }

        alt_atualizar_attempt_at($loja_id);
        return false;
    } catch (Exception $e) {
        $message = 'Erro em alt_get_veiculos_json: ' . $e->getMessage();
        error_log($message);
        return false;
    }
}

/**
 * Remove veículos externos que não estão na lista de veículos listados
 * 
 * Esta função busca todos os veículos externos cadastrados para uma loja
 * e identifica quais não estão na lista de veículos listados. Em seguida,
 * remove esses veículos externos da loja.
 * 
 * @param int $loja_id ID da loja a ser verificada
 * @param array $ids_listados Array com os IDs de veículos listados
 * @return bool Retorna true se a remoção for bem-sucedida, ou false em caso de erro
 */
function alt_remover_veiculos_externos_nao_listados($loja_id, $ids_listados) {
    global $wpdb;

    try {
        if (!alt_check_table_queue_lista_veiculos_externos()) {
            throw new Exception('Tabela de veículos externos não existe.');
        }

        $table_name = alt_name_table_lista_veiculos_externos();

        $externo_ids = $wpdb->get_col($wpdb->prepare(
            "SELECT externo_id FROM $table_name WHERE loja_id = %s",
            $loja_id
        ));

        if ($externo_ids === null) {
            throw new Exception('Erro ao buscar externo_ids: ' . $wpdb->last_error);
        }

        $ids_para_remover = array_diff($externo_ids, $ids_listados);

        if (empty($ids_para_remover)) {
            return true;
        }

        foreach ($ids_para_remover as $externo_id) {
            if (!alt_delete_veiculo_externo($loja_id, $externo_id)) {
                throw new Exception('Falha ao remover veículo externo: loja_id=' . $loja_id . ', externo_id=' . $externo_id);
            }
        }

        return true;
    } catch (Exception $e) {
        error_log('Erro em alt_remover_veiculos_externos_nao_listados: ' . $e->getMessage());
        return false;
    }
}


/**
 * Insere ou atualiza o registro de uma loja na tabela de fila de lista de lojas.
 *
 * Esta função verifica se a tabela existe, e então insere um novo registro
 * ou atualiza um existente com o hash fornecido para o loja_id especificado.
 *
 * @param int $loja_id O ID da loja a ser inserida ou atualizada.
 * @param string $hash O hash associado à lista de veículos da loja.
 * @return bool Retorna true se a operação for bem-sucedida, false caso contrário.
 */

function alt_insert_update_queue_lista_lojas($loja_id, $hash) {
    global $wpdb;

    try {
        if (!alt_check_table_queue_lista_lojas()) {
            throw new Exception('Tabela de queue de lista de lojas não existe.');
        }

        $tablename = alt_name_table_lista_lojas();

        $existing_record = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM $tablename WHERE loja_id = %s",
            $loja_id
        ));

        if ($wpdb->last_error) {
            throw new Exception('Erro ao buscar registro existente: ' . $wpdb->last_error);
        }

        $current_time = current_time('mysql');

        if (!$existing_record) {
            $result = $wpdb->insert(
                $tablename,
                array(
                    'loja_id' => $loja_id,
                    'hash' => $hash,
                    'created_at' => $current_time,
                )
            );
        } elseif ($existing_record->hash !== $hash) {
            $result = $wpdb->update(
                $tablename,
                array(
                    'hash' => $hash,
                    'updated_at' => $current_time,
                ),
                array('loja_id' => $loja_id)
            );
        } else {
            $result = $wpdb->update(
                $tablename,
                array('attempt_at' => $current_time),
                array('loja_id' => $loja_id)
            );
        }

        if ($result === false) {
            throw new Exception('Erro ao inserir/atualizar registro: ' . $wpdb->last_error);
        }

        return true;
    } catch (Exception $e) {
        error_log('Erro em alt_insert_update_queue_lista_lojas: ' . $e->getMessage());
        return false;
    }
}

/**
 * Atualiza o campo 'attempt_at' para um determinado loja_id na tabela de queue de lista de lojas.
 *
 * Esta função verifica se a tabela existe, e então atualiza o campo 'attempt_at'
 * com o timestamp atual para o loja_id especificado.
 *
 * @param int $loja_id O ID do post para atualizar o campo 'attempt_at'.
 * @return bool Retorna true se a atualização foi bem-sucedida, false caso contrário.
 */
function alt_atualizar_attempt_at($loja_id) {
    global $wpdb;

    try {
        if (!alt_check_table_queue_lista_lojas()) {
            throw new Exception('Tabela de queue de lista de lojas não existe.');
        }

        $tabela = alt_name_table_lista_lojas();

        $resultado = $wpdb->update(
            $tabela,
            array('attempt_at' => current_time('mysql')),
            array('loja_id' => $loja_id)
        );

        if ($resultado === false) {
            throw new Exception('Falha ao atualizar attempt_at: ' . $wpdb->last_error);
        }

        return true;
    } catch (Exception $e) {
        error_log('Erro em alt_atualizar_attempt_at: ' . $e->getMessage());
        return false;
    }
}

/**
 * Processa um veículo externo, verificando se é necessário atualizar ou inserir no sistema.
 *
 * Esta função recebe os dados de um veículo externo, verifica se ele já existe no sistema,
 * e atualiza ou insere conforme necessário. Ela também gera um hash dos dados do veículo
 * para determinar se houve alterações desde a última atualização.
 *
 * @param string $loja_id ID da loja associada ao veículo
 * @param int $loja_user_id ID do usuário associado à loja
 * @param array $veiculo Array contendo os dados do veículo externo
 * @return bool Retorna true se o processamento foi bem-sucedido, false caso contrário
 */

function alt_processar_veiculo_externo($loja_id, $loja_user_id, $veiculo) {
    try {
        $externo_id = $veiculo['id'] ?? '';
        if (empty($externo_id)) {
            throw new Exception("ID externo do veículo não fornecido para loja $loja_id");
        }

        $veiculo_db = alt_get_veiculo_externo($loja_id, $externo_id);
        $veiculo_hash = $veiculo_db['hash'] ?? '';
        
        $veiculo_json = json_encode($veiculo);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception('Erro ao codificar JSON: ' . json_last_error_msg());
        }
        
        $hash_atual = hash('sha256', $veiculo_json);
        if ($hash_atual === false) {
            throw new Exception('Falha ao gerar hash SHA-256');
        }

        $result = alt_insert_update_veiculo_externo($loja_id, $externo_id, $hash_atual);
        
        if (empty($veiculo_hash) || $veiculo_hash !== $hash_atual) {
            $post_id = alt_editar_incluir_veiculo_externo($loja_id, $loja_user_id, $veiculo);
            if (!$post_id) {
                alt_atualizar_hash($loja_id, $veiculo_hash, $externo_id);
                throw new Exception("Falha ao editar/incluir veículo externo: loja_id=$loja_id, externo_id=$externo_id");
            }
        }

        if (!$result) {
            throw new Exception("Falha ao processar veículo externo: loja_id=$loja_id, externo_id=$externo_id");
        }

        return true;
    } catch (Exception $e) {
        $message = 'Erro em alt_processar_veiculo_externo: ' . $e->getMessage();
        error_log($message);
        return false;
    }
}

/**
 * Verifica se a tabela de veículos externos existe e a cria se necessário
 * 
 * @return bool True se a tabela existe ou foi criada com sucesso, False caso contrário
 */
function alt_check_table_queue_lista_veiculos_externos(){
    global $wpdb;

    try {
        $tablename = alt_name_table_lista_veiculos_externos();

        if ($wpdb->get_var("SHOW TABLES LIKE '$tablename'") == $tablename) {
            return true;
        }
        
        $existTable = alt_create_table_queue_lista_veiculos_externos();
        
        if (!$existTable) {
            throw new Exception("Falha ao criar a tabela $tablename");
        }

        return true;
    } catch (Exception $e) {
        error_log('Erro em alt_check_table_queue_lista_veiculos_externos: ' . $e->getMessage());
        return false;
    }
}

/**
 * Cria a tabela de queue de veículos externos com os campos necessários
 * 
 * @return bool True se a tabela foi criada com sucesso, False caso contrário
 */
function alt_create_table_queue_lista_veiculos_externos() {    
    try {
        $tablename = alt_name_table_lista_veiculos_externos();
        
        $sql = "CREATE TABLE `$tablename` (
            `id` int(10) primary key NOT NULL AUTO_INCREMENT,
            `externo_id` varchar(100) NOT NULL,
            `loja_id` varchar(100) NOT NULL,
            `veiculo_id` varchar(100) NOT NULL,
            `hash` text,
            `created_at` datetime,
            `updated_at` datetime,
            INDEX `idx_externo_id` (`externo_id`),
            INDEX `idx_loja_id` (`loja_id`),
            INDEX `idx_veiculo_id` (`veiculo_id`)
            );";
        
        require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
        
        dbDelta( $sql );
        return true;
    } catch (\Throwable $th) {
        error_log($th->getMessage());
        return false;
    }
}

/**
 * Verifica se a tabela de lista de lojas existe e a cria se necessário
 * 
 * @return bool True se a tabela existe ou foi criada com sucesso, False caso contrário
 */
function alt_check_table_queue_lista_lojas(){
    try {
        global $wpdb;

        $tablename = alt_name_table_lista_lojas();

        if ($wpdb->get_var("SHOW TABLES LIKE '$tablename'") == $tablename) {
            return true;
        }

        if (!alt_create_table_queue_lista_lojas()) {
            throw new Exception("Falha ao criar a tabela $tablename");
        }

        return true;
    } catch (Exception $e) {
        error_log("Erro em alt_check_table_queue_lista_lojas: " . $e->getMessage());
        return false;
    }
}

/**
 * Cria a tabela de queue de lista de lojas com os campos necessários
 * 
 * @return bool True se a tabela foi criada com sucesso, False caso contrário
 */
function alt_create_table_queue_lista_lojas() {    
    try {
        $tablename = alt_name_table_lista_lojas();
        
        $sql = "CREATE TABLE `$tablename` (
            `id` int(10) primary key NOT NULL AUTO_INCREMENT,
            `loja_id` varchar(100) NOT NULL,
            `hash` text,
            `created_at` datetime,
            `updated_at` datetime,
            `attempt_at` datetime
            );";
        
        require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
        
        dbDelta( $sql );
        return true;
    } catch (\Throwable $th) {
        error_log($th->getMessage());
        return false;
    }
}

/**
 * Busca e retorna o hash associado a um loja_id específico.
 *
 * Esta função verifica primeiro se a tabela de queue de lista de lojas existe.
 * Se existir, busca o hash correspondente ao loja_id fornecido.
 *
 * @param int $loja_id O ID da loja para o qual o hash deve ser recuperado.
 * @return string|false O hash associado ao loja_id, ou false se não encontrado ou se a tabela não existir.
 */
function alt_get_hash_loja($loja_id) {
    global $wpdb;

    try {
        if (!alt_check_table_queue_lista_lojas()) {
            throw new Exception('Tabela de queue de lista de lojas não existe.');
        }

        $tablename = alt_name_table_lista_lojas();

        $hash = $wpdb->get_var($wpdb->prepare(
            "SELECT hash FROM $tablename WHERE loja_id = %d",
            $loja_id
        ));

        if ($wpdb->last_error) {
            throw new Exception('Erro ao buscar hash: ' . $wpdb->last_error);
        }

        return $hash !== null ? $hash : false;
    } catch (Exception $e) {
        error_log('Erro em alt_get_hash_loja: ' . $e->getMessage());
        return false;
    }
}

/**
 * Atualiza o hash na tabela de lista de lojas ou na tabela de veículos externos.
 *
 * Esta função recebe o ID da loja, o novo hash e opcionalmente o ID externo do veículo.
 * Se o ID externo for fornecido, atualiza o hash na tabela de veículos externos.
 * Caso contrário, atualiza o hash na tabela de lista de lojas.
 *
 * @param int $loja_id ID da loja
 * @param string $hash Novo hash a ser atualizado
 * @param string|null $externo_id ID externo do veículo (opcional)
 * @return bool Retorna true se a atualização for bem-sucedida, false caso contrário
 */
function alt_atualizar_hash($loja_id, $hash, $externo_id = null) {
    global $wpdb;

    try {
        if ($externo_id !== null) {
            $table_name = alt_name_table_lista_veiculos_externos();
            $where = array('loja_id' => $loja_id, 'externo_id' => $externo_id);
        } else {
            $table_name = alt_name_table_lista_lojas();
            $where = array('loja_id' => $loja_id);
        }

        $result = $wpdb->update(
            $table_name,
            array('hash' => $hash),
            $where
        );

        if ($result === false) {
            throw new Exception('Erro ao atualizar hash: ' . $wpdb->last_error);
        }

        return true;
    } catch (Exception $e) {
        error_log('Erro em alt_atualizar_hash: ' . $e->getMessage());
        return false;
    }
}


/**
 * Formata um array de URLs de imagens para o formato esperado pelo sistema
 * 
 * @param array $veiculo Array com dados do veículo incluindo fotos
 * @return array Array de imagens formatadas com src, name, alt e position
 */
function alt_formatar_imagens_externo($veiculo) {
    try {
        if (empty($veiculo['fotos'])) {
            return array();
        }

        if (!isset($veiculo['marca'], $veiculo['modelo'], $veiculo['versao'], $veiculo['cor'], $veiculo['anoFabricacao'], $veiculo['anoModelo'])) {
            throw new Exception('Dados do veículo incompletos');
        }

        $nome_veiculo = "{$veiculo['marca']} {$veiculo['modelo']} {$veiculo['versao']} - {$veiculo['cor']} - {$veiculo['anoFabricacao']}/{$veiculo['anoModelo']}";
        
        return array_map(function($url, $index) use ($nome_veiculo) {
            if (!filter_var($url, FILTER_VALIDATE_URL)) {
                throw new Exception("URL inválida: $url");
            }
            return array(
                'src' => $url,
                'name' => basename($url),
                'alt' => "Foto numero " . ($index + 1) . " do veiculo $nome_veiculo",
                'position' => (string)($index + 1)
            );
        }, $veiculo['fotos'], array_keys($veiculo['fotos']));
    } catch (Exception $e) {
        error_log('Erro em alt_formatar_imagens_externo: ' . $e->getMessage());
        return array();
    }
}

/**
 * Insere ou atualiza um registro na tabela de veículos externos
 * 
 * @param string $loja_id ID da loja
 * @param string $externo_id ID externo do veículo
 * @param string $veiculo_id ID do veículo no WordPress
 * @param string $hash Hash dos dados do veículo
 * @return bool True se a operação foi bem sucedida, False caso contrário
 */
function alt_insert_update_veiculo_externo($loja_id, $externo_id, $hash) {
    global $wpdb;

    try {
        if (!alt_check_table_queue_lista_veiculos_externos()) {
            throw new Exception('Tabela de veículos externos não existe.');
        }

        $table_name = alt_name_table_lista_veiculos_externos();
        
        $existing_record = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM $table_name WHERE loja_id = %s AND externo_id = %s",
            $loja_id,
            $externo_id
        ));

        if ($wpdb->last_error) {
            throw new Exception('Erro ao verificar registro existente: ' . $wpdb->last_error);
        }

        $current_time = current_time('mysql');

        if (!$existing_record) {
            $result = $wpdb->insert(
                $table_name,
                array(
                    'loja_id' => $loja_id,
                    'externo_id' => $externo_id,
                    'hash' => $hash,
                    'created_at' => $current_time
                ),
                array('%s', '%s', '%s', '%s')
            );
            if ($result === false) {
                throw new Exception('Erro ao inserir novo registro: ' . $wpdb->last_error);
            }
        } elseif ($existing_record->hash !== $hash) {
            $result = $wpdb->update(
                $table_name,
                array(
                    'hash' => $hash,
                    'updated_at' => $current_time
                ),
                array(
                    'loja_id' => $loja_id,
                    'externo_id' => $externo_id
                ),
                array('%s', '%s'),
                array('%s', '%s')
            );
            if ($result === false) {
                throw new Exception('Erro ao atualizar registro existente: ' . $wpdb->last_error);
            }
        } else {
            $result = true;
        }

        return true;
    } catch (Exception $e) {
        error_log('Erro em alt_insert_update_veiculo_externo: ' . $e->getMessage());
        return false;
    }
}

/**
 * Retorna os dados de um veículo externo específico
 * 
 * @param string $loja_id ID da loja
 * @param string $externo_id ID externo do veículo
 * @return array|false Array com os dados do veículo ou false se não encontrado
 */
function alt_get_veiculo_externo($loja_id, $externo_id) {
    global $wpdb;

    try {
        if (!alt_check_table_queue_lista_veiculos_externos()) {
            throw new Exception('Tabela de veículos externos não existe.');
        }

        $table_name = alt_name_table_lista_veiculos_externos();
        
        $veiculo = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM $table_name WHERE loja_id = %s AND externo_id = %s",
            $loja_id,
            $externo_id
        ), ARRAY_A);

        if ($veiculo === null && $wpdb->last_error) {
            throw new Exception('Erro na consulta SQL: ' . $wpdb->last_error);
        }

        return $veiculo ?: false;
    } catch (Exception $e) {
        error_log('Erro em alt_get_veiculo_externo: ' . $e->getMessage());
        return false;
    }
}

/**
 * Atualiza o campo 'veiculo_id' de um veículo externo
 * 
 * @param string $loja_id ID da loja
 * @param string $externo_id ID externo do veículo
 * @param int $veiculo_id ID do veículo no WordPress
 * @return bool True se a atualização foi bem sucedida, False caso contrário
 */
function alt_update_veiculo_externo($loja_id, $externo_id, $veiculo_id) {
    global $wpdb;
    try {
        $table_name = alt_name_table_lista_veiculos_externos();
        
        $result = $wpdb->update(
            $table_name,
            array('veiculo_id' => $veiculo_id),
            array(
                'loja_id' => $loja_id,
                'externo_id' => $externo_id
            ),
            array('%d'),
            array('%s', '%s')
        );

        if ($result === false) {
            throw new Exception('Falha ao atualizar veículo externo: ' . $wpdb->last_error);
        }

        return true;
    } catch (Exception $e) {
        error_log('Erro em alt_update_veiculo_externo: ' . $e->getMessage());
        return false;
    }
}

/**
 * Exclui um veículo externo do banco de dados e seu post correspondente no WordPress
 * 
 * Esta função remove o registro do veículo externo da tabela personalizada
 * e também exclui o post associado no WordPress, se existir.
 * 
 * @param int $loja_id ID da loja
 * @param int $externo_id ID externo do veículo
 * @return bool True se a exclusão foi bem sucedida, False caso contrário
 */
function alt_delete_veiculo_externo($loja_id, $externo_id) {
    global $wpdb;
    try {
        $table_name = alt_name_table_lista_veiculos_externos();
        
        // Busca o veiculo_id antes de deletar
        $veiculo = $wpdb->get_row(
            $wpdb->prepare(
                "SELECT veiculo_id FROM $table_name WHERE loja_id = %d AND externo_id = %d",
                $loja_id,
                $externo_id
            ),
            ARRAY_A
        );

        if ($wpdb->last_error) {
            throw new Exception('Erro ao buscar veículo: ' . $wpdb->last_error);
        }

        // Remove o registro da tabela de veículos externos
        $result = $wpdb->delete(
            $table_name,
            array('loja_id' => $loja_id, 'externo_id' => $externo_id),
            array('%d', '%d')
        );

        if ($result === false) {
            throw new Exception('Erro ao deletar veículo da tabela: ' . $wpdb->last_error);
        }

        // Se encontrou o post e a remoção da tabela foi bem sucedida, remove o post
        if ($veiculo && isset($veiculo['veiculo_id'])) {
            if (!alt_delete_veiculos($veiculo['veiculo_id'])) {
                throw new Exception('Erro ao deletar post do veículo');
            }
        }

        return true;
    } catch (Exception $e) {
        error_log('Erro em alt_delete_veiculo_externo: ' . $e->getMessage());
        return false;
    }
}

/**
 * Edita ou inclui um veículo externo no WordPress
 * 
 * @param array $veiculo Array com os dados do veículo
 * @param int $loja_user_id ID do usuário da loja
 * @return int|false ID do post criado/editado ou false em caso de erro
 */
function alt_editar_incluir_veiculo_externo($loja_id, $loja_user_id, $veiculo) {
    try {
        $titulo = alt_formatar_titulo_veiculo_externo($veiculo);
        $descricao = alt_formatar_descricao_veiculo_externo($veiculo);
        $externo_id = $veiculo['id'] ?? '';

        $veiculo_existente = alt_get_veiculo_externo($loja_id, $externo_id);

        if ($veiculo_existente && !empty($veiculo_existente['veiculo_id'])) {
            $post_id = $veiculo_existente['veiculo_id'];
        } else {
            $my_post = [
                'post_title'    => wp_strip_all_tags($titulo),
                'post_content'  => $descricao,
                'post_type'     => 'veiculos',
                'post_status'   => 'publish',
                'post_author'   => $loja_user_id
            ];
            $post_id = wp_insert_post($my_post);
            if (is_wp_error($post_id)) {
                throw new Exception('Erro ao criar post: ' . $post_id->get_error_message());
            }
            if (!alt_update_veiculo_externo($loja_id, $externo_id, $post_id)) {
                throw new Exception('Erro ao atualizar veículo externo');
            }
        }
        
        // Remove todas as meta_values
        try {
            $meta_values = get_post_meta($post_id);
            if (!empty($meta_values)) {
                foreach ($meta_values as $meta_key => $meta_value) {
                    delete_post_meta($post_id, $meta_key);
                }
            }
        } catch (Exception $e) {
            error_log('Erro ao remover meta_values: ' . $e->getMessage());
        }

        $meta_dados = [
            'alt_id' => $veiculo['id'] ?? '',
            'alt_preco' => $veiculo['valorVenda'] ?? '',
            'alt_kilometragem' => $veiculo['km'] ?? '',
            'alt_ano_fab' => $veiculo['anoFabricacao'] ?? '',
            'alt_ano_mod' => $veiculo['anoModelo'] ?? '',
            'alt_modelo_complemento' => $veiculo['versao'] ?? '',
            'alt_cor' => $veiculo['cor'] ?? '',
            'alt_combustivel' => $veiculo['combustivel'] ?? '',
            'alt_cambio' => $veiculo['cambio'] ?? '',
            'alt_portas' => $veiculo['portas'] ?? '',
            'alt_potencia' => $veiculo['potencia'] ?? '',
            'alt_placa' => $veiculo['placa'] ?? '',
            'alt_localizacao' => $veiculo['cidade'] ?? '',
            'alt_destaque' => $veiculo['destaque'] ?? 0,
        ];

        foreach ($meta_dados as $meta_key => $meta_value) {
            if (!update_post_meta($post_id, $meta_key, $meta_value)) {
                throw new Exception("Erro ao atualizar meta dado: $meta_key");
            }
        }

        if (!empty($veiculo['opcionais'])) {
            if (!update_post_meta($post_id, 'alt_acessorios', implode(', ', $veiculo['opcionais']))) {
                throw new Exception('Erro ao atualizar opcionais');
            }
        }

        $taxonomias = [
            'carroceria' => $veiculo['categoria'] ?? 'Não definida',
            'tipo' => $veiculo['tipo'] ?? 'Não definida',
            'marca' => $veiculo['marca'] ?? 'Não definida',
            'modelo' => $veiculo['modelo'] ?? 'Não definida'
        ];

        foreach ($taxonomias as $taxonomia => $valor) {
            $termo = term_exists($valor, $taxonomia) ?: wp_insert_term($valor, $taxonomia);
            if (is_wp_error($termo)) {
                throw new Exception("Erro ao inserir termo $valor na taxonomia $taxonomia: " . $termo->get_error_message());
            }
            $termo_id = is_array($termo) ? $termo['term_id'] : $termo;
            if (!wp_set_post_terms($post_id, $termo_id, $taxonomia)) {
                throw new Exception("Erro ao associar termo $valor à taxonomia $taxonomia");
            }
        }

        if ($taxonomias['marca'] == 'Honda' && strtolower($taxonomias['tipo']) == 'moto') {
            $honda_moto_termo = term_exists('honda-motos', 'marca') ?: wp_insert_term('Honda', 'marca', ['slug' => 'honda-motos']);
            if (is_wp_error($honda_moto_termo)) {
                throw new Exception('Erro ao inserir termo Honda-motos: ' . $honda_moto_termo->get_error_message());
            }
            $honda_moto_id = is_array($honda_moto_termo) ? $honda_moto_termo['term_id'] : $honda_moto_termo;
            if (!wp_set_post_terms($post_id, $honda_moto_id, 'marca')) {
                throw new Exception('Erro ao associar Honda-motos');
            }
        }

        $imagens_formatadas = alt_formatar_imagens_externo($veiculo);
        if (!empty($imagens_formatadas)) {
            if (!alt_insert_queue_car_images($post_id, $imagens_formatadas)) {
                throw new Exception('Erro ao inserir imagens na fila');
            }
            wp_schedule_single_event(alt_generate_timestamp_hook(), 'alt_salvar_imagem_no_veiculo');
        }

        alt_formatar_titulo($post_id);
        error_log('Veículo externo ' . $externo_id . ' salvo com sucesso!!!');
        return $post_id;
    } catch (Exception $e) {
        $message = 'Falha ao editar/incluir veículo externo ' . $externo_id . ': ' . $e->getMessage();
        error_log($message);
        alt_enviar_mensagem_erro_slack($message);
        return false;
    }
}

/**
 * Formata o título do veículo com base nos dados fornecidos
 * 
 * @param array $veiculo Array com os dados do veículo
 * @return string Título formatado do veículo
 */
function alt_formatar_titulo_veiculo_externo($veiculo) {
    try {
        $partes = array(
            $veiculo['marca'] ?? '',
            $veiculo['modelo'] ?? '',
            $veiculo['versao'] ?? '',
            $veiculo['cor'] ?? '',
            $veiculo['anoModelo'] ?? '',
            ($veiculo['anoModelo'] && $veiculo['anoFabricacao']) ? '/' : '',
            $veiculo['anoFabricacao'] ?? '',
        );

        if (empty(array_filter($partes))) {
            throw new Exception('Dados insuficientes para formar o título');
        }

        $partes = array_filter($partes, 'strlen');
        $titulo = implode(' ', $partes);
        
        return wp_strip_all_tags(trim($titulo));
    } catch (Exception $e) {
        error_log('Erro ao formatar título do veículo: ' . $e->getMessage());
        return 'Veículo sem título';
    }
}

/**
 * Formata a descrição do veículo extraindo apenas a parte inicial antes dos opcionais
 * 
 * @param array $veiculo Array com os dados do veículo
 * @return string Descrição formatada do veículo
 */
function alt_formatar_descricao_veiculo_externo($veiculo) {
    try {
        if (empty($veiculo['observacao'])) {
            return '';
        }
        
        // Divide a string na parte "Opcionais:"
        $partes = explode("\n\tOpcionais:", $veiculo['observacao']);
        
        // Retorna apenas a primeira parte (antes de "Opcionais:")
        return trim($partes[0]);
    } catch (Exception $e) {
        error_log('Erro ao formatar descrição do veículo: ' . $e->getMessage());
        return '';
    }
}

/**
 * Envia uma mensagem para um canal específico do Slack
 *
 * Esta função utiliza a API do Slack para enviar uma mensagem para um canal predefinido.
 * Ela lida com a autenticação, formatação da mensagem e tratamento de erros.
 *
 * @param string $mensagem O conteúdo da mensagem a ser enviada ao Slack
 * @return bool Retorna true se a mensagem foi enviada com sucesso, false em caso de falha
 */
function alt_enviar_mensagem_erro_slack($mensagem) {
    error_log('Enviando mensagem ao Slack');

    $texto = '[site]: *' . alt_get_title_site() . "*\n";
    $texto .= '[url]: ' . get_site_url() . "\n";
    $texto .= '[erro]: *' . $mensagem . "*\n";
    $texto .= '[data]: ' . date('Y-m-d H:i:s') . "\n";

    $url = 'https://slack.com/api/chat.postMessage'; // URL do endpoint do Slack
    $token = 'xoxb-2595340630-7855953470530-4N8RyJmKqDA8Wilw6AaDTdjh'; // Token do Slack
    $channel = 'C087ZA1005T'; // ID do canal

    $payload = [
        'channel' => $channel,
        'text'    => $texto,
    ];

    $args = [
        'body'    => json_encode($payload),
        'headers' => [
            'Authorization' => 'Bearer ' . $token,
            'Content-Type'  => 'application/json',
        ],
        'timeout' => 15,
    ];

    // Faz a requisição para o Slack
    $response = wp_remote_post($url, $args);

    // Verifica se houve erro na requisição
    if (is_wp_error($response)) {
        error_log('Erro ao enviar mensagem ao Slack: ' . $response->get_error_message());
        return false;
    }

    $response_body = json_decode(wp_remote_retrieve_body($response), true);

    // Verifica se o Slack retornou sucesso
    if (!$response_body['ok']) {
        error_log('Erro do Slack: ' . $response_body['error']);
        return false;
    }

    return true;
}