<?php
// includes/admin/import-profiles.php
//
// Sistema de perfis de distribuidoras para importação de CSVs.
// Cada distribuidora tem formato próprio (colunas, moeda, tipo de agregação).
// O admin escolhe o perfil no Passo 1, o sistema aplica as regras certas.
//
// Perfis suportados:
//   - tunecore_track   → Track Report (tem ISRC por linha)
//   - tunecore_data    → Data Report (agregado mensal, sem ISRC)
//   - zebralution      → IIP-DDEX (europeu, EUR, formato Zebralution/Mzouk)
//   - distrokid        → CSV DistroKid (Title, Artist, Store, Earnings)
//   - cdbaby           → CD Baby clássico (UPC, ISRC, Net Amount)
//   - onerpm           → ONErpm (ISRC, Store, Territory, Amount)
//   - auto             → fallback: detecta pelas colunas

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


/* ============================================================================
 * PERFIS — definição de cada distribuidora
 * ============================================================================ */
function rmbz_get_import_profiles() {
    return [
        // [1.5.139] Amadea Music é a distribuidora real do 1MZ Records — colocada
        // em primeiro e marcada como "recomendado" para guiar correctamente os
        // admins ao formato certo (CSV IIP-DDEX). TuneCore mantém-se na lista
        // para histórico / suporte a artistas que ainda usam essa via.
        'amadea' => [
            'id'              => 'amadea',
            'name'            => 'Amadea Music / Mzouk Ltd',
            'distributor'     => 'Amadea Music',
            'short'           => 'Amadea',
            'badge_initial'   => 'Am',
            'badge_color'     => '#1a5490',
            'type'            => 'per_track',
            'currency'        => 'EUR',
            'description'     => 'Distribuidor europeu (formato IIP-DDEX). Paga 80% das receitas dos DSPs.',
            'required_cols'   => ['isrc','partner'],
            'amount_cols'     => ['profit','net revenue','royalties','royalty'],
            'isrc_cols'       => ['isrc','optional isrc'],
            'store_cols'      => ['partner','store'],
            'country_cols'    => ['country','territory'],
            'artist_cols'     => ['track_artist','album_artist','artist'],
            'track_cols'      => ['track_name','song_title','track','title'],
            'album_cols'      => ['album','release_title'],
            'label_cols'      => ['label'],
            'upc_cols'        => ['upc_ean','upc'],
            'units_cols'      => ['quantity','streams','units'],
            // [1.5.175] Coluna de data — IIP-DDEX usa varios nomes
            // [1.5.206] Adicionado 'sale_start_date' (formato Amadea Music real)
            //           e 'sale_end_date' como fallback. Sem isto, o detector
            //           não encontrava a data e o import-processor caía no
            //           fallback ao $period (form admin), gravando todas as
            //           linhas com a mesma data.
            'date_cols'       => ['sale_start_date','sales period','sales_month','reporting_period','period','month','reporting_date','transaction_date','sale_date','sale_end_date','date'],
            'recommended'     => true,
            'sample_header'   => 'ISRC, Track_Name, Track_Artist, Partner, Quantity, Profit, Currency, Country',
        ],

        'tunecore_track' => [
            'id'              => 'tunecore_track',
            'name'            => 'TuneCore — Music Sales (Track Report)',
            'distributor'     => 'TuneCore',
            'short'           => 'TuneCore',
            'badge_initial'   => 'T',
            'badge_color'     => '#000000',
            'type'            => 'per_track',
            'currency'        => 'USD',
            'description'     => 'Relatório oficial TuneCore com ISRC, artista, loja e país por transacção.',
            'required_cols'   => ['song title'],
            'amount_cols'     => ['total earned','earnings','net sales','amount'],
            'isrc_cols'       => ['optional isrc','isrc','tc song id'],
            'store_cols'      => ['store name','store','partner'],
            'country_cols'    => ['country of sale','country','territory'],
            'artist_cols'     => ['artist','artist name'],
            'track_cols'      => ['song title','track title','title'],
            'album_cols'      => ['release title','album'],
            'label_cols'      => ['label'],
            'upc_cols'        => ['upc','upc_ean','barcode'],
            'units_cols'      => ['# units sold','units','quantity','streams'],
            // [1.5.175] Era 'date_col' singular (não usado no resolver). Agora plural array.
            'date_cols'       => ['sales period','sale_start_date','date'],
            'sample_header'   => 'Sales Period, Store Name, Country Of Sale, Artist, Song Title, Optional ISRC, # Units Sold, Total Earned',
        ],

        'zebralution' => [
            'id'              => 'zebralution',
            'name'            => 'Zebralution / IIP-DDEX (genérico)',
            'distributor'     => 'Zebralution',
            'short'           => 'Zebralution',
            'badge_initial'   => 'Z',
            'badge_color'     => '#666666',
            'type'            => 'per_track',
            'currency'        => 'EUR',
            'description'     => 'Outros distribuidores com formato IIP-DDEX genérico.',
            'required_cols'   => ['isrc','partner'],
            'amount_cols'     => ['profit','net revenue','royalties','royalty'],
            'sample_header'   => 'ISRC, Track_Name, Track_Artist, Partner, Quantity, Profit, Currency, Country',
        ],

        'distrokid' => [
            'id'              => 'distrokid',
            'name'            => 'DistroKid',
            'distributor'     => 'DistroKid',
            'short'           => 'DistroKid',
            'badge_initial'   => 'DK',
            'badge_color'     => '#1DB954',
            'type'            => 'per_track',
            'currency'        => 'USD',
            'description'     => 'Formato DistroKid com Song Title, Artist, Store, Earnings.',
            'required_cols'   => ['isrc'],
            'amount_cols'     => ['earnings','earnings (usd)','amount','total'],
            'sample_header'   => 'Reporting Date, Sale Month, Store, ISRC, Artist, Title, Quantity, Earnings',
        ],

        'cdbaby' => [
            'id'              => 'cdbaby',
            'name'            => 'CD Baby',
            'distributor'     => 'CD Baby',
            'short'           => 'CD Baby',
            'badge_initial'   => 'CB',
            'badge_color'     => '#ff8c00',
            'type'            => 'per_track',
            'currency'        => 'USD',
            'description'     => 'Formato clássico com UPC, ISRC, Net Amount por transacção.',
            'required_cols'   => ['isrc'],
            'amount_cols'     => ['net','net amount','amount','earnings','artist_amount','artist amount'],
            'sample_header'   => 'Sale Date, UPC, ISRC, Title, Artist, Partner, Country, Quantity, Net Amount',
        ],

        'onerpm' => [
            'id'              => 'onerpm',
            'name'            => 'ONErpm',
            'distributor'     => 'ONErpm',
            'short'           => 'ONErpm',
            'badge_initial'   => 'OR',
            'badge_color'     => '#e60039',
            'type'            => 'per_track',
            'currency'        => 'USD',
            'description'     => 'Formato ONErpm com ISRC, Store, Territory, Amount.',
            'required_cols'   => ['isrc'],
            'amount_cols'     => ['amount','revenue','earnings','payable'],
            'sample_header'   => 'Month, ISRC, Title, Artist, Store, Territory, Streams, Amount',
        ],

        'auto' => [
            'id'              => 'auto',
            'name'            => 'Auto-detectar (genérico)',
            'distributor'     => 'Desconhecida',
            'short'           => 'Auto',
            'badge_initial'   => '?',
            'badge_color'     => '#888888',
            'type'            => 'per_track',
            'currency'        => 'USD',
            'description'     => 'Deixa o sistema adivinhar pelas colunas. Use apenas se a sua distribuidora não está na lista.',
            'required_cols'   => ['isrc'],
            'amount_cols'     => ['profit','net_revenue','usd_payable','payable','royalty','royalties','amount','earnings','total'],
            'fallback'        => true,
        ],
    ];
}

