<?php
/**
 * includes/admin/import-additional.php
 *
 * ============================================================================
 * RE-IMPORTAÇÃO ADICIONAL (PICK-UP) — 1.5.115
 * ============================================================================
 *
 * Permite voltar a um import já feito e processar linhas que tinham sido
 * desmarcadas no preview da primeira vez. Reusa o CSV arquivado (1.5.108).
 *
 * Cenário de uso:
 *   - Importei 100 faixas, desmarquei 20 (artista X ainda não cadastrado)
 *   - Mais tarde cadastro o artista X e quero importar essas 20 linhas
 *   - Clico "↻ Re-importar do mesmo CSV" no card daquele import
 *   - Sistema abre o preview com as 80 já importadas marcadas a cinza
 *     ("✓ Já importado") e desmarcadas por padrão; as 20 ficam disponíveis
 *     para selecção
 *   - Confirmo, cria-se novo log ligado ao primeiro via additional_import_of
 *
 * Diferença vs "Desfazer Anulação" (1.5.108):
 *   - Unrevert: usado quando um import foi anulado e queremos repor tudo
 *   - Additional: usado quando o import está activo e queremos somar linhas
 *     que tinham ficado de fora
 *
 * Protecções contra duplicação:
 *   - Linhas já importadas ficam visualmente marcadas e desmarcadas por
 *     default no preview
 *   - O processador faz dedup por (ISRC, reporting_period, hash original)
 *     antes de inserir no ledger
 */

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


function rmbz_handle_additional_import() {
    if ( ! current_user_can('manage_options') ) wp_die('Sem permissão.');

    $log_id = isset($_GET['log_id']) ? (int) $_GET['log_id'] : 0;
    if ( $log_id <= 0 ) wp_die('ID inválido.');

    check_admin_referer( 'rmbz_additional_import_' . $log_id );

    global $wpdb;
    $t_logs = $wpdb->prefix . 'rmbz_distro_import_logs';
    $base_url = admin_url('admin.php?page=rmbz-admin-distribution&tab=royalties&rsub=imports');

    $log = $wpdb->get_row( $wpdb->prepare(
        "SELECT * FROM $t_logs WHERE id = %d",
        $log_id
    ) );

    if ( ! $log ) {
        wp_safe_redirect( add_query_arg('additional_error', urlencode('Importação não encontrada.'), $base_url) );
        exit;
    }

    // Validações
    if ( $log->status === 'reverted' ) {
        wp_safe_redirect( add_query_arg('additional_error', urlencode('Esta importação está anulada — usa "Desfazer Anulação" em vez disto.'), $base_url) );
        exit;
    }
    if ( ! empty($log->approval_status) && $log->approval_status === 'rejected' ) {
        wp_safe_redirect( add_query_arg('additional_error', urlencode('Esta importação foi rejeitada.'), $base_url) );
        exit;
    }
    if ( empty($log->archived_path) || ! function_exists('rmbz_archive_csv_exists') || ! rmbz_archive_csv_exists($log->archived_path) ) {
        wp_safe_redirect( add_query_arg('additional_error', urlencode('CSV original não está arquivado (importação anterior à 1.5.108 ou já foi limpo pela retenção).'), $base_url) );
        exit;
    }

    // Preparar área temporária
    $upload_dir = wp_upload_dir();
    if ( ! empty($upload_dir['error']) ) {
        wp_safe_redirect( add_query_arg('additional_error', urlencode('Erro de filesystem.'), $base_url) );
        exit;
    }
    $tmp_dir = $upload_dir['basedir'] . '/rmbz_temp_imports';
    if ( ! file_exists($tmp_dir) ) wp_mkdir_p($tmp_dir);

    // Nome temporário com prefixo "additional_"
    $original_basename = basename($log->archived_path);
    $clean_name = preg_replace('/^\d+_[a-f0-9]{8}_/', '', $original_basename);
    if ( empty($clean_name) ) $clean_name = $original_basename;
    $tmp_name = 'additional_' . time() . '_' . sanitize_file_name($clean_name);
    $tmp_path = $tmp_dir . '/' . $tmp_name;

    if ( ! @copy( $log->archived_path, $tmp_path ) ) {
        wp_safe_redirect( add_query_arg('additional_error', urlencode('Erro ao copiar CSV arquivado.'), $base_url) );
        exit;
    }

    // ATENÇÃO: NÃO mexemos em rmbz_imported_csv_hashes — o hash continua
    // bloqueado para uploads novos. Mas o nosso fluxo aqui NÃO faz log de
    // hash duplicado (ver flag `rmbz_force_allow_duplicate_hash` mais
    // abaixo). Em vez disso usamos transient para sinalizar ao processador
    // que esta é uma "additional import" do log $log_id.
    $current_user = wp_get_current_user();
    $admin_login = $current_user && $current_user->exists() ? $current_user->user_login : 'admin';
    set_transient( 'rmbz_additional_pending_' . md5($tmp_name), [
        'original_log_id' => (int) $log->id,
        'original_hash'   => (string) $log->file_hash,
        'admin'           => $admin_login,
    ], 30 * MINUTE_IN_SECONDS );

    // Redireccionar para o fluxo de preview do import normal
    wp_safe_redirect( admin_url(
        'admin.php?page=rmbz-admin-distribution&tab=import' .
        '&temp_file=' . urlencode($tmp_name) .
        '&from_additional=' . (int) $log->id
    ) );
    exit;
}
add_action( 'admin_post_rmbz_additional_import', 'rmbz_handle_additional_import' );


