<?php
// includes/cron-jobs.php

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

/**
 * Adiciona intervalos de tempo personalizados ao Cron do WordPress.
 */
add_filter( 'cron_schedules', function ($schedules) {
    if ( ! isset( $schedules['every_five_minutes'] ) ) {
        $schedules['every_five_minutes'] = [
            'interval' => 300, // 300 segundos = 5 minutos
            'display' => __( 'A cada 5 minutos' ),
        ];
    }
    if ( ! isset( $schedules['daily'] ) ) {
         $schedules['daily'] = [
            'interval' => 86400, // 24 horas
            'display' => __( 'Uma vez por dia' ),
        ];
    }
    return $schedules;
});

/**
 * Agenda os eventos na ativação do plugin.
 */
register_activation_hook( RMBZ_PLUGIN_PATH . '1mz-for-artists.php', function () {
    // Cron job diário (Usado para desbloquear fundos e limpar a base de dados)
    if ( ! wp_next_scheduled( 'rmbz_unlock_funds_hook' ) ) {
        wp_schedule_event( time(), 'daily', 'rmbz_unlock_funds_hook' );
    }
});

/**
 * Limpa os eventos agendados na desativação.
 */
register_deactivation_hook( RMBZ_PLUGIN_PATH . '1mz-for-artists.php', function () {
    wp_clear_scheduled_hook( 'rmbz_unlock_funds_hook' );
});


/**
 * ==========================================================================
 * TAREFA DIÁRIA 1: Processar fundos bloqueados na carteira.
 * ==========================================================================
 */
add_action( 'rmbz_unlock_funds_hook', 'rmbz_process_unlocked_funds' );

function rmbz_process_unlocked_funds() {
    global $wpdb;
    $transactions_table = $wpdb->prefix . 'rmbz_wallet_transactions';
    $now_gmt = current_time('mysql', 1);

    // Atualiza transações que ainda estão bloqueadas e cuja data de desbloqueio já passou
    $wpdb->query( $wpdb->prepare(
        "UPDATE {$transactions_table} 
         SET is_unlocked = 1 
         WHERE is_unlocked = 0 
         AND unlock_date IS NOT NULL 
         AND unlock_date <= %s",
        $now_gmt
    ) );
}

/**
 * ==========================================================================
 * TAREFA DIÁRIA 2: Limpeza automática de Notificações / E-mails antigos.
 * ==========================================================================
 */
add_action( 'rmbz_unlock_funds_hook', 'rmbz_process_email_cleanup' );

function rmbz_process_email_cleanup() {
    global $wpdb;
    $table_emails = $wpdb->prefix . 'rmbz_email_logs';
    $now = current_time('mysql');

    // 1. Apagar e-mails LIDOS (is_read = 1) ou LIMPOS (is_cleared = 1) há mais de 7 dias
    $wpdb->query( $wpdb->prepare(
        "DELETE FROM {$table_emails} 
         WHERE (is_read = 1 OR is_cleared = 1) 
         AND sent_date <= DATE_SUB(%s, INTERVAL 7 DAY)",
        $now
    ) );

    // 2. Apagar e-mails NÃO LIDOS (is_read = 0) há mais de 30 dias (1 Mês)
    $wpdb->query( $wpdb->prepare(
        "DELETE FROM {$table_emails} 
         WHERE is_read = 0 
         AND sent_date <= DATE_SUB(%s, INTERVAL 30 DAY)",
        $now
    ) );
}

/**
 * ==========================================================================
 * TAREFA DIÁRIA 3: Excluir Depósitos Pendentes após 24 horas.
 * ==========================================================================
 */
add_action( 'rmbz_unlock_funds_hook', 'rmbz_cleanup_expired_deposits' );

function rmbz_cleanup_expired_deposits() {
    global $wpdb;
    $table_deposits = $wpdb->prefix . 'rmbz_deposit_requests';
    $now = current_time('mysql');

    // Apagar depósitos pendentes que foram criados há mais de 24 horas
    $wpdb->query( $wpdb->prepare(
        "DELETE FROM {$table_deposits} 
         WHERE status = 'pendente' 
         AND request_date <= DATE_SUB(%s, INTERVAL 24 HOUR)",
        $now
    ) );
}

/**
 * ==========================================================================
 * TAREFA DIÁRIA 4: Excluir Candidaturas de Videoclipe Rejeitadas (Auto-Limpeza)
 * ==========================================================================
 */
add_action( 'rmbz_unlock_funds_hook', 'rmbz_cleanup_rejected_projects' );

