<?php
/**
 * 1MZ For Artists — Collaborations Endpoint
 *
 * Devolve as músicas onde o user está como collaborator/split payee.
 * Faz join entre `rmbz_track_splits` (configuração) e
 * `rmbz_splits_holdings` (dinheiro acumulado).
 *
 * ENDPOINTS:
 *   GET /me/collaborations                — lista
 *   GET /me/collaborations/summary        — KPIs (total a receber, nº músicas)
 *
 * @package 1MZ_For_Artists
 * @since 1.6.56
 */

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

if ( ! defined( 'RMBZ_API_COLLAB_VERSION' ) ) {
    define( 'RMBZ_API_COLLAB_VERSION', '1.6.56' );
}

add_action( 'rest_api_init', 'rmbz_api_register_collaborations_routes' );

function rmbz_api_register_collaborations_routes() {
    register_rest_route( RMBZ_API_NAMESPACE, '/me/collaborations', [
        'methods'             => 'GET',
        'callback'            => 'rmbz_api_handle_me_collaborations',
        'permission_callback' => 'rmbz_api_require_auth',
        'args' => [
            'filter' => [ 'type' => 'string', 'default' => 'all' ],
        ],
    ] );

    register_rest_route( RMBZ_API_NAMESPACE, '/me/collaborations/summary', [
        'methods'             => 'GET',
        'callback'            => 'rmbz_api_handle_me_collaborations_summary',
        'permission_callback' => 'rmbz_api_require_auth',
    ] );
}

/**
 * GET /me/collaborations?filter=all|live|pending
 *
 * Item devolvido:
 *  {
 *    track_id, release_id,
 *    track_title, release_title, cover_url,
 *    artist_main, artist_main_telemovel,
 *    role, percentage, split_status,        // pending | accepted | declined
 *    release_status,                          // live | pendente | rejected | ...
 *    pending_amount_usd,   // holdings ainda não claimed para este track
 *    claimed_amount_usd,   // já levantado
 *    created_at,           // quando o split foi criado
 *  }
 */