function rmbz_get_profile( $id ) {
    $profiles = rmbz_get_import_profiles();
    return $profiles[ $id ] ?? $profiles['auto'];
}


/* ============================================================================
 * DETECÇÃO — sugere o perfil mais provável baseado no cabeçalho do CSV
 * ============================================================================ */
function rmbz_detect_profile_from_header( array $header_lower ) {
    if ( empty($header_lower) ) return 'auto';

    // TuneCore Track Report (Music Sales): tem Sales Period + Store Name + TC Song ID + Total Earned
    if ( in_array('sales period', $header_lower, true)
         && in_array('store name', $header_lower, true)
         && ( in_array('tc song id', $header_lower, true) || in_array('optional isrc', $header_lower, true) ) ) {
        return 'tunecore_track';
    }

    // Zebralution/IIP-DDEX: tem Partner + Profit + Album_Artist
    if ( in_array('partner', $header_lower, true)
         && ( in_array('profit', $header_lower, true) || in_array('album_artist', $header_lower, true) ) ) {
        return 'zebralution';
    }

    // DistroKid: Sale Month + Store + Earnings
    if ( ( in_array('sale month', $header_lower, true) || in_array('reporting date', $header_lower, true) )
         && in_array('earnings', $header_lower, true) ) {
        return 'distrokid';
    }

    // CD Baby: Net Amount
    if ( in_array('net amount', $header_lower, true) ) {
        return 'cdbaby';
    }

    // ONErpm: Territory (vs Country) + Amount
    if ( in_array('territory', $header_lower, true)
         && in_array('amount', $header_lower, true) ) {
        return 'onerpm';
    }

    return 'auto';
}