function rmbz_cleanup_rejected_projects() {
    global $wpdb;
    $table_projects = $wpdb->prefix . 'rmbz_artist_projects';
    
    // Apaga diretamente os projetos que tenham o estado de produção como "rejected"
    // Como esta tarefa corre apenas 1 vez por dia, o artista terá em média
    // até 24 horas para aceder ao painel e ver o motivo antes de o projeto desaparecer.
    $wpdb->query(
        "DELETE FROM {$table_projects} 
         WHERE production_status = 'rejected'"
    );
}

/**
 * ==========================================================================
 * [1.5.138] TAREFA DIÁRIA 5: Avisar utilizadores de subscrições a expirar
 * ==========================================================================
 *
 * Envia notificação (email + sino) 3 dias antes da subscrição expirar, para
 * o utilizador ter tempo de renovar antes de perder o acesso.
 *
 * Heurística para evitar spam:
 *   - Só uma vez por subscrição: marca extra_data['vip_expiring_notified']
 *     na rmbz_wallets quando notifica.
 *   - Reset desta flag quando uma nova subscrição é criada/estendida
 *     (controlado pelos handlers de compra de plano).
 */
add_action( 'rmbz_unlock_funds_hook', 'rmbz_cron_vip_expiring_notice' );

function rmbz_cron_vip_expiring_notice() {
    if ( ! function_exists('rmbz_notify') ) return;
    global $wpdb;

    $table_subs = $wpdb->prefix . 'rmbz_subscriptions';
    if ( $wpdb->get_var("SHOW TABLES LIKE '$table_subs'") !== $table_subs ) return;

    // Encontrar subscrições activas que expiram entre 2 e 3 dias.
    // Janela de 1 dia evita perder casos por causa do timing do cron.
    $rows = $wpdb->get_results(
        "SELECT s.user_telemovel, s.end_date, w.extra_data
         FROM $table_subs s
         JOIN {$wpdb->prefix}rmbz_wallets w ON w.user_telemovel = s.user_telemovel
         WHERE s.status = 'active'
           AND s.end_date > NOW()
           AND s.end_date <= DATE_ADD(NOW(), INTERVAL 3 DAY)
           AND s.end_date > DATE_ADD(NOW(), INTERVAL 2 DAY)"
    );

    if ( empty($rows) ) return;

    foreach ( $rows as $r ) {
        $extra = ! empty($r->extra_data) ? json_decode($r->extra_data, true) : [];
        if ( ! is_array($extra) ) $extra = [];

        // Já avisado para esta subscrição? (extra_data['vip_expiring_notified'] = end_date)
        if ( isset($extra['vip_expiring_notified']) && $extra['vip_expiring_notified'] === $r->end_date ) {
            continue;
        }

        $days_left = max(1, (int) ceil( (strtotime($r->end_date) - time()) / 86400 ));

        // [1.6.370] Se o artista tem um videoclipe EM PRODUÇÃO, avisa também a
        // regra da multa por atraso (a equipa não trabalha sem subscrição).
        $video_project = function_exists('rmbz_artist_active_video_project')
            ? rmbz_artist_active_video_project( $r->user_telemovel ) : null;

        // [1.6.392] Se o projeto tem notificações desativadas, não menciona o
        // projeto/multa — envia só o aviso genérico de subscrição.
        $video_project_muted = $video_project && function_exists('rmbz_project_notifications_muted')
            && rmbz_project_notifications_muted( $video_project->id );

        if ( $video_project && ! $video_project_muted && function_exists('rmbz_project_fine_rule_text') ) {
            $sent = rmbz_notify( $r->user_telemovel, 'vip_expiring_project_fine', [
                'dias'           => $days_left,
                'data_expiracao' => date_i18n( 'd/m/Y', strtotime($r->end_date) ),
                'musica'         => $video_project->project_title ?: 'o teu videoclipe',
                'regra_multa'    => rmbz_project_fine_rule_text(),
            ]);
        } else {
            $sent = rmbz_notify( $r->user_telemovel, 'vip_expiring', [
                'dias'           => $days_left,
                'data_expiracao' => date_i18n( 'd/m/Y', strtotime($r->end_date) ),
            ]);
        }

        if ( $sent ) {
            $extra['vip_expiring_notified'] = $r->end_date;
            $wpdb->update(
                $wpdb->prefix . 'rmbz_wallets',
                [ 'extra_data' => wp_json_encode($extra) ],
                [ 'user_telemovel' => $r->user_telemovel ],
                ['%s'], ['%s']
            );
        }
    }
}

/**
 * ==========================================================================
 * [1.6.391] TAREFA DIÁRIA 6: Lembrete enquanto a multa do videoclipe acumula
 * ==========================================================================
 *
 * Enquanto a subscrição COM o serviço Ganhar Vídeo está expirada, o projeto
 * está em produção e a multa cresce, lembra o artista em TODOS os canais
 * (email + sino + app/push) — uma vez por dia (cadência configurável via filtro
 * rmbz_fine_reminder_interval_hours, default 24h) — com a dívida atual e o pedido
 * para renovar o VIP (para a multa dar pausa).
 */
