<?php
/**
 * Integra o módulo Artists na identidade canónica do 1MZ For Artists.
 *
 * A conta pública continua a existir apenas em rmbz_wallets (telemóvel + PIN).
 * O utilizador WordPress criado por esta ponte é uma identidade técnica para
 * post_author, user_meta, nonces e ownership dos conteúdos do módulo Artists.
 */

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

if ( ! defined( 'RMBZ_ARTISTS_EMBEDDED' ) ) {
    define( 'RMBZ_ARTISTS_EMBEDDED', true );
}

if ( ! defined( 'RMBZ_ARTISTS_SCHEMA_VERSION' ) ) {
    define( 'RMBZ_ARTISTS_SCHEMA_VERSION', '1.1.0' );
}

/** Obtém a wallet que representa a conta oficial do artista. */
function rmbz_artists_get_wallet( $telemovel ) {
    global $wpdb;

    $telemovel = trim( (string) $telemovel );
    if ( $telemovel === '' ) {
        return null;
    }

    return $wpdb->get_row( $wpdb->prepare(
        "SELECT id, user_telemovel, user_email, user_nome, is_banned, extra_data
         FROM {$wpdb->prefix}rmbz_wallets
         WHERE user_telemovel = %s
         LIMIT 1",
        $telemovel
    ) );
}

/** Formatos históricos aceites ao procurar o telefone no user_meta antigo. */
function rmbz_artists_phone_variants( $telemovel ) {
    $phone = trim( (string) $telemovel );
    $digits = preg_replace( '/\D+/', '', $phone );
    $local = strlen( $digits ) >= 9 ? substr( $digits, -9 ) : $digits;

    return array_values( array_unique( array_filter( [
        $phone,
        $digits,
        $local,
        $local !== '' ? '258' . $local : '',
        $local !== '' ? '+258' . $local : '',
    ] ) ) );
}

/** Normaliza um contacto moçambicano para o formato usado pelas wallets. */
function rmbz_artists_normalize_phone( $telemovel ) {
    $digits = preg_replace( '/\D+/', '', (string) $telemovel );
    if ( strlen( $digits ) >= 9 ) {
        return '+258' . substr( $digits, -9 );
    }
    return $digits !== '' ? '+' . $digits : '';
}

/** Procura uma wallet por telefone e, em alternativa, pelo email real. */
function rmbz_artists_find_wallet_by_identity( $telemovel = '', $email = '' ) {
    foreach ( rmbz_artists_phone_variants( $telemovel ) as $variant ) {
        $wallet = rmbz_artists_get_wallet( $variant );
        if ( $wallet ) {
            return $wallet;
        }
    }

    $email = sanitize_email( (string) $email );
    if ( $email === '' ) {
        return null;
    }

    global $wpdb;
    return $wpdb->get_row( $wpdb->prepare(
        "SELECT id, user_telemovel, user_email, user_nome, is_banned, extra_data
         FROM {$wpdb->prefix}rmbz_wallets
         WHERE LOWER(user_email) = LOWER(%s)
         LIMIT 1",
        $email
    ) );
}

/** Obtém o Art Track já ligado a uma identidade técnica. */
function rmbz_artists_get_art_track_for_user( $user_id ) {
    $user_id = absint( $user_id );
    if ( ! $user_id ) {
        return 0;
    }

    if ( function_exists( 'rmbz_art_track_find_by_user' ) && rmbz_art_tracks_native_ready() ) {
        $native_id = rmbz_art_track_find_by_user( $user_id );
        if ( $native_id ) return $native_id;
    }

    $track_id = absint( get_user_meta( $user_id, '_imz_art_track_id', true ) );
    if ( $track_id && get_post_type( $track_id ) === 'imz_artista' ) {
        return $track_id;
    }

    $tracks = get_posts( [
        'post_type'      => 'imz_artista',
        'post_status'    => [ 'publish', 'draft', 'pending', 'private', 'future' ],
        'posts_per_page' => 2,
        'fields'         => 'ids',
        'meta_key'       => '_imz_artista_linked_user_id',
        'meta_value'     => $user_id,
        'no_found_rows'  => true,
    ] );
    if ( count( $tracks ) !== 1 ) {
        return 0;
    }

    update_user_meta( $user_id, '_imz_art_track_id', (int) $tracks[0] );
    return (int) $tracks[0];
}

/**
 * Liga a conta 1MZ ao Art Track preparado pelo admin.
 * O telefone tem prioridade. O email só é usado quando não há correspondência
 * telefónica, e vínculos ambíguos nunca são aplicados automaticamente.
 */