/* ============================================================================
 * VALIDAÇÃO — verifica se o CSV tem as colunas que o perfil exige
 * ============================================================================ */
function rmbz_validate_profile_match( $profile_id, array $header_lower ) {
    $profile = rmbz_get_profile($profile_id);
    $missing = [];

    foreach ( (array) $profile['required_cols'] as $required ) {
        if ( ! in_array($required, $header_lower, true) ) {
            $missing[] = $required;
        }
    }

    // Verificar se pelo menos uma coluna de valor está presente
    $has_amount = false;
    foreach ( (array) $profile['amount_cols'] as $amt ) {
        if ( in_array($amt, $header_lower, true) ) { $has_amount = true; break; }
    }
    if ( ! $has_amount ) $missing[] = 'valor monetário (' . implode(' / ', $profile['amount_cols']) . ')';

    return [
        'valid'   => empty($missing),
        'missing' => $missing,
        'profile' => $profile,
    ];
}


/* ============================================================================
 * RESOLVE COLUMN INDICES — mapa completo de colunas baseado no perfil
 * ============================================================================
 * Devolve array indexado com os índices das colunas relevantes no CSV,
 * usando primeiro a lista específica do perfil e caindo para fallbacks genéricos.
 */
function rmbz_resolve_column_indices( array $header_lower, $profile = null ) {
    $find_first = function(array $candidates) use ($header_lower) {
        foreach ( $candidates as $c ) {
            $i = array_search(strtolower($c), $header_lower, true);
            if ( $i !== false ) return $i;
        }
        return false;
    };

    $p = is_array($profile) ? $profile : [];

    // Se o perfil define listas específicas, usamo-las primeiro; senão fallback genérico.
    $isrc_cols    = $p['isrc_cols']    ?? ['isrc','isrc_code','isrc code','optional isrc','tc song id'];
    $amount_cols  = $p['amount_cols']  ?? ['profit','total earned','net_revenue','net revenue','usd_payable','payable','net','amount','royalty','royalties','earnings','total','artist_amount'];
    $store_cols   = $p['store_cols']   ?? ['store name','partner','store','platform','service','dsp','source'];
    $country_cols = $p['country_cols'] ?? ['country of sale','country','territory','country_code'];
    $streams_cols = $p['units_cols']   ?? ['streams','# units sold','quantity','units sold','plays','units','qty'];
    $track_cols   = $p['track_cols']   ?? ['song title','track_name','track','title','song','song_title'];
    $artist_cols  = $p['artist_cols']  ?? ['artist','track_artist','album_artist','artist_name','main_artist'];
    $upc_cols     = $p['upc_cols']     ?? ['upc','upc_ean','ean','barcode'];
    $album_cols   = $p['album_cols']   ?? ['release title','album','album_name','release_title'];
    $label_cols   = $p['label_cols']   ?? ['label','label_name','record_label'];
    // [1.5.175] Date col reading — agora usa array do profile com fallback genérico amplo.
    // Antes, o resolver só procurava 'sales period' ou 'sale_start_date' hardcoded.
    // Resultado: imports Amadea (formato IIP-DDEX) nunca detectavam mês — o admin
    // tinha de mudar manualmente para o mês correcto.
    $date_cols    = $p['date_cols']    ?? [
        'sales period',
        'sale_start_date',
        'reporting_period',
        'reporting_date',
        'sales_month',
        'period',
        'month',
        'transaction_date',
        'sale_date',
        'date',
    ];

    return [
        'isrc'       => $find_first($isrc_cols),
        'amount'     => $find_first($amount_cols),
        'store'      => $find_first($store_cols),
        'country'    => $find_first($country_cols),
        'streams'    => $find_first($streams_cols),
        'track_name' => $find_first($track_cols),
        'artist'     => $find_first($artist_cols),
        'upc'        => $find_first($upc_cols),
        'album'      => $find_first($album_cols),
        'label'      => $find_first($label_cols),
        'currency'   => array_search('currency', $header_lower),
        'date'       => $find_first($date_cols),
    ];
}


