<?php
/**
 * 1MZ For Artists — Migração de Schema do Sistema de Origem v1.0
 *
 * Adiciona:
 *   1. Tabela `rmbz_app_devices` — histórico de dispositivos conhecidos
 *   2. Colunas em `rmbz_withdrawal_requests`:
 *        - origin_channel    (web | app_android | app_ios | api)
 *        - origin_ip         (IPv4 ou IPv6)
 *        - origin_user_agent (string truncada)
 *        - origin_device_id  (UUID estável da app)
 *        - origin_app_version
 *
 * Migração é IDEMPOTENTE — pode correr várias vezes sem efeito secundário.
 * É chamada automaticamente quando a versão do schema é bumped.
 *
 * @package 1MZ_For_Artists
 * @since 1.6.1
 */

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

/**
 * Versão do schema deste módulo. Bump quando alterar estrutura.
 */
define( 'RMBZ_ORIGIN_SCHEMA_VERSION', '1.0.0' );

/**
 * Hook que corre na activação do plugin OU quando se detecta versão antiga.
 * Pode ser chamado a qualquer momento — é seguro.
 */
function rmbz_origin_schema_install_or_upgrade() {
    $current = get_option( 'rmbz_origin_schema_version', '0.0.0' );
    if ( version_compare( $current, RMBZ_ORIGIN_SCHEMA_VERSION, '>=' ) ) {
        return; // já está actualizado
    }

    global $wpdb;
    $charset_collate = $wpdb->get_charset_collate();

    require_once ABSPATH . 'wp-admin/includes/upgrade.php';

    // -----------------------------------------------------------
    // 1. TABELA DE DISPOSITIVOS CONHECIDOS POR UTILIZADOR
    // -----------------------------------------------------------
    // Cada login com um device_id novo cria uma linha. Logins seguintes
    // do mesmo dispositivo só actualizam last_seen_at e last_ip.
    // O Guarda-Costas consulta esta tabela para detectar dispositivos
    // novos (red flag em pedidos de levantamento).
    $sql_devices = "CREATE TABLE {$wpdb->prefix}rmbz_app_devices (
        id bigint(20) NOT NULL AUTO_INCREMENT,
        user_telemovel varchar(20) NOT NULL,
        device_id varchar(64) NOT NULL,
        device_label varchar(120) DEFAULT NULL,
        first_seen_at datetime NOT NULL,
        last_seen_at datetime NOT NULL,
        first_ip varchar(45) DEFAULT NULL,
        last_ip varchar(45) DEFAULT NULL,
        last_user_agent varchar(255) DEFAULT NULL,
        last_app_version varchar(20) DEFAULT NULL,
        login_count int(11) NOT NULL DEFAULT 1,
        is_trusted tinyint(1) NOT NULL DEFAULT 0,
        marked_suspicious_at datetime DEFAULT NULL,
        suspicious_reason varchar(255) DEFAULT NULL,
        PRIMARY KEY (id),
        UNIQUE KEY uniq_user_device (user_telemovel, device_id),
        KEY idx_telemovel (user_telemovel),
        KEY idx_last_seen (last_seen_at)
    ) {$charset_collate};";

    dbDelta( $sql_devices );

    // -----------------------------------------------------------
    // 2. COLUNAS NOVAS EM rmbz_withdrawal_requests
    // -----------------------------------------------------------
    // dbDelta não consegue alterar colunas em tabelas existentes de forma
    // fiável, então fazemos ALTER TABLE manual com guards.
    rmbz_origin_add_column_if_missing( 'rmbz_withdrawal_requests', 'origin_channel',
        "varchar(20) DEFAULT 'web' NOT NULL" );
    rmbz_origin_add_column_if_missing( 'rmbz_withdrawal_requests', 'origin_ip',
        "varchar(45) DEFAULT NULL" );
    rmbz_origin_add_column_if_missing( 'rmbz_withdrawal_requests', 'origin_user_agent',
        "varchar(255) DEFAULT NULL" );
    rmbz_origin_add_column_if_missing( 'rmbz_withdrawal_requests', 'origin_device_id',
        "varchar(64) DEFAULT NULL" );
    rmbz_origin_add_column_if_missing( 'rmbz_withdrawal_requests', 'origin_app_version',
        "varchar(20) DEFAULT NULL" );

    // Índice em origin_channel para consultas de relatório (ex: "quantos
    // levantamentos vieram do app este mês").
    rmbz_origin_add_index_if_missing( 'rmbz_withdrawal_requests', 'idx_origin_channel',
        '(origin_channel)' );

    update_option( 'rmbz_origin_schema_version', RMBZ_ORIGIN_SCHEMA_VERSION );
}

/**
 * Adiciona uma coluna a uma tabela se não existir.
 *
 * @param string $table_name_no_prefix nome da tabela SEM prefixo (ex: 'rmbz_xxx')
 * @param string $column nome da coluna
 * @param string $definition definição SQL (ex: "varchar(20) DEFAULT 'web' NOT NULL")
 */
function rmbz_origin_add_column_if_missing( $table_name_no_prefix, $column, $definition ) {
    global $wpdb;
    $table = $wpdb->prefix . $table_name_no_prefix;

    // Verificar que a tabela existe (pode estar a correr antes do plugin principal)
    if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) !== $table ) {
        return;
    }

    $exists = $wpdb->get_var( $wpdb->prepare(
        "SELECT COLUMN_NAME FROM information_schema.COLUMNS
         WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND COLUMN_NAME = %s",
        DB_NAME, $table, $column
    ) );

    if ( ! $exists ) {
        // ALTER TABLE não suporta prepare() para nomes de tabela/coluna,
        // mas $table e $column vêm hardcoded deste ficheiro (não input).
        $wpdb->query( "ALTER TABLE {$table} ADD COLUMN {$column} {$definition}" );
    }
}

/**
 * Adiciona um índice a uma tabela se não existir.
 *
 * @param string $table_name_no_prefix
 * @param string $index_name
 * @param string $columns_clause ex: "(coluna1, coluna2)"
 */
function rmbz_origin_add_index_if_missing( $table_name_no_prefix, $index_name, $columns_clause ) {
    global $wpdb;
    $table = $wpdb->prefix . $table_name_no_prefix;

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

    $exists = $wpdb->get_var( $wpdb->prepare(
        "SELECT INDEX_NAME FROM information_schema.STATISTICS
         WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND INDEX_NAME = %s LIMIT 1",
        DB_NAME, $table, $index_name
    ) );

    if ( ! $exists ) {
        $wpdb->query( "ALTER TABLE {$table} ADD INDEX {$index_name} {$columns_clause}" );
    }
}

// Correr a migração no init (uma vez por carregamento; é idempotente).
add_action( 'init', 'rmbz_origin_schema_install_or_upgrade', 5 );
