<?php
/**
 * 1MZ For Artists — History Endpoint
 *
 * Devolve a timeline cronológica do artista, agregando dados de várias
 * tabelas que já existem mas nunca foram expostas em conjunto:
 *
 *   - rmbz_distro_status_history  → eventos de releases (submeter, aprovar,
 *                                    rejeitar, takedown)
 *   - rmbz_wallet_transactions     → depósitos e levantamentos
 *   - rmbz_splits_audit            → splits convidados/aceites/recusados
 *                                    onde o user é actor ou beneficiário
 *   - rmbz_artists (meta)          → conta criada
 *
 * ENDPOINT:
 *   GET /me/history?limit=50&offset=0&filter=all|releases|payments|splits|account
 *
 * @package 1MZ_For_Artists
 * @since 1.6.54
 */

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

if ( ! defined( 'RMBZ_API_HISTORY_VERSION' ) ) {
    define( 'RMBZ_API_HISTORY_VERSION', '1.6.54' );
}

add_action( 'rest_api_init', 'rmbz_api_register_history_routes' );

function rmbz_api_register_history_routes() {
    register_rest_route( RMBZ_API_NAMESPACE, '/me/history', [
        'methods'             => 'GET',
        'callback'            => 'rmbz_api_handle_me_history',
        'permission_callback' => 'rmbz_api_require_auth',
        'args' => [
            'limit'  => [ 'type' => 'integer', 'default' => 50 ],
            'offset' => [ 'type' => 'integer', 'default' => 0 ],
            'filter' => [ 'type' => 'string',  'default' => 'all' ],
        ],
    ] );
}

/**
 * Estrutura de cada item devolvido:
 *  {
 *    id:         string,   // único entre todos (prefix por tipo)
 *    category:   string,   // "release"|"payment"|"split"|"account"
 *    type:       string,   // sub-tipo específico (ver lista abaixo)
 *    title:      string,
 *    subtitle:   string|null,
 *    release_id: int|null, // se aplicável, para deep-link
 *    severity:   string,   // info|success|warning|danger
 *    created_at: string,   // ISO 8601
 *  }
 *
 * Tipos:
 *   release.created, release.submitted, release.approved,
 *   release.rejected, release.returned, release.takedown_requested,
 *   release.taken_down
 *   payment.deposit, payment.withdrawal, payment.refund, payment.adjust
 *   split.invited, split.accepted, split.declined, split.removed
 *   account.created
 */
function rmbz_api_handle_me_history( WP_REST_Request $request ) {
    $tel    = (string) $request->get_param( 'rmbz_telemovel' );
    $limit  = max( 1, min( 100, (int) $request->get_param( 'limit' ) ) );
    $offset = max( 0, (int) $request->get_param( 'offset' ) );
    $filter = (string) $request->get_param( 'filter' );

    if ( ! in_array( $filter, [ 'all', 'releases', 'payments', 'splits', 'account' ], true ) ) {
        $filter = 'all';
    }

    $items = [];

    if ( $filter === 'all' || $filter === 'releases' ) {
        $items = array_merge( $items, rmbz_api_history_collect_releases( $tel ) );
    }
    if ( $filter === 'all' || $filter === 'payments' ) {
        $items = array_merge( $items, rmbz_api_history_collect_payments( $tel ) );
    }
    if ( $filter === 'all' || $filter === 'splits' ) {
        $items = array_merge( $items, rmbz_api_history_collect_splits( $tel ) );
    }
    if ( $filter === 'all' || $filter === 'account' ) {
        $items = array_merge( $items, rmbz_api_history_collect_account( $tel ) );
    }

    // Ordenar globalmente por created_at desc
    usort( $items, function( $a, $b ) {
        return strcmp( $b['created_at'], $a['created_at'] );
    } );

    $total = count( $items );
    $page  = array_slice( $items, $offset, $limit );

    return rmbz_api_ok( [
        'items'  => $page,
        'total'  => $total,
        'limit'  => $limit,
        'offset' => $offset,
    ] );
}

/* ----------------------------------------------------------------------- */
/* RELEASES                                                                */
/* ----------------------------------------------------------------------- */