/* ============================================================================
 * PROCESSADOR ESPECIAL — TuneCore Data Report (agregado mensal)
 * Cada linha = 1 mês. Sem ISRC. Vai tudo para Black Box como entrada especial.
 * ============================================================================ */
function rmbz_process_tunecore_data_report( $handle, $header_lower, $period, $stats, $temp_file_hash ) {
    global $wpdb;
    $t_unclaimed = $wpdb->prefix . 'rmbz_distro_unclaimed';

    $idx_date    = array_search('date', $header_lower);
    $idx_streams = array_search('streams', $header_lower);
    $idx_songs   = array_search('songs sold', $header_lower);
    $idx_total   = array_search('total earned', $header_lower);
    if ( $idx_total === false ) $idx_total = array_search('total_earned', $header_lower);
    if ( $idx_total === false ) $idx_total = array_search('earnings', $header_lower);

    if ( $idx_date === false || $idx_total === false ) {
        return [ 'error' => 'Colunas Date + Total Earned não encontradas.' ];
    }

    while ( ($row = fgetcsv($handle)) !== FALSE ) {
        if ( ! is_array($row) ) continue;

        $date_raw = trim( $row[$idx_date] ?? '' );
        $val = (float) str_replace([',','$','€'], ['.','',''], (string) ($row[$idx_total] ?? '0'));
        if ( empty($date_raw) || $val <= 0 ) { $stats['skipped']++; continue; }

        $ts = strtotime($date_raw);
        if ( ! $ts ) { $stats['skipped']++; continue; }

        // Normalizar para primeiro dia do mês (chave de agregação)
        $month_key = date('Y-m-01', $ts);
        $month_label = rmbz_fmt_month_year_pt($ts);
        $streams_count = $idx_streams !== false ? (int) ($row[$idx_streams] ?? 0) : 0;
        $songs_sold    = $idx_songs !== false ? (int) ($row[$idx_songs] ?? 0) : 0;

        // Identificador único desta entrada agregada:
        // usa um "ISRC virtual" para Data Reports, com marcador especial
        $virtual_isrc = 'AGG-TUNECORE-' . date('Ym', $ts);

        // UPSERT por virtual_isrc + período
        $existing = $wpdb->get_row( $wpdb->prepare(
            "SELECT id, amount, streams_total, line_count
             FROM $t_unclaimed
             WHERE isrc = %s AND report_date = %s AND status = 'pending'
             LIMIT 1",
            $virtual_isrc, $month_key
        ) );

        if ( $existing ) {
            $wpdb->update( $t_unclaimed,
                [
                    'amount'        => (float) $existing->amount + $val,
                    'streams_total' => (int)   $existing->streams_total + $streams_count,
                    'line_count'    => (int)   $existing->line_count + 1,
                ],
                [ 'id' => (int) $existing->id ],
                [ '%f','%d','%d' ],
                [ '%d' ]
            );
        } else {
            $wpdb->insert( $t_unclaimed, [
                'isrc'          => $virtual_isrc,
                'isrc_code'     => $virtual_isrc,
                'track_title'   => 'TuneCore Agregado · ' . $month_label,
                'artist_name'   => '(distribuição por determinar)',
                'album'         => $songs_sold > 0 ? $songs_sold . ' música(s) vendida(s)' : '',
                'label'         => 'TuneCore Data Report',
                'amount'        => $val,
                'streams_total' => $streams_count,
                'line_count'    => 1,
                'platform'      => 'TuneCore (agregado)',
                'country'       => 'GLOBAL',
                'stores'        => wp_json_encode(['TuneCore' => $val]),
                'countries'     => wp_json_encode(['GLOBAL' => $val]),
                'report_date'   => $month_key,
                'status'        => 'pending',
            ] );
        }

        $stats['unclaimed']++;
        $stats['total_usd'] += $val;
    }

    return $stats;
}


/* ============================================================================
 * HELPER — nome de mês em português
 * ============================================================================ */
function rmbz_fmt_month_year_pt( $ts ) {
    $meses = ['', 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',
              'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'];
    return $meses[ (int) date('n', $ts) ] . ' ' . date('Y', $ts);
}


