<?php
/**
 * 1MZ For Artists API — Platforms Controller (1.6.11)
 *
 * Endpoints de configuração de plataformas/territórios por release.
 *
 * Reutiliza a lógica e tabelas do sistema de plataformas que já existe em
 *   includes/distribution/distribution-platforms.php
 *
 * Tabela envolvida:
 *   wp_rmbz_distro_release_platforms — uma linha por release com config
 *
 * Endpoints:
 *   GET /releases/options/platforms       — catálogo (DSPs + territórios + serviços exclusivos)
 *   PUT /releases/{id}/platforms          — actualizar config de um release
 *
 * O endpoint GET /releases/{id}/platforms (ler config actual) já existe em
 * releases-controller.php — não duplicamos.
 *
 * @package 1MZ_For_Artists
 * @since 1.6.11
 */

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

// Garantir que o módulo de plataformas está carregado (defensivo).
if ( ! function_exists( 'rmbz_distro_dsp_catalog' ) ) {
    require_once dirname( __FILE__, 3 ) . '/distribution/distribution-platforms.php';
}

add_action( 'rest_api_init', 'rmbz_api_register_platforms_routes' );

function rmbz_api_register_platforms_routes() {
    $ns = RMBZ_API_NAMESPACE;

    register_rest_route( $ns, '/releases/options/platforms', [
        'methods'             => 'GET',
        'callback'            => 'rmbz_api_handle_platforms_catalog',
        'permission_callback' => 'rmbz_api_require_auth',
    ] );

    register_rest_route( $ns, '/releases/(?P<id>\d+)/platforms', [
        'methods'             => 'PUT',
        'callback'            => 'rmbz_api_handle_update_platforms',
        'permission_callback' => 'rmbz_api_require_auth',
        'args' => [
            'id' => [ 'type' => 'integer', 'required' => true ],
        ],
    ] );
}

/* ============================================================================
 * GET /releases/options/platforms
 *
 * Retorna o catálogo completo: DSPs disponíveis, territórios, serviços
 * exclusivos. A app usa isto para construir os checkboxes/lista de selecção.
 * ============================================================================ */
function rmbz_api_handle_platforms_catalog( WP_REST_Request $request ) {
    // DSPs (com tier para a app poder agrupar)
    $catalog = rmbz_distro_dsp_catalog();
    $dsps = [];
    foreach ( $catalog as $slug => $meta ) {
        $dsps[] = [
            'slug' => (string) $slug,
            'name' => (string) ( $meta['name'] ?? $slug ),
            'tier' => (int) ( $meta['tier'] ?? 3 ),
        ];
    }

    // DSPs default (Tier 1) — pré-selecção
    $default_dsps = function_exists( 'rmbz_distro_dsp_default_selection' )
        ? rmbz_distro_dsp_default_selection()
        : [];

    // Territórios agrupados por região
    $regions_raw = function_exists( 'rmbz_distro_territory_regions' )
        ? rmbz_distro_territory_regions()
        : [];
    $regions = [];
    foreach ( $regions_raw as $key => $reg ) {
        $countries = [];
        foreach ( (array) ( $reg['countries'] ?? [] ) as $code => $name ) {
            $countries[] = [
                'code' => (string) $code,
                'name' => (string) $name,
            ];
        }
        $regions[] = [
            'key'       => (string) $key,
            'label'     => (string) ( $reg['label'] ?? $key ),
            'countries' => $countries,
        ];
    }

    // Serviços exclusivos (com avisos completos para o user concordar)
    $exclusives_raw = function_exists( 'rmbz_distro_exclusive_services' )
        ? rmbz_distro_exclusive_services()
        : [];
    $exclusives = [];
    foreach ( $exclusives_raw as $key => $svc ) {
        $exclusives[] = [
            'key'    => (string) $key,
            'name'   => (string) ( $svc['name']   ?? $key ),
            'short'  => (string) ( $svc['short']  ?? '' ),
            'notice' => (string) ( $svc['notice'] ?? '' ),
        ];
    }

    return rmbz_api_ok( [
        'dsps'         => $dsps,
        'default_dsps' => $default_dsps,
        'regions'      => $regions,
        'exclusives'   => $exclusives,
    ] );
}