add_action( 'rmbz_unlock_funds_hook', 'rmbz_cron_fine_accruing_reminder' );

function rmbz_cron_fine_accruing_reminder() {
    if ( ! function_exists( 'rmbz_project_overdue_info' ) ) return;
    global $wpdb;

    $states = function_exists( 'rmbz_project_inprogress_states' )
        ? rmbz_project_inprogress_states() : [ 'pre-production', 'kyc_review', 'filming', 'editing' ];
    if ( empty( $states ) ) return;
    $place = implode( ',', array_fill( 0, count( $states ), '%s' ) );

    $rows = $wpdb->get_results( $wpdb->prepare(
        "SELECT id, artist_telemovel, project_title
           FROM {$wpdb->prefix}rmbz_artist_projects
          WHERE production_status IN ($place)
          ORDER BY id DESC",
        $states
    ) );
    if ( empty( $rows ) ) return;

    $interval_s = max( 1, (int) apply_filters( 'rmbz_fine_reminder_interval_hours', 24 ) ) * HOUR_IN_SECONDS;
    $now        = time();
    $seen_tel   = [];

    foreach ( $rows as $r ) {
        $tel = (string) $r->artist_telemovel;
        if ( $tel === '' || isset( $seen_tel[ $tel ] ) ) continue;
        $seen_tel[ $tel ] = 1;

        $ov = rmbz_project_overdue_info( $tel );
        // Só quando está mesmo a ACUMULAR (expirado, não congelado) e há valor.
        if ( empty( $ov['overdue'] ) || ! empty( $ov['frozen'] )
            || empty( $ov['enabled'] ) || (float) ( $ov['amount'] ?? 0 ) <= 0 ) {
            continue;
        }

        $project_id = (int) ( $ov['project_id'] ?? $r->id );
        // [1.6.392] Notificações desativadas neste projeto pelo admin → não lembra.
        if ( function_exists( 'rmbz_project_notifications_muted' )
            && rmbz_project_notifications_muted( $project_id ) ) {
            continue;
        }
        // Guard de cadência por projeto (extra_data['fine_reminder_last']).
        $row_extra = $wpdb->get_var( $wpdb->prepare(
            "SELECT extra_data FROM {$wpdb->prefix}rmbz_artist_projects WHERE id = %d", $project_id ) );
        $extra = $row_extra ? json_decode( $row_extra, true ) : [];
        if ( ! is_array( $extra ) ) $extra = [];
        $last = isset( $extra['fine_reminder_last'] ) ? strtotime( (string) $extra['fine_reminder_last'] ) : 0;
        if ( $last && ( $now - $last ) < $interval_s ) continue; // ainda não é altura

        $unit_each = ( ( $ov['unit'] ?? 'day' ) === 'hour' ) ? 'hora' : 'dia';
        $divida    = number_format( (float) $ov['amount'], 2, ',', '.' ) . ' MT';
        $taxa      = number_format( (float) $ov['rate'], 2, ',', '.' ) . ' MT/' . $unit_each;
        $musica    = $r->project_title ?: 'o teu videoclipe';

        // 1) Email + sino (rmbz_notify ignora emails placeholder @1mz.local).
        if ( function_exists( 'rmbz_notify' ) ) {
            rmbz_notify( $tel, 'fine_reminder', [
                'musica' => $musica,
                'divida' => $divida,
                'taxa'   => $taxa,
            ] );
        }

        // 2) In-app + push (FCM) na app.
        if ( function_exists( 'rmbz_notify_user' ) ) {
            rmbz_notify_user(
                $tel,
                '💸 Multa a acumular: ' . $divida,
                'A subscrição com Ganhar Vídeo expirou e "' . $musica . '" está em produção. '
                    . 'A multa já vai em ' . $divida . ' e continua a crescer. Renova o VIP para a parar.',
                'danger',
                [
                    'type'         => 'fine_reminder',
                    'action_url'   => 'onemz://projects/' . $project_id,
                    'action_label' => 'Abrir projeto',
                    'dedup_key'    => 'fine_reminder_' . $project_id . '_' . date( 'Y-m-d', $now ),
                    'created_by'   => 'system',
                ]
            );
        }

        // Registar o envio (cadência).
        $extra['fine_reminder_last'] = current_time( 'mysql' );
        $wpdb->update(
            $wpdb->prefix . 'rmbz_artist_projects',
            [ 'extra_data' => wp_json_encode( $extra ) ],
            [ 'id' => $project_id ],
            [ '%s' ], [ '%d' ]
        );
    }
}