<?php
// includes/subscription-functions.php

/**
 * Funções de Gestão de Subscrições (Acesso Artista).
 * Verifica validade, datas de expiração e processa pagamentos mensais.
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Acesso direto bloqueado
}

/**
 * Verifica se o utilizador (artista) tem uma subscrição ativa.
 *
 * @param string $telemovel O número de telemóvel do utilizador.
 * @return bool True se tiver subscrição válida, False caso contrário.
 */
function rmbz_user_has_active_subscription( $telemovel ) {
    global $wpdb;
    $table = $wpdb->prefix . 'rmbz_subscriptions';
    $now = current_time('mysql');
    
    // Procura se existe ALGUMA subscrição onde a data de fim ainda não chegou
    $active_id = $wpdb->get_var( $wpdb->prepare(
        "SELECT id FROM $table WHERE user_telemovel = %s AND end_date > %s LIMIT 1", 
        $telemovel, $now
    ) );

    return $active_id ? true : false;
}

/**
 * Obtém a data de expiração da subscrição de um utilizador.
 *
 * @param string $telemovel O número de telemóvel.
 * @return string|null A data de expiração (Y-m-d H:i:s) ou null.
 */
function rmbz_get_subscription_expiry( $telemovel ) {
    global $wpdb;
    $table = $wpdb->prefix . 'rmbz_subscriptions';
    
    // Pega sempre a data mais distante no futuro
    return $wpdb->get_var( $wpdb->prepare( 
        "SELECT end_date FROM $table WHERE user_telemovel = %s ORDER BY end_date DESC LIMIT 1", 
        $telemovel 
    ) );
}

/**
 * Processa o pagamento da subscrição usando o saldo da carteira.
 * Desconta o valor, atualiza a data de expiração e restaura os privilégios totais VIP.
 *
 * @param string $telemovel O número de telemóvel do utilizador.
 * @return array Resultado da operação ['success' => bool, 'message' => string].
 */