function rmbz_api_handle_me_collaborations( WP_REST_Request $request ) {
    $tel    = (string) $request->get_param( 'rmbz_telemovel' );
    $filter = (string) $request->get_param( 'filter' );
    if ( ! in_array( $filter, [ 'all', 'live', 'pending' ], true ) ) {
        $filter = 'all';
    }

    global $wpdb;

    $t_splits   = $wpdb->prefix . 'rmbz_track_splits';
    $t_tracks   = $wpdb->prefix . 'rmbz_distro_tracks';
    $t_releases = $wpdb->prefix . 'rmbz_distro_releases';
    $t_wallets  = $wpdb->prefix . 'rmbz_wallets';
    $t_hold     = $wpdb->prefix . 'rmbz_splits_holdings';

    // [1.6.56] Gerar variantes do telemovel para apanhar qualquer
    // formato que possa estar guardado em rmbz_track_splits
    // (o user pode ter sido convidado escrevendo "861640807",
    // "+258861640807", "258861640807", etc).
    $tel_variants = rmbz_api_collab_telemovel_variants( $tel );
    $placeholders_tel = implode( ',', array_fill( 0, count( $tel_variants ), '%s' ) );

    // Listagem dos splits do user que tenham linha em rmbz_track_splits
    // (i.e., foi formalmente convidado). Não dependemos só dos holdings
    // porque pode haver convite sem haver dinheiro ainda.
    $params = array_merge( $tel_variants, [ $tel ] );
    $rows = $wpdb->get_results( $wpdb->prepare(
        "SELECT
            s.id           AS split_id,
            s.track_id,
            s.role,
            s.percentage,
            s.invite_status AS split_status,
            s.created_at   AS split_created_at,
            t.title        AS track_title,
            t.release_id,
            r.title        AS release_title,
            r.cover_image,
            r.status       AS release_status,
            r.artist_telemovel AS artist_main_telemovel,
            w.user_nome    AS artist_main_nome
         FROM $t_splits s
         INNER JOIN $t_tracks   t ON t.id = s.track_id
         INNER JOIN $t_releases r ON r.id = t.release_id
         LEFT  JOIN $t_wallets  w ON w.user_telemovel = r.artist_telemovel
         WHERE s.collaborator_telemovel IN ($placeholders_tel)
           AND r.artist_telemovel <> %s  /* NÃO o próprio user */
         ORDER BY s.created_at DESC",
        $params
    ) );

    if ( ! $rows ) {
        return rmbz_api_ok( [ 'items' => [] ] );
    }

    // Aggregar holdings em 2 passes — pending (claimed_at IS NULL) e
    // claimed. Indexar por track_id para colar a cada split.
    $track_ids = array_unique( array_map( fn( $r ) => (int) $r->track_id, $rows ) );
    if ( ! empty( $track_ids ) ) {
        $placeholders_track = implode( ',', array_fill( 0, count( $track_ids ), '%d' ) );
        $params_hold = array_merge( $tel_variants, $track_ids );

        $pending = $wpdb->get_results( $wpdb->prepare(
            "SELECT track_id, SUM(amount_usd) AS s
             FROM $t_hold
             WHERE collaborator_telemovel IN ($placeholders_tel)
               AND claimed_at IS NULL
               AND track_id IN ($placeholders_track)
             GROUP BY track_id",
            $params_hold
        ) );
        $claimed = $wpdb->get_results( $wpdb->prepare(
            "SELECT track_id, SUM(amount_usd) AS s
             FROM $t_hold
             WHERE collaborator_telemovel IN ($placeholders_tel)
               AND claimed_at IS NOT NULL
               AND track_id IN ($placeholders_track)
             GROUP BY track_id",
            $params_hold
        ) );
    } else {
        $pending = [];
        $claimed = [];
    }

    $pending_by_track = [];
    foreach ( $pending as $p ) $pending_by_track[ (int) $p->track_id ] = (float) $p->s;
    $claimed_by_track = [];
    foreach ( $claimed as $c ) $claimed_by_track[ (int) $c->track_id ] = (float) $c->s;

    $items = [];
    foreach ( $rows as $r ) {
        $track_id = (int) $r->track_id;

        // Aplicar filtro
        if ( $filter === 'live' && $r->release_status !== 'live' && $r->release_status !== 'distribuido' ) {
            continue;
        }
        if ( $filter === 'pending' && in_array( $r->release_status, ['live','distribuido'], true ) ) {
            continue;
        }

        $items[] = [
            'split_id'            => (int) $r->split_id,
            'track_id'            => $track_id,
            'release_id'          => (int) $r->release_id,
            'track_title'         => (string) $r->track_title,
            'release_title'       => (string) $r->release_title,
            'cover_url'           => $r->cover_image
                ? rmbz_api_collab_resolve_cover( $r->cover_image )
                : null,
            'artist_main'         => (string) ( $r->artist_main_nome ?: $r->artist_main_telemovel ),
            'role'                => (string) $r->role,
            'percentage'          => (float) $r->percentage,
            'split_status'        => (string) $r->split_status,
            'release_status'      => (string) $r->release_status,
            'pending_amount_usd'  => round( $pending_by_track[ $track_id ] ?? 0.0, 4 ),
            'claimed_amount_usd'  => round( $claimed_by_track[ $track_id ] ?? 0.0, 4 ),
            'created_at'          => mysql_to_rfc3339( $r->split_created_at ),
        ];
    }

    return rmbz_api_ok( [ 'items' => $items ] );
}

/**
 * GET /me/collaborations/summary
 *
 * Devolve:
 *  {
 *    total_pending_usd,
 *    total_claimed_usd,
 *    songs_count_active,    // músicas live com split aceite
 *    songs_count_pending,   // músicas onde foi convidado mas ainda não aceitou
 *  }
 */