function rmbz_artists_link_art_track_for_account( $telemovel, $user_id, $wallet = null ) {
    $user_id = absint( $user_id );
    $wallet = $wallet ?: rmbz_artists_get_wallet( $telemovel );
    if ( ! $user_id || ! $wallet ) {
        return 0;
    }

    $already_linked = rmbz_artists_get_art_track_for_user( $user_id );
    if ( $already_linked ) {
        return $already_linked;
    }

    if ( function_exists( 'rmbz_art_track_find_by_phone' ) && rmbz_art_tracks_native_ready() ) {
        $wallet_email = sanitize_email( (string) $wallet->user_email );
        $placeholder = substr( strtolower( $wallet_email ), -10 ) === '@1mz.local';
        $track_id = rmbz_art_track_find_by_phone( (string) $wallet->user_telemovel );
        if ( ! $track_id && $wallet_email !== '' && ! $placeholder ) $track_id = rmbz_art_track_find_by_email( $wallet_email );
        if ( ! $track_id ) return 0;
        $native = rmbz_art_track_get( $track_id );
        if ( ! $native || ( (int) $native->linked_user_id && (int) $native->linked_user_id !== $user_id ) ) return 0;
        if ( ! rmbz_art_track_link_account( $track_id, $wallet, $user_id ) ) return 0;
        update_user_meta( $user_id, '_imz_art_track_id', $track_id );
        $fresh_wallet = rmbz_artists_get_wallet( $wallet->user_telemovel );
        $extra = $fresh_wallet && ! empty( $fresh_wallet->extra_data ) ? json_decode( (string) $fresh_wallet->extra_data, true ) : [];
        $extra = is_array( $extra ) ? $extra : [];
        $extra['artists_art_track_id'] = $track_id;
        $extra['artists_art_track_linked_at'] = current_time( 'mysql' );
        global $wpdb;
        $wpdb->update( $wpdb->prefix . 'rmbz_wallets', [ 'extra_data' => wp_json_encode( $extra, JSON_UNESCAPED_UNICODE ) ], [ 'id' => (int) $wallet->id ], [ '%s' ], [ '%d' ] );
        return $track_id;
    }

    $common = [
        'post_type'      => 'imz_artista',
        'post_status'    => [ 'publish', 'draft', 'pending', 'private', 'future' ],
        'posts_per_page' => 3,
        'fields'         => 'ids',
        'no_found_rows'  => true,
    ];

    $phone_matches = get_posts( array_merge( $common, [
        'meta_key'     => '_imz_artista_account_phone',
        'meta_value'   => rmbz_artists_phone_variants( $wallet->user_telemovel ),
        'meta_compare' => 'IN',
    ] ) );

    $matches = $phone_matches;
    $wallet_email = sanitize_email( (string) $wallet->user_email );
    $is_placeholder_email = substr( strtolower( $wallet_email ), -10 ) === '@1mz.local';
    if ( empty( $matches ) && $wallet_email !== '' && ! $is_placeholder_email ) {
        $matches = get_posts( array_merge( $common, [
            'meta_key'     => '_imz_artista_account_email',
            'meta_value'   => $wallet_email,
            'meta_compare' => '=',
        ] ) );
    }

    $matches = array_values( array_unique( array_map( 'absint', $matches ) ) );
    if ( count( $matches ) !== 1 ) {
        return 0;
    }

    $track_id = (int) $matches[0];
    $linked_user = absint( get_post_meta( $track_id, '_imz_artista_linked_user_id', true ) );
    if ( $linked_user && $linked_user !== $user_id ) {
        return 0;
    }

    update_post_meta( $track_id, '_imz_artista_linked_user_id', $user_id );
    update_post_meta( $track_id, '_imz_artista_linked_wallet_id', (int) $wallet->id );
    update_post_meta( $track_id, '_imz_artista_account_phone', rmbz_artists_normalize_phone( $wallet->user_telemovel ) );
    if ( $wallet_email !== '' && ! $is_placeholder_email ) {
        update_post_meta( $track_id, '_imz_artista_account_email', $wallet_email );
    }
    update_post_meta( $track_id, '_imz_artista_linked_at', current_time( 'mysql' ) );
    update_user_meta( $user_id, '_imz_art_track_id', $track_id );

    $fresh_wallet = rmbz_artists_get_wallet( $wallet->user_telemovel );
    $extra = $fresh_wallet && ! empty( $fresh_wallet->extra_data ) ? json_decode( (string) $fresh_wallet->extra_data, true ) : [];
    $extra = is_array( $extra ) ? $extra : [];
    $extra['artists_art_track_id'] = $track_id;
    $extra['artists_art_track_linked_at'] = current_time( 'mysql' );
    global $wpdb;
    $wpdb->update(
        $wpdb->prefix . 'rmbz_wallets',
        [ 'extra_data' => wp_json_encode( $extra, JSON_UNESCAPED_UNICODE ) ],
        [ 'id' => (int) $wallet->id ],
        [ '%s' ],
        [ '%d' ]
    );

    delete_transient( 'imz_auto_verified_' . $track_id );
    return $track_id;
}