function rmbz_process_subscription_payment( $telemovel ) {
    // Obter configurações do admin ou usar os padrões do 1MZ (1500 MT / 30 dias)
    $price = (float) get_option('rmbz_sub_price', 1500); 
    $days = (int) get_option('rmbz_sub_days', 30);
    
    // 1. Verificar se o utilizador tem saldo suficiente na carteira
    $balance = rmbz_get_wallet_balance_by_phone( $telemovel );
    if ( $balance < $price ) {
        return [ 'success' => false, 'message' => 'Saldo insuficiente na carteira. Por favor, faça um depósito.' ];
    }

    // 2. Tentar debitar o valor da carteira
    $details = "Pagamento de Subscrição 1MZ ($days dias)";
    $debit_result = rmbz_update_wallet_balance( $telemovel, -$price, 'subscription_payment', null, $details );
    
    if ( ! $debit_result['success'] ) {
        return [ 'success' => false, 'message' => 'Erro ao processar o pagamento: ' . $debit_result['error'] ];
    }

    // [1.6.380] Congelar a multa por atraso ANTES de estender a subscrição.
    if ( function_exists( 'rmbz_project_freeze_pending_fine' ) ) {
        rmbz_project_freeze_pending_fine( $telemovel );
    }

    // 3. Atualizar ou Criar a subscrição na base de dados
    global $wpdb;
    $table = $wpdb->prefix . 'rmbz_subscriptions';
    
    // Busca a subscrição com a data mais longa
    $existing = $wpdb->get_row( $wpdb->prepare(
        "SELECT id, end_date FROM $table WHERE user_telemovel = %s ORDER BY end_date DESC LIMIT 1", 
        $telemovel
    ) );
    
    $start_date = current_time('mysql');
    $now_timestamp = current_time('timestamp');
    
    // Calcula a nova data de fim
    if ( $existing && $existing->end_date > $start_date ) {
        $new_end_date = date('Y-m-d H:i:s', strtotime("+$days days", strtotime($existing->end_date)));
    } else {
        $new_end_date = date('Y-m-d H:i:s', strtotime("+$days days", $now_timestamp));
    }

    if ( $existing ) {
        // ATUALIZAR registo existente (Renovação)
        $wpdb->update(
            $table,
            [ 
                'start_date' => $start_date, 
                'end_date' => $new_end_date, 
                'last_payment_amount' => $price, 
                'status' => 'active' 
            ],
            [ 'id' => $existing->id ],
            [ '%s', '%s', '%f', '%s' ], 
            [ '%d' ]
        );
    } else {
        // INSERIR novo registo (Primeira vez)
        $wpdb->insert(
            $table,
            [ 
                'user_telemovel' => $telemovel, 
                'start_date' => $start_date, 
                'end_date' => $new_end_date, 
                'last_payment_amount' => $price, 
                'status' => 'active' 
            ],
            [ '%s', '%s', '%s', '%f', '%s' ]
        );
    }

    // ==========================================================================
    // 4. RESTAURAR PERMISSÕES TOTAIS (FULL VIP)
    // Se ele pagou com dinheiro, apagamos os limites de cupões antigos!
    // ==========================================================================
    $wallet_table = $wpdb->prefix . 'rmbz_wallets';
    $wallet = $wpdb->get_row($wpdb->prepare("SELECT extra_data FROM {$wallet_table} WHERE user_telemovel = %s", $telemovel));
    
    $w_extra = !empty($wallet->extra_data) ? json_decode($wallet->extra_data, true) : [];
    
    // Forçamos que ele tenha permissão total (1) para tudo
    $w_extra['vip_permissions'] = [
        'distribute' => 1,
        'site'       => 1,
        'social'     => 1,
        'video'      => 1
    ];
    
    $wpdb->update(
        $wallet_table, 
        ['extra_data' => wp_json_encode($w_extra)], 
        ['user_telemovel' => $telemovel]
    );
    // ==========================================================================

    return [ 'success' => true, 'message' => 'Subscrição ativada com sucesso! Recebeu acesso VIP Total.' ];
}

/* ============================================================================
 * [1.5.372] DURAÇÕES VIP — 1 / 2 / 3 / 4 / 12 meses, com ou sem IA.
 *
 * O preço de 1 mês é o `preco` base do pacote. Os outros = preco × meses, com
 * um desconto opcional por duração (definido pelo admin em
 * pacote['duration_discounts'][meses] = percentagem). O add-on de IA também é
 * por mês (ai_price × meses). O desconto incide sobre o subtotal (base + IA).
 * Os dias = `dias` base × meses.
 * ============================================================================ */

/** Meses disponíveis para subscrição. */
function rmbz_vip_duration_months() {
    return [ 1, 2, 3, 4, 12 ];
}

/** Rótulo pt-PT de uma duração em meses. */
function rmbz_vip_duration_label( $months ) {
    $months = (int) $months;
    if ( $months === 12 ) return '1 ano';
    return $months . ( $months === 1 ? ' mês' : ' meses' );
}

/**
 * [1.5.376] Rótulo de uma duração a partir dos DIAS reais. Quando os dias são
 * um múltiplo exato de 30, mostra a forma amigável em meses (ex.: "1 mês",
 * "2 meses", "1 ano"); caso contrário, mostra os dias ("15 dias", "45 dias").
 */
function rmbz_vip_duration_label_days( $days ) {
    $days = (int) $days;
    if ( $days > 0 && $days % 30 === 0 ) {
        $m = intdiv( $days, 30 );
        if ( $m === 12 ) return '1 ano';
        return $m . ( $m === 1 ? ' mês' : ' meses' );
    }
    return $days . ' ' . ( $days === 1 ? 'dia' : 'dias' );
}