/**
 * Para um log original, devolve um set de chaves (ISRC|reporting_period)
 * que já estão no ledger. Usado pelo preview para marcar como "já importado".
 *
 * Estratégia (em camadas):
 *   1. Buscar do ledger via `import_log_id` (1.5.104+)
 *   2. Buscar do ledger via `import_hash` + coluna `isrc` (1.5.115+)
 *   3. Fallback: buscar de `rmbz_distro_unclaimed` por `import_hash`
 *      (cobre imports antigos pre-1.5.115 onde o ledger não tinha ISRC)
 *
 * @return array  associativo: ['ISRC|2024-03' => true, ...]
 *                Para fallback, o period pode ser '' (vazio).
 */
function rmbz_get_already_imported_keys( $original_log_id ) {
    global $wpdb;
    $t_ledger    = $wpdb->prefix . 'rmbz_distro_ledger';
    $t_logs      = $wpdb->prefix . 'rmbz_distro_import_logs';
    $t_unclaimed = $wpdb->prefix . 'rmbz_distro_unclaimed';

    // Buscar info do log para ter o file_hash (usado em fallbacks)
    $log = $wpdb->get_row( $wpdb->prepare(
        "SELECT id, file_hash FROM $t_logs WHERE id = %d",
        $original_log_id
    ) );
    if ( ! $log ) return [];
    $hash = (string) $log->file_hash;

    $set = [];

    // ─── Camada 1+2: ledger ───
    if ( $wpdb->get_var("SHOW TABLES LIKE '$t_ledger'") === $t_ledger ) {
        $cols = $wpdb->get_col("SHOW COLUMNS FROM $t_ledger");
        $has_isrc = in_array('isrc', $cols, true);

        if ( $has_isrc ) {
            $rows = $wpdb->get_results( $wpdb->prepare(
                "SELECT DISTINCT isrc, reporting_period
                 FROM $t_ledger
                 WHERE ( import_log_id = %d
                      OR import_log_id IN (
                            SELECT id FROM $t_logs
                            WHERE additional_import_of = %d
                         )
                      OR import_hash = %s
                      )
                   AND reverted_at IS NULL
                   AND isrc IS NOT NULL
                   AND isrc != ''",
                $original_log_id, $original_log_id, $hash
            ) );
            foreach ( $rows as $r ) {
                $key = strtoupper(trim((string) $r->isrc)) . '|' . trim((string) $r->reporting_period);
                $set[$key] = true;
            }
        }
    }

    // ─── Camada 3: fallback via unclaimed ───
    // (sempre corre, agrega; pode haver overlap com camada 1+2 mas não importa)
    if ( ! empty($hash) && $wpdb->get_var("SHOW TABLES LIKE '$t_unclaimed'") === $t_unclaimed ) {
        $rows = $wpdb->get_results( $wpdb->prepare(
            "SELECT DISTINCT isrc, report_date
             FROM $t_unclaimed
             WHERE import_hash = %s
               AND isrc IS NOT NULL
               AND isrc != ''",
            $hash
        ) );
        foreach ( $rows as $r ) {
            $period = '';
            if ( ! empty($r->report_date) ) {
                $period = substr((string) $r->report_date, 0, 7);
            }
            $key = strtoupper(trim((string) $r->isrc)) . '|' . $period;
            $set[$key] = true;
        }
    }

    return $set;
}


/**
 * Hook para pegar info do "additional import" no preview e passar
 * para o renderer marcar linhas já importadas.
 *
 * Usado em admin-import-royalties.php para decidir o estado inicial
 * dos checkboxes.
 */
function rmbz_get_additional_import_context( $temp_filename ) {
    if ( empty($temp_filename) ) return null;
    $key = 'rmbz_additional_pending_' . md5($temp_filename);
    $data = get_transient($key);
    return is_array($data) ? $data : null;
}


/**
 * Hook ao log_csv_import: quando o "additional import" é committado,
 * preencher additional_import_of no novo log.
 */
add_action( 'rmbz_after_log_csv_import', function( $new_log_id, $hash, $temp_filename ) {
    if ( empty($temp_filename) ) return;
    $key = 'rmbz_additional_pending_' . md5($temp_filename);
    $pending = get_transient($key);
    if ( ! is_array($pending) || empty($pending['original_log_id']) ) return;

    global $wpdb;
    $t_logs = $wpdb->prefix . 'rmbz_distro_import_logs';

    $wpdb->update(
        $t_logs,
        [ 'additional_import_of' => (int) $pending['original_log_id'] ],
        [ 'id' => (int) $new_log_id ],
        [ '%d' ], [ '%d' ]
    );

    delete_transient($key);
}, 10, 3 );