/** Resolve o telemóvel 1MZ associado a um utilizador WordPress técnico. */
function imz_rmbz_phone_for_user( $user_id ) {
    $user_id = absint( $user_id );
    if ( ! $user_id ) {
        return '';
    }

    $phone = trim( (string) get_user_meta( $user_id, '_rmbz_artist_telemovel', true ) );
    if ( $phone === '' ) {
        $phone = trim( (string) get_user_meta( $user_id, 'telemovel', true ) );
    }

    if ( $phone === '' && function_exists( 'rmbz_get_current_user_telemovel' ) && get_current_user_id() === $user_id ) {
        $phone = trim( (string) rmbz_get_current_user_telemovel() );
    }

    return rmbz_artists_get_wallet( $phone ) ? $phone : '';
}

/**
 * Liga uma wallet a um utilizador WordPress existente ou cria o vínculo técnico.
 * A procura preserva primeiro vínculos explícitos, depois telemóvel e por fim
 * email, permitindo migrar automaticamente artistas do plugin antigo.
 */
function rmbz_artists_ensure_wp_user( $telemovel ) {
    static $resolved = [];

    $wallet = rmbz_artists_get_wallet( $telemovel );
    if ( ! $wallet ) {
        return 0;
    }

    $phone = (string) $wallet->user_telemovel;
    if ( isset( $resolved[ $phone ] ) ) {
        return (int) $resolved[ $phone ];
    }

    $extra = ! empty( $wallet->extra_data ) ? json_decode( (string) $wallet->extra_data, true ) : [];
    if ( ! is_array( $extra ) ) {
        $extra = [];
    }

    $user_id = absint( $extra['artists_wp_user_id'] ?? 0 );
    if ( $user_id && ! get_user_by( 'id', $user_id ) ) {
        $user_id = 0;
    }

    if ( ! $user_id ) {
        $matches = get_users( [
            'meta_key'   => '_rmbz_artist_telemovel',
            'meta_value' => $phone,
            'number'     => 1,
            'fields'     => 'ids',
        ] );
        $user_id = ! empty( $matches ) ? absint( $matches[0] ) : 0;
    }

    if ( ! $user_id ) {
        $matches = get_users( [
            'meta_key'   => 'telemovel',
            'meta_value' => rmbz_artists_phone_variants( $phone ),
            'meta_compare' => 'IN',
            'number'     => 1,
            'fields'     => 'ids',
        ] );
        $user_id = ! empty( $matches ) ? absint( $matches[0] ) : 0;
    }

    $wallet_email = sanitize_email( (string) $wallet->user_email );
    if ( ! $user_id && $wallet_email !== '' ) {
        $email_user = get_user_by( 'email', $wallet_email );
        if ( $email_user && ! user_can( $email_user, 'manage_options' ) ) {
            $bound_phone = trim( (string) get_user_meta( $email_user->ID, '_rmbz_artist_telemovel', true ) );
            if ( $bound_phone === '' || hash_equals( $bound_phone, $phone ) ) {
                $user_id = (int) $email_user->ID;
            }
        }
    }

    if ( ! $user_id ) {
        $digits = preg_replace( '/\D+/', '', $phone );
        $base_login = '1mz_artist_' . ( $digits !== '' ? $digits : (int) $wallet->id );
        $user_login = sanitize_user( $base_login, true );
        $suffix = 0;
        while ( username_exists( $user_login ) ) {
            $suffix++;
            $user_login = sanitize_user( $base_login . '_' . $suffix, true );
        }

        $insert_email = $wallet_email;
        if ( $insert_email !== '' && email_exists( $insert_email ) ) {
            $insert_email = '';
        }

        $created = wp_insert_user( [
            'user_login'   => $user_login,
            'user_pass'    => wp_generate_password( 40, true, true ),
            'user_email'   => $insert_email,
            'display_name' => sanitize_text_field( (string) $wallet->user_nome ) ?: $phone,
            'nickname'     => sanitize_text_field( (string) $wallet->user_nome ) ?: $phone,
            'role'         => get_role( 'imz_artist' ) ? 'imz_artist' : 'subscriber',
        ] );
        if ( is_wp_error( $created ) ) {
            error_log( '[1MZ Artists] Falha ao criar identidade técnica: ' . $created->get_error_message() );
            return 0;
        }
        $user_id = (int) $created;
    }

    $user = get_user_by( 'id', $user_id );
    if ( ! $user || user_can( $user, 'manage_options' ) ) {
        return 0;
    }

    update_user_meta( $user_id, '_rmbz_artist_telemovel', $phone );
    update_user_meta( $user_id, 'telemovel', $phone );
    update_user_meta( $user_id, '_rmbz_artist_wallet_id', (int) $wallet->id );
    update_user_meta( $user_id, '_rmbz_artist_managed_account', 1 );

    $display_name = sanitize_text_field( (string) $wallet->user_nome ) ?: $phone;
    $update = [ 'ID' => $user_id ];
    $needs_update = false;
    if ( $display_name !== '' && $user->display_name !== $display_name ) {
        $update['display_name'] = $display_name;
        $update['nickname'] = $display_name;
        $needs_update = true;
    }
    if ( $wallet_email !== '' && $user->user_email !== $wallet_email && ! email_exists( $wallet_email ) ) {
        $update['user_email'] = $wallet_email;
        $needs_update = true;
    }
    if ( $needs_update ) {
        wp_update_user( $update );
    }

    if ( (int) ( $extra['artists_wp_user_id'] ?? 0 ) !== $user_id ) {
        global $wpdb;
        $extra['artists_wp_user_id'] = $user_id;
        $extra['artists_linked_at'] = current_time( 'mysql' );
        $wpdb->update(
            $wpdb->prefix . 'rmbz_wallets',
            [ 'extra_data' => wp_json_encode( $extra, JSON_UNESCAPED_UNICODE ) ],
            [ 'id' => (int) $wallet->id ],
            [ '%s' ],
            [ '%d' ]
        );
    }

    rmbz_artists_link_art_track_for_account( $phone, $user_id, $wallet );

    $resolved[ $phone ] = $user_id;
    return $user_id;
}