/* ============================================================================
 * RENDER — cards de selecção de distribuidora (Passo 1)
 * ============================================================================ */
function rmbz_render_profile_selector( $selected = '' ) {
    $profiles = rmbz_get_import_profiles();
    ?>
    <div class="rmbz-profile-selector">
        <h3 style="margin: 0 0 4px 0; font-size:15px; font-weight:500;">Escolha a sua distribuidora</h3>
        <p style="margin: 0 0 14px 0; color:#666; font-size:12px;">
            Cada distribuidora usa um formato diferente. Escolher correctamente garante que todos os campos são lidos.
        </p>
        <div class="rmbz-profile-grid">
            <?php foreach ( $profiles as $p ):
                $is_selected = ( $selected === $p['id'] );
                $recommended = ! empty($p['recommended']);
            ?>
                <label class="rmbz-profile-card <?php echo $is_selected ? 'selected' : ''; ?> <?php echo $recommended ? 'recommended' : ''; ?>">
                    <input type="radio" name="profile_id" value="<?php echo esc_attr($p['id']); ?>" <?php checked($is_selected); ?> required>
                    <div class="rmbz-profile-card-head">
                        <div class="badge" style="background: <?php echo esc_attr($p['badge_color']); ?>;">
                            <?php echo esc_html($p['badge_initial']); ?>
                        </div>
                        <div>
                            <strong><?php echo esc_html($p['short']); ?></strong>
                            <?php if ( $recommended ): ?>
                                <span class="tag-recommended">recomendado</span>
                            <?php endif; ?>
                        </div>
                    </div>
                    <div class="rmbz-profile-card-body">
                        <div class="name"><?php echo esc_html($p['name']); ?></div>
                        <div class="desc"><?php echo esc_html($p['description']); ?></div>
                        <div class="meta">
                            <span class="cur"><?php echo esc_html($p['currency']); ?></span>
                            <?php if ( $p['type'] === 'aggregate_monthly' ): ?>
                                <span class="type-agg">agregado</span>
                            <?php else: ?>
                                <span class="type-track">por faixa</span>
                            <?php endif; ?>
                        </div>
                    </div>
                </label>
            <?php endforeach; ?>
        </div>
    </div>

    <style>
    .rmbz-profile-selector { margin: 0 0 20px 0; text-align: left; }
    .rmbz-profile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; }
    .rmbz-profile-card { background: #fff; border: 2px solid #e5e5e5; border-radius: 8px; padding: 12px; cursor: pointer; transition: all 0.15s; display: block; position: relative; }
    .rmbz-profile-card:hover { border-color: #3498db; background: #fafbfc; }
    .rmbz-profile-card.selected { border-color: #3498db; background: #eef7ff; box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1); }
    .rmbz-profile-card.recommended { border-color: #2ecc71; }
    .rmbz-profile-card.recommended.selected { border-color: #3498db; }
    .rmbz-profile-card input[type="radio"] { position: absolute; top: 12px; right: 12px; margin: 0; cursor: pointer; }
    .rmbz-profile-card-head { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; }
    .rmbz-profile-card-head .badge { width: 32px; height: 32px; border-radius: 6px; display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; font-size: 13px; flex-shrink: 0; }
    .rmbz-profile-card-head strong { font-size: 13px; color: #222; display: block; }
    .rmbz-profile-card-head .tag-recommended { font-size: 9px; color: #27ae60; text-transform: uppercase; font-weight: 600; letter-spacing: 0.5px; }
    .rmbz-profile-card-body .name { font-size: 11px; color: #555; font-weight: 500; margin-bottom: 4px; }
    .rmbz-profile-card-body .desc { font-size: 11px; color: #777; line-height: 1.4; margin-bottom: 8px; min-height: 30px; }
    .rmbz-profile-card-body .meta { display: flex; gap: 6px; }
    .rmbz-profile-card-body .meta span { font-size: 10px; padding: 2px 8px; border-radius: 10px; background: #f0f0f0; color: #555; text-transform: uppercase; font-weight: 600; letter-spacing: 0.3px; }
    .rmbz-profile-card-body .meta .cur { background: #e8f4fd; color: #1a5490; }
    .rmbz-profile-card-body .meta .type-agg { background: #fff3cd; color: #856404; }
    .rmbz-profile-card-body .meta .type-track { background: #d4edda; color: #155724; }
    </style>
    <?php
}