/**
 * Desconto (%) configurado para um pacote numa dada duração. 1 mês = sem
 * desconto (é o preço base). Clamp a 0–90%.
 */
function rmbz_vip_package_discount( $pkg, $months ) {
    $months = (int) $months;
    if ( $months <= 1 ) return 0.0;
    $map = ( is_array( $pkg ) && isset( $pkg['duration_discounts'] ) && is_array( $pkg['duration_discounts'] ) )
        ? $pkg['duration_discounts'] : [];
    // Aceita chave int ou string.
    $raw = $map[ $months ] ?? ( $map[ (string) $months ] ?? 0 );
    return max( 0.0, min( 90.0, (float) $raw ) );
}

/**
 * Calcula o detalhe de preço de um pacote para uma duração + flag de IA.
 *
 * @return array|null Null se a duração não for válida.
 */
function rmbz_vip_compute_price( $pkg, $months, $include_ai = false ) {
    $months = (int) $months;
    if ( ! in_array( $months, rmbz_vip_duration_months(), true ) ) return null;
    if ( ! is_array( $pkg ) ) return null;

    $base       = max( 0.0, (float) ( $pkg['preco'] ?? 0 ) );
    $dias_base  = max( 1, (int) ( $pkg['dias'] ?? 30 ) );
    $ai_offered = ! empty( $pkg['ai_offered'] );
    $ai_price   = isset( $pkg['ai_price'] ) ? max( 0.0, (float) $pkg['ai_price'] ) : 0.0;
    $include_ai = $include_ai && $ai_offered;
    $disc       = rmbz_vip_package_discount( $pkg, $months );

    // [1.5.376] RESPEITAR O PACOTE — o preço/período configurados são a unidade.
    // A opção 1× é o pacote tal-e-qual (ex.: 800 MT / 15 dias); as durações
    // maiores MULTIPLICAM esse período: 2× = 1600/30d, 3× = 2400/45d, etc.
    // (Os rótulos mostram os dias reais — ver rmbz_vip_duration_label_days.)
    $base_total = $base * $months;
    $ai_total   = $include_ai ? $ai_price * $months : 0.0;
    $subtotal   = $base_total + $ai_total;
    $disc_amt   = round( $subtotal * $disc / 100.0, 2 );
    $total      = round( $subtotal - $disc_amt, 2 );

    return [
        'months'          => $months,
        'days'            => $dias_base * $months,
        'base_total'      => round( $base_total, 2 ),
        'ai_total'        => round( $ai_total, 2 ),
        'subtotal'        => round( $subtotal, 2 ),
        'discount_pct'    => $disc,
        'discount_amount' => $disc_amt,
        'total'           => $total,
        'include_ai'      => $include_ai ? 1 : 0,
    ];
}

/**
 * Lista de opções de duração para um pacote (para UI da app/site e API).
 * Cada opção traz o total SEM IA e o total COM IA (já com desconto aplicado).
 *
 * @return array<int,array>
 */
function rmbz_vip_package_duration_options( $pkg ) {
    $out = [];
    foreach ( rmbz_vip_duration_months() as $m ) {
        $no_ai = rmbz_vip_compute_price( $pkg, $m, false );
        if ( $no_ai === null ) continue;
        $with_ai = rmbz_vip_compute_price( $pkg, $m, true );
        $out[] = [
            'months'        => $m,
            // [1.5.376] Rótulo pelos dias reais do pacote (× multiplicador).
            'label'         => rmbz_vip_duration_label_days( $no_ai['days'] ),
            'days'          => $no_ai['days'],
            'discount_pct'  => $no_ai['discount_pct'],
            'price'         => $no_ai['total'],                                  // sem IA
            'price_with_ai' => $with_ai ? $with_ai['total'] : $no_ai['total'],   // com IA
            'ai_extra'      => $with_ai ? round( $with_ai['total'] - $no_ai['total'], 2 ) : 0.0,
        ];
    }
    return $out;
}