/** True apenas quando existe uma sessão válida da conta 1MZ. */
function imz_rmbz_is_artist_logged_in() {
    if ( ! function_exists( 'rmbz_is_user_logged_in' ) || ! function_exists( 'rmbz_get_current_user_telemovel' ) ) {
        return false;
    }
    return rmbz_is_user_logged_in() && (string) rmbz_get_current_user_telemovel() !== '';
}

/** ID técnico do artista autenticado pela conta 1MZ. */
function imz_get_current_artist_user_id() {
    if ( ! imz_rmbz_is_artist_logged_in() ) {
        return 0;
    }
    return rmbz_artists_ensure_wp_user( rmbz_get_current_user_telemovel() );
}

/** URL oficial para login, perfil e planos da conta 1MZ. */
function imz_rmbz_account_url( $section = 'inicio' ) {
    $url = home_url( '/minha-conta/' );
    $section = sanitize_key( (string) $section );
    return $section !== '' && $section !== 'inicio' ? add_query_arg( 'sect', $section, $url ) : $url;
}

/** Converte o bloqueio da wallet no estado esperado pelo painel Artists. */
function imz_rmbz_artist_account_status( $user_id = 0 ) {
    $user_id = $user_id ? absint( $user_id ) : get_current_user_id();
    $phone = imz_rmbz_phone_for_user( $user_id );
    $wallet = $phone !== '' ? rmbz_artists_get_wallet( $phone ) : null;
    return $wallet && (int) $wallet->is_banned === 1 ? 'blocked' : 'active';
}

/** Data de expiração VIP da conta 1MZ associada. */
function imz_rmbz_subscription_expiry_for_user( $user_id ) {
    $phone = imz_rmbz_phone_for_user( $user_id );
    return $phone !== '' && function_exists( 'rmbz_get_subscription_expiry' )
        ? (string) rmbz_get_subscription_expiry( $phone )
        : '';
}

/** Aplica a identidade técnica sem criar cookie ou credencial WordPress. */
function rmbz_artists_boot_current_identity() {
    $current_id = get_current_user_id();
    if ( $current_id && user_can( $current_id, 'manage_options' ) ) {
        return;
    }
    $artist_id = imz_get_current_artist_user_id();
    if ( $artist_id ) {
        wp_set_current_user( $artist_id );
    }
}
add_action( 'init', 'rmbz_artists_boot_current_identity', 2 );
add_action( 'rmbz_user_logged_in', function( $telemovel ) {
    $artist_id = rmbz_artists_ensure_wp_user( $telemovel );
    if ( $artist_id ) {
        wp_set_current_user( $artist_id );
    }
}, 5 );
add_action( 'rmbz_user_registered', function( $telemovel ) {
    rmbz_artists_ensure_wp_user( $telemovel );
}, 5, 1 );