/* ============================================================================
 * PUT /releases/{id}/platforms
 *
 * Actualiza a config de plataformas de um release.
 * Body esperado:
 *   {
 *     "territory_mode": "worldwide" | "include" | "exclude",
 *     "territories": ["MZ", "PT", ...],
 *     "dsps": ["spotify", "apple_music", ...],
 *     "exclusives": {
 *       "youtube_content_id":   "requested" | "not_requested",
 *       "facebook_monetization":"requested" | "not_requested",
 *       "tiktok_monetization":  "requested" | "not_requested"
 *     }
 *   }
 * ============================================================================ */
function rmbz_api_handle_update_platforms( WP_REST_Request $request ) {
    global $wpdb;
    $telemovel = (string) $request->get_param( 'rmbz_telemovel' );
    $id        = (int)    $request->get_param( 'id' );

    // 1) Verificar ownership
    $owns = (int) $wpdb->get_var( $wpdb->prepare(
        "SELECT 1 FROM {$wpdb->prefix}rmbz_distro_releases
         WHERE id = %d AND artist_telemovel = %s",
        $id, $telemovel
    ) );
    if ( ! $owns ) {
        return rmbz_api_error( 'Release não encontrado.', 404, 'not_found' );
    }

    // 2) Verificar que o release está editável (mesmas regras do PUT /releases/{id})
    $release = $wpdb->get_row( $wpdb->prepare(
        "SELECT status FROM {$wpdb->prefix}rmbz_distro_releases WHERE id = %d", $id
    ) );
    $editable_statuses = [ 'incomplete', 'draft', 'returned' ];
    if ( ! in_array( $release->status, $editable_statuses, true ) ) {
        return rmbz_api_error(
            'Plataformas só podem ser editadas com release em rascunho ou devolvido (estado actual: ' . $release->status . ').',
            409,
            'not_editable'
        );
    }

    $body = $request->get_json_params();
    if ( ! is_array( $body ) ) $body = [];

    // 3) Validar territory_mode
    // Aceitamos os valores novos do app E os legados do site (compatibilidade).
    // Mapeamos para 1 dos 3 valores válidos para a BD.
    $allowed_modes = [ 'worldwide', 'include', 'exclude', 'selected', 'worldwide_except' ];
    $territory_mode_in = isset( $body['territory_mode'] )
        ? (string) $body['territory_mode']
        : 'worldwide';
    if ( ! in_array( $territory_mode_in, $allowed_modes, true ) ) {
        return rmbz_api_error( 'Modo de território inválido.', 400, 'invalid_territory_mode' );
    }
    // Normalizar valores legados para os novos
    $mode_map = [
        'worldwide'        => 'worldwide',
        'include'          => 'selected',           // BD usa 'selected'
        'exclude'          => 'worldwide_except',   // BD usa 'worldwide_except'
        'selected'         => 'selected',
        'worldwide_except' => 'worldwide_except',
    ];
    $territory_mode = $mode_map[ $territory_mode_in ];

    // 4) Validar territories (lista de códigos ISO 2 letras)
    $territories_in = isset( $body['territories'] ) && is_array( $body['territories'] )
        ? $body['territories']
        : [];
    $territories = [];
    $valid_codes = function_exists( 'rmbz_distro_territory_list' )
        ? rmbz_distro_territory_list()
        : [];
    foreach ( $territories_in as $code ) {
        $code = strtoupper( trim( (string) $code ) );
        if ( strlen( $code ) === 2 ) {
            // Se temos catálogo de territórios, validar; senão aceitar (defensivo)
            if ( empty( $valid_codes ) || isset( $valid_codes[ $code ] ) ) {
                $territories[] = $code;
            }
        }
    }
    $territories = array_values( array_unique( $territories ) );

    // Se modo é worldwide, lista deve estar vazia
    if ( $territory_mode === 'worldwide' ) {
        $territories = [];
    } else if ( empty( $territories ) ) {
        // Se selected/worldwide_except, precisa de pelo menos 1 país
        return rmbz_api_error(
            'Para o modo "' . $territory_mode_in . '" precisa de pelo menos 1 país.',
            400,
            'no_territories'
        );
    }

    // 5) Validar DSPs
    $dsps_in = isset( $body['dsps'] ) && is_array( $body['dsps'] )
        ? $body['dsps']
        : [];
    $catalog = function_exists( 'rmbz_distro_dsp_catalog' )
        ? rmbz_distro_dsp_catalog()
        : [];
    $dsps = [];
    foreach ( $dsps_in as $slug ) {
        $slug = (string) $slug;
        if ( isset( $catalog[ $slug ] ) ) {
            $dsps[] = $slug;
        }
    }
    $dsps = array_values( array_unique( $dsps ) );

    // Tem de ter pelo menos 1 DSP seleccionado
    if ( empty( $dsps ) ) {
        return rmbz_api_error(
            'Tem que escolher pelo menos uma plataforma.',
            400,
            'no_dsps'
        );
    }

    // 6) Validar exclusivos (opt_in/opt_out, mas só do lado do user)
    $exclusives_in = isset( $body['exclusives'] ) && is_array( $body['exclusives'] )
        ? $body['exclusives']
        : [];

    // Carregar valores actuais para preservar status existentes (admin pode já
    // ter aprovado/rejeitado, e isso NÃO se mexe daqui)
    $current = $wpdb->get_row( $wpdb->prepare(
        "SELECT yt_content_id_status, fb_monet_status, tt_monet_status
         FROM {$wpdb->prefix}rmbz_distro_release_platforms
         WHERE release_id = %d",
        $id
    ) );
    $cur_yt = $current ? (string) $current->yt_content_id_status : 'not_requested';
    $cur_fb = $current ? (string) $current->fb_monet_status      : 'not_requested';
    $cur_tt = $current ? (string) $current->tt_monet_status      : 'not_requested';

    // Mapeamento user → BD: user só pode alternar entre 'not_requested' e 'requested'.
    // Se admin já aprovou/rejeitou (approved, rejected, conflict), ignoramos pedidos do user.
    $user_only_states = [ 'not_requested', 'requested' ];

    $next_yt = $cur_yt;
    if ( isset( $exclusives_in['youtube_content_id'] )
        && in_array( $exclusives_in['youtube_content_id'], $user_only_states, true )
        && in_array( $cur_yt, $user_only_states, true ) ) {
        $next_yt = $exclusives_in['youtube_content_id'];
    }

    $next_fb = $cur_fb;
    if ( isset( $exclusives_in['facebook_monetization'] )
        && in_array( $exclusives_in['facebook_monetization'], $user_only_states, true )
        && in_array( $cur_fb, $user_only_states, true ) ) {
        $next_fb = $exclusives_in['facebook_monetization'];
    }

    $next_tt = $cur_tt;
    if ( isset( $exclusives_in['tiktok_monetization'] )
        && in_array( $exclusives_in['tiktok_monetization'], $user_only_states, true )
        && in_array( $cur_tt, $user_only_states, true ) ) {
        $next_tt = $exclusives_in['tiktok_monetization'];
    }

    // 7) UPSERT na tabela
    $table = $wpdb->prefix . 'rmbz_distro_release_platforms';
    $exists = (int) $wpdb->get_var( $wpdb->prepare(
        "SELECT 1 FROM $table WHERE release_id = %d", $id
    ) );

    $data = [
        'release_id'           => $id,
        'territory_mode'       => $territory_mode,
        'territory_list'       => wp_json_encode( $territories ),
        'dsp_list'             => wp_json_encode( $dsps ),
        'user_confirmed'       => 1,
        'yt_content_id_status' => $next_yt,
        'fb_monet_status'      => $next_fb,
        'tt_monet_status'      => $next_tt,
        'updated_at'           => current_time( 'mysql' ),
    ];
    $fmt = [ '%d', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%s' ];

    if ( $exists ) {
        $wpdb->update( $table, $data, [ 'release_id' => $id ], $fmt, [ '%d' ] );
    } else {
        $wpdb->insert( $table, $data, $fmt );
    }

    // 8) Devolver o estado actualizado (mesmo formato que GET /releases/{id}/platforms)
    return rmbz_api_handle_get_release_platforms( $request );
}