function rmbz_api_history_collect_releases( $tel ) {
    global $wpdb;

    // status_history só tem release_id — fazemos join para confirmar
    // ownership e obter o título do release. Renomear `r.title` para
    // `release_title` para não confundir com o `title` do output JSON.
    $rows = $wpdb->get_results( $wpdb->prepare(
        "SELECT h.id, h.release_id, h.from_status, h.to_status,
                h.reason_code, h.reason_text, h.created_at,
                r.title AS release_title
         FROM {$wpdb->prefix}rmbz_distro_status_history h
         INNER JOIN {$wpdb->prefix}rmbz_distro_releases r
                 ON r.id = h.release_id
         WHERE r.artist_telemovel = %s
         ORDER BY h.created_at DESC
         LIMIT 300",
        $tel
    ) );

    $out = [];
    if ( ! $rows ) return $out;

    foreach ( $rows as $r ) {
        $title    = $r->release_title ?: 'Release';
        $type     = null;
        $heading  = '';
        $sub      = null;
        $severity = 'info';

        switch ( $r->to_status ) {
            case 'pendente':
                if ( $r->from_status === 'rejected' || $r->reason_code === 'submitted_by_artist' ) {
                    $type    = 'release.submitted';
                    $heading = 'Release submetido';
                    $sub     = '"' . $title . '" enviado para revisão';
                    $severity = 'info';
                } else {
                    $type    = 'release.submitted';
                    $heading = 'Release submetido';
                    $sub     = '"' . $title . '" enviado para revisão';
                }
                break;
            case 'live':
                $type    = 'release.approved';
                $heading = 'Release aprovado';
                $sub     = '"' . $title . '" entrou nas lojas';
                $severity = 'success';
                break;
            case 'rejected':
                $type    = 'release.rejected';
                $heading = 'Release rejeitado';
                $sub     = '"' . $title . '"' . ( $r->reason_text
                            ? ' — ' . wp_trim_words( $r->reason_text, 8, '...' )
                            : '' );
                $severity = 'danger';
                break;
            case 'returned':
                $type    = 'release.returned';
                $heading = 'Release devolvido';
                $sub     = '"' . $title . '"' . ( $r->reason_text
                            ? ' — ' . wp_trim_words( $r->reason_text, 8, '...' )
                            : ' — para correcção' );
                $severity = 'warning';
                break;
            case 'takedown_requested':
                $type    = 'release.takedown_requested';
                $heading = 'Takedown solicitado';
                $sub     = 'Pedido para retirar "' . $title . '" das lojas';
                $severity = 'warning';
                break;
            case 'taken_down':
                $type    = 'release.taken_down';
                $heading = 'Release retirado';
                $sub     = '"' . $title . '" foi removido das lojas';
                $severity = 'info';
                break;
            default:
                continue 2; // saltar estado desconhecido
        }

        $out[] = [
            'id'         => 'rel-' . (int) $r->id,
            'category'   => 'release',
            'type'       => $type,
            'title'      => $heading,
            'subtitle'   => $sub,
            'release_id' => (int) $r->release_id,
            'severity'   => $severity,
            'created_at' => mysql_to_rfc3339( $r->created_at ),
        ];
    }

    return $out;
}

/* ----------------------------------------------------------------------- */
/* PAYMENTS — wallet_transactions                                          */
/* ----------------------------------------------------------------------- */

function rmbz_api_history_collect_payments( $tel ) {
    global $wpdb;

    $rows = $wpdb->get_results( $wpdb->prepare(
        "SELECT transaction_id, amount, type, details, transaction_date
         FROM {$wpdb->prefix}rmbz_wallet_transactions
         WHERE user_telemovel = %s
         ORDER BY transaction_date DESC
         LIMIT 300",
        $tel
    ) );

    $out = [];
    if ( ! $rows ) return $out;

    foreach ( $rows as $r ) {
        $amount = (float) $r->amount;
        $type_raw = strtolower( (string) $r->type );

        // Classificar como deposit/withdrawal/refund/adjust
        $heading  = '';
        $sub      = '';
        $type     = '';
        $severity = 'info';

        if ( strpos( $type_raw, 'with' ) !== false || $amount < 0 ) {
            // levantamento
            $type     = 'payment.withdrawal';
            $heading  = 'Levantamento';
            $sub      = number_format_i18n( abs( $amount ), 2 ) . ' MT';
            $severity = 'info';
        } elseif ( strpos( $type_raw, 'refund' ) !== false ) {
            $type     = 'payment.refund';
            $heading  = 'Estorno';
            $sub      = number_format_i18n( abs( $amount ), 2 ) . ' MT';
            $severity = 'info';
        } elseif ( strpos( $type_raw, 'adjust' ) !== false ) {
            $type     = 'payment.adjust';
            $heading  = 'Ajuste de saldo';
            $sub      = ( $amount >= 0 ? '+' : '' )
                      . number_format_i18n( $amount, 2 ) . ' MT';
            $severity = 'info';
        } else {
            // depósito / royalty
            $type     = 'payment.deposit';
            $heading  = 'Depósito';
            $sub      = number_format_i18n( $amount, 2 ) . ' MT';
            $severity = 'success';
        }

        $out[] = [
            'id'         => 'pay-' . (int) $r->transaction_id,
            'category'   => 'payment',
            'type'       => $type,
            'title'      => $heading,
            'subtitle'   => $sub,
            'release_id' => null,
            'severity'   => $severity,
            'created_at' => mysql_to_rfc3339( $r->transaction_date ),
        ];
    }

    return $out;
}