function rmbz_api_handle_me_collaborations_summary( WP_REST_Request $request ) {
    $tel = (string) $request->get_param( 'rmbz_telemovel' );
    global $wpdb;

    $t_splits   = $wpdb->prefix . 'rmbz_track_splits';
    $t_tracks   = $wpdb->prefix . 'rmbz_distro_tracks';
    $t_releases = $wpdb->prefix . 'rmbz_distro_releases';
    $t_hold     = $wpdb->prefix . 'rmbz_splits_holdings';

    $tel_variants = rmbz_api_collab_telemovel_variants( $tel );
    $placeholders_tel = implode( ',', array_fill( 0, count( $tel_variants ), '%s' ) );

    $total_pending = (float) $wpdb->get_var( $wpdb->prepare(
        "SELECT COALESCE(SUM(amount_usd),0)
         FROM $t_hold
         WHERE collaborator_telemovel IN ($placeholders_tel)
           AND claimed_at IS NULL",
        $tel_variants
    ) );
    $total_claimed = (float) $wpdb->get_var( $wpdb->prepare(
        "SELECT COALESCE(SUM(amount_usd),0)
         FROM $t_hold
         WHERE collaborator_telemovel IN ($placeholders_tel)
           AND claimed_at IS NOT NULL",
        $tel_variants
    ) );

    $params_with_owner = array_merge( $tel_variants, [ $tel ] );

    $songs_active = (int) $wpdb->get_var( $wpdb->prepare(
        "SELECT COUNT(DISTINCT s.track_id)
         FROM $t_splits s
         INNER JOIN $t_tracks   t ON t.id = s.track_id
         INNER JOIN $t_releases r ON r.id = t.release_id
         WHERE s.collaborator_telemovel IN ($placeholders_tel)
           AND r.artist_telemovel <> %s
           AND r.status IN ('live','distribuido')
           AND s.invite_status = 'accepted'",
        $params_with_owner
    ) );
    $songs_pending = (int) $wpdb->get_var( $wpdb->prepare(
        "SELECT COUNT(DISTINCT s.track_id)
         FROM $t_splits s
         INNER JOIN $t_tracks   t ON t.id = s.track_id
         INNER JOIN $t_releases r ON r.id = t.release_id
         WHERE s.collaborator_telemovel IN ($placeholders_tel)
           AND r.artist_telemovel <> %s
           AND s.invite_status = 'pending'",
        $params_with_owner
    ) );

    return rmbz_api_ok( [
        'total_pending_usd'   => round( $total_pending, 4 ),
        'total_claimed_usd'   => round( $total_claimed, 4 ),
        'songs_count_active'  => $songs_active,
        'songs_count_pending' => $songs_pending,
    ] );
}

/**
 * Helper para resolver capa: pode ser URL absoluto ou attachment ID.
 * Devolve sempre URL absoluto ou null.
 */
function rmbz_api_collab_resolve_cover( $cover ) {
    if ( empty( $cover ) ) return null;
    if ( is_numeric( $cover ) ) {
        $url = wp_get_attachment_image_url( (int) $cover, 'medium' );
        return $url ?: null;
    }
    // já é URL
    if ( filter_var( $cover, FILTER_VALIDATE_URL ) ) return $cover;
    return null;
}

/**
 * [1.6.56] Gera variantes do telemovel para apanhar qualquer
 * formato que tenha sido guardado (ex: "861640807",
 * "+258861640807", "258861640807"). Devolve um array com pelo
 * menos a entrada original.
 */
function rmbz_api_collab_telemovel_variants( $tel ) {
    $tel = trim( (string) $tel );
    if ( $tel === '' ) return [ '' ];

    $variants = [ $tel ];

    // Sem "+" inicial
    if ( strpos( $tel, '+' ) === 0 ) {
        $no_plus = substr( $tel, 1 );
        $variants[] = $no_plus;
        // Sem prefixo 258
        if ( strpos( $no_plus, '258' ) === 0 ) {
            $variants[] = substr( $no_plus, 3 );
        }
    } else {
        // Sem "+" mas começa com 258
        if ( strpos( $tel, '258' ) === 0 ) {
            $variants[] = '+' . $tel;
            $variants[] = substr( $tel, 3 );
        } else {
            // só dígitos locais — adicionar versões com prefixo
            $variants[] = '258' . $tel;
            $variants[] = '+258' . $tel;
        }
    }

    return array_values( array_unique( $variants ) );
}