// Endpoints privados do painel deixam de aceitar um login WordPress antigo
// sem uma sessão 1MZ válida. Endpoints públicos (player, downloads, reportes
// e compras de visitantes) continuam disponíveis através de nopriv.
add_action( 'init', function() {
    if ( ! wp_doing_ajax() || current_user_can( 'manage_options' ) || imz_rmbz_is_artist_logged_in() ) {
        return;
    }
    $action = sanitize_key( wp_unslash( $_REQUEST['action'] ?? '' ) );
    $private_actions = [
        'imz_upload_claim_document',
        'imz_artist_contacted_buyer',
        'imz_artist_cancel_buyer',
        'imz_submit_takedown',
        'imz_save_music_settings',
        'imz_request_payout',
        'imz_save_payout_method',
        'imz_claim_music',
        'imz_get_dashboard_chart_data',
        'imz_save_theme_preference',
        'imz_ad_initiate_payment',
        'imz_ad_toggle_status',
    ];
    if ( in_array( $action, $private_actions, true ) ) {
        wp_set_current_user( 0 );
    }
}, 3 );

add_action( 'init', function() {
    add_role( 'imz_artist', 'Artista 1MZ', [ 'read' => true, 'upload_files' => true ] );
}, 0 );

add_filter( 'show_admin_bar', function( $show ) {
    return get_user_meta( get_current_user_id(), '_rmbz_artist_managed_account', true ) ? false : $show;
} );

// O módulo antigo passa a viver dentro deste plugin e deixa de ter conta própria.
// O carregamento em plugins_loaded permite detetar uma instalação antiga ainda
// ativa antes de declarar as mesmas funções e evita um erro fatal na atualização.
function rmbz_artists_load_embedded_module() {
    if ( defined( 'IMZ_VERSION' ) ) {
        if ( ! defined( 'RMBZ_ARTISTS_MODULE_LOADED_BY_CORE' ) ) {
            add_action( 'admin_notices', function() {
                if ( current_user_can( 'activate_plugins' ) ) {
                    echo '<div class="notice notice-warning"><p><strong>1MZ For Artists:</strong> foi detetada uma cópia antiga do plugin Artists ativa. Desativa essa cópia; as funções já estão incluídas no 1MZ For Artists.</p></div>';
                }
            } );
        }
        return;
    }

    $artists_module = defined( 'RMBZ_PLUGIN_PATH' ) ? RMBZ_PLUGIN_PATH . 'artists/impulsionamento-musicas.php' : '';
    if ( $artists_module && file_exists( $artists_module ) ) {
        define( 'RMBZ_ARTISTS_MODULE_LOADED_BY_CORE', true );
        require_once $artists_module;
    }
}

if ( did_action( 'plugins_loaded' ) ) {
    rmbz_artists_load_embedded_module();
} else {
    add_action( 'plugins_loaded', 'rmbz_artists_load_embedded_module', 5 );
}

/** Instala/atualiza todas as tabelas do módulo embutido. */
function rmbz_artists_install_schema() {
    $installers = [
        'rmbz_art_tracks_native_install',
        'imz_install_analytics_table',
        'imz_install_reports_table',
        'imz_install_purchases_table',
        'imz_install_plays_table',
        'imz_install_ads_table',
        'imz_install_follows_table',
        'imz_install_engagements_table',
        'imz_install_monthly_payouts_table',
        'imz_install_recommendations_table',
        'imz_create_proof_of_ownership_page',
    ];
    foreach ( $installers as $installer ) {
        if ( function_exists( $installer ) ) {
            $installer();
        }
    }

    $migrations = [
        'imz_migrate_reports_table',
        'imz_migrate_copyright_table',
        'imz_migrate_presave_table',
    ];
    foreach ( $migrations as $migration ) {
        if ( function_exists( $migration ) ) {
            $migration();
        }
    }

    // A expiração PRO antiga não participa na subscrição VIP canónica.
    wp_clear_scheduled_hook( 'imz_daily_expired_check_event' );
    update_option( 'rmbz_artists_schema_version', RMBZ_ARTISTS_SCHEMA_VERSION, false );
}

function rmbz_artists_maybe_install_schema() {
    if ( get_option( 'rmbz_artists_schema_version' ) !== RMBZ_ARTISTS_SCHEMA_VERSION ) {
        rmbz_artists_install_schema();
    }
}
add_action( 'admin_init', 'rmbz_artists_maybe_install_schema', 2 );