/* ----------------------------------------------------------------------- */
/* SPLITS                                                                   */
/* ----------------------------------------------------------------------- */

function rmbz_api_history_collect_splits( $tel ) {
    global $wpdb;

    // Pegar splits onde o user é actor OU dono da release (apanha quando
    // o user é convidado).
    $rows = $wpdb->get_results( $wpdb->prepare(
        "SELECT s.id, s.split_id, s.track_id, s.release_id, s.action,
                s.actor, s.note, s.created_at,
                r.title AS release_title
         FROM {$wpdb->prefix}rmbz_splits_audit s
         INNER JOIN {$wpdb->prefix}rmbz_distro_releases r
                 ON r.id = s.release_id
         WHERE r.artist_telemovel = %s
            OR s.actor = %s
         ORDER BY s.created_at DESC
         LIMIT 300",
        $tel, $tel
    ) );

    $out = [];
    if ( ! $rows ) return $out;

    foreach ( $rows as $r ) {
        $action = strtolower( (string) $r->action );
        $title  = $r->release_title ?: 'Release';

        $type    = '';
        $heading = '';
        $sub     = $r->note ? wp_trim_words( $r->note, 10, '...' )
                            : 'Em "' . $title . '"';
        $severity = 'info';

        if ( strpos( $action, 'invite' ) !== false || strpos( $action, 'create' ) !== false ) {
            $type     = 'split.invited';
            $heading  = 'Split criado';
        } elseif ( strpos( $action, 'accept' ) !== false ) {
            $type     = 'split.accepted';
            $heading  = 'Split aceite';
            $severity = 'success';
        } elseif ( strpos( $action, 'decline' ) !== false || strpos( $action, 'reject' ) !== false ) {
            $type     = 'split.declined';
            $heading  = 'Split recusado';
            $severity = 'warning';
        } elseif ( strpos( $action, 'remove' ) !== false || strpos( $action, 'delete' ) !== false ) {
            $type     = 'split.removed';
            $heading  = 'Split removido';
        } else {
            // Acção desconhecida — saltar (não poluir a timeline)
            continue;
        }

        $out[] = [
            'id'         => 'spl-' . (int) $r->id,
            'category'   => 'split',
            'type'       => $type,
            'title'      => $heading,
            'subtitle'   => $sub,
            'release_id' => (int) $r->release_id,
            'severity'   => $severity,
            'created_at' => mysql_to_rfc3339( $r->created_at ),
        ];
    }

    return $out;
}

/* ----------------------------------------------------------------------- */
/* ACCOUNT                                                                  */
/* ----------------------------------------------------------------------- */

function rmbz_api_history_collect_account( $tel ) {
    global $wpdb;

    // Para v1, apenas "conta criada" — usamos a tabela de wallets que
    // tem `last_updated`. Não há campo `created_at` directo; como
    // fallback razoável, usamos o registo mais antigo de wallet
    // transaction (TYPE=deposit_inicial) ou o `last_updated` da wallet
    // se nada melhor existir. Para já, usamos o mais antigo evento de
    // history dessa user — se não houver, omitimos.
    $row = $wpdb->get_row( $wpdb->prepare(
        "SELECT user_nome, last_updated
         FROM {$wpdb->prefix}rmbz_wallets
         WHERE user_telemovel = %s
         LIMIT 1",
        $tel
    ) );

    if ( ! $row ) return [];

    // Tentar achar a data real de criação — a transação mais antiga é
    // melhor proxy do que `last_updated` (que muda em qualquer edit).
    $earliest = $wpdb->get_var( $wpdb->prepare(
        "SELECT MIN(transaction_date)
         FROM {$wpdb->prefix}rmbz_wallet_transactions
         WHERE user_telemovel = %s",
        $tel
    ) );

    $created_at = $earliest ?: $row->last_updated;
    if ( empty( $created_at ) ) return [];

    return [ [
        'id'         => 'acc-created',
        'category'   => 'account',
        'type'       => 'account.created',
        'title'      => 'Bem-vindo ao 1MZ for Artists',
        'subtitle'   => $row->user_nome
                        ? 'A tua conta como "' . $row->user_nome . '" foi criada'
                        : 'A tua conta foi criada',
        'release_id' => null,
        'severity'   => 'info',
        'created_at' => mysql_to_rfc3339( $created_at ),
    ] ];
}
