<?php
$roulette = new \Plugin\NexoraRoulette\NexoraRoulette();
$roulette->ensureSchema();
$studio = new \Plugin\NexoraRoulette\NexoraPoolStudio($roulette->getRealm());
$realmLabel = $roulette->getRealmLabel();
$simulation = null;

if(!function_exists('nxrPoolStudioSavePrizeRow')) {
    function nxrPoolStudioSavePrizeRow($roulette,$row,$overrides=array()) {
        $data=array(
            'id'=>(int)($row['id']??0),
            'name'=>(string)($row['name']??''),
            'description'=>(string)($row['description']??''),
            'prize_type'=>(string)($row['prize_type']??'manual'),
            'rarity'=>(string)($row['rarity']??'common'),
            'weight'=>(int)($row['weight']??0),
            'amount'=>(int)($row['amount']??0),
            'credit_config_id'=>(int)($row['credit_config_id']??0),
            'item_id'=>(int)($row['item_id']??0),
            'daily_global_limit'=>(int)($row['daily_global_limit']??0),
            'daily_account_limit'=>(int)($row['daily_account_limit']??0),
            'active'=>(int)($row['active']??0),
            'sort_order'=>(int)($row['sort_order']??100),
        );
        foreach($overrides as $k=>$v) $data[$k]=$v;
        return $roulette->savePrize($data);
    }
}
if(!function_exists('nxrPoolStudioEsc')) {
    function nxrPoolStudioEsc($v) { return htmlspecialchars((string)$v,ENT_QUOTES,'UTF-8'); }
}
if(!function_exists('nxrPoolStudioIcon')) {
    function nxrPoolStudioIcon($roulette,$prize) {
        $name=mb_strtolower((string)($prize['name']??''),'UTF-8');
        $type=(string)($prize['prize_type']??'manual');
        if(strpos($name,'legado nexora')!==false) return __PATH_TEMPLATE_IMG__.'nexora-legacy-icon.png?v=1.8.0';
        if($type==='credits') return __PATH_TEMPLATE_IMG__.'nexora-wc-coin.png?v=1.8.0';
        if($type==='fragments') return __PATH_TEMPLATE_IMG__.'nexora-fragment.png?v=1.8.0';
        if($type==='free_spins' && (strpos($name,'reentrada')!==false || strpos($name,'reentry')!==false)) return __PATH_TEMPLATE_IMG__.'nexora-reentry-icon.png?v=1.8.0';
        if($type==='itemshop' && !empty($prize['item_id'])) {
            $visual=$roulette->itemshopRewardVisual((int)$prize['item_id']);
            if(is_array($visual) && !empty($visual['url'])) return (string)$visual['url'];
        }
        return __PATH_TEMPLATE_IMG__.'icons/usercp_default.png';
    }
}

if(isset($_POST['save_poolstudio'])) {
    try {
        $studio->save($_POST);
        if(class_exists('NexoraAudit')) \NexoraAudit::log('roulette.poolstudio_save','roulette',$roulette->getRealm(),null,array('campaign_title'=>(string)($_POST['campaign_title']??'')),$roulette->getRealm());
        message('success','Pool Studio guardado para '.$realmLabel.'.');
    } catch(Throwable $e) { message('error',$e->getMessage()); }
}

if(isset($_POST['save_order'])) {
    try {
        $ids=array_values(array_filter(array_map('intval',explode(',',(string)($_POST['ordered_ids']??'')))));
        if(!$ids) throw new RuntimeException('No se recibió un orden válido.');
        $sort=10;
        foreach($ids as $id) {
            $row=$roulette->getPrize($id);
            if(!is_array($row)) continue;
            nxrPoolStudioSavePrizeRow($roulette,$row,array('sort_order'=>$sort));
            $sort+=10;
        }
        message('success','Orden visual guardado.');
    } catch(Throwable $e) { message('error',$e->getMessage()); }
}

if(isset($_POST['duplicate_prize'])) {
    try {
        $row=$roulette->getPrize((int)$_POST['duplicate_prize']);
        if(!is_array($row)) throw new RuntimeException('Premio no encontrado.');
        $name=trim((string)$row['name'].' · copia');
        if(mb_strlen($name)>120) $name=mb_substr($name,0,120);
        nxrPoolStudioSavePrizeRow($roulette,$row,array('id'=>0,'name'=>$name,'active'=>0,'sort_order'=>(int)$row['sort_order']+5));
        message('success','Premio duplicado como inactivo. Puedes editarlo sin alterar el pool actual.');
    } catch(Throwable $e) { message('error',$e->getMessage()); }
}

if(isset($_POST['save_snapshot'])) {
    try {
        $cfg=$studio->load();
        $snap=$studio->saveSnapshot((string)($_POST['snapshot_label']??''),$roulette->getPrizes(true),array(
            'campaign_title'=>$cfg['campaign_title'],
            'campaign_subtitle'=>$cfg['campaign_subtitle'],
            'campaign_starts_at'=>$cfg['campaign_starts_at'],
            'campaign_ends_at'=>$cfg['campaign_ends_at'],
            'featured_prize_id'=>$cfg['featured_prize_id'],
        ));
        message('success','Copia del pool guardada: '.$snap['label'].'.');
    } catch(Throwable $e) { message('error',$e->getMessage()); }
}

if(isset($_POST['delete_snapshot'])) {
    try { $studio->deleteSnapshot((string)$_POST['delete_snapshot']); message('success','Copia del pool eliminada.'); }
    catch(Throwable $e) { message('error',$e->getMessage()); }
}

if(isset($_POST['restore_snapshot'])) {
    try {
        if(empty($_POST['confirm_restore'])) throw new RuntimeException('Confirma la restauración del pool.');
        $snap=$studio->snapshot((string)$_POST['restore_snapshot']);
        if(!is_array($snap) || empty($snap['prizes']) || !is_array($snap['prizes'])) throw new RuntimeException('La copia seleccionada no existe o está vacía.');
        $current=$roulette->getPrizes(false);
        foreach($current as $row) if((int)$row['active']===1) $roulette->retirePrize((int)$row['id']);
        $all=$roulette->getPrizes(false);
        foreach($snap['prizes'] as $saved) {
            $existing=null;
            foreach($all as $candidate) if((string)$candidate['name']===(string)$saved['name']) { $existing=$candidate; break; }
            $saved['id']=is_array($existing)?(int)$existing['id']:0;
            $saved['active']=1;
            nxrPoolStudioSavePrizeRow($roulette,$saved);
            $all=$roulette->getPrizes(false);
        }
        if(!empty($snap['campaign']) && is_array($snap['campaign'])) {
            $currentCfg=$studio->load();
            $campaign=array_merge($currentCfg,$snap['campaign']);
            $campaign['show_campaign']=$currentCfg['show_campaign'];
            $campaign['show_featured']=$currentCfg['show_featured'];
            $campaign['show_probability_modal']=$currentCfg['show_probability_modal'];
            $campaign['default_spin_mode']=$currentCfg['default_spin_mode'];
            $campaign['quick_spin_ms']=$currentCfg['quick_spin_ms'];
            $campaign['max_direct_return_ratio']=$currentCfg['max_direct_return_ratio'];
            $studio->save($campaign);
        }
        message('success','Pool restaurado desde la copia '.$snap['label'].'.');
    } catch(Throwable $e) { message('error',$e->getMessage()); }
}

if(isset($_POST['simulate_100k'])) {
    try { $simulation=$roulette->simulateEconomy(100000); }
    catch(Throwable $e) { message('error',$e->getMessage()); }
}

$cfg=$studio->load();
$odds=$roulette->odds(true);
$activePrizes=$odds['prizes'];
$allPrizes=$roulette->getPrizes(false);
$availability=$roulette->prizeAvailability('');
$economy=$roulette->economyDashboard();
$expectedRatio=$economy['expected']['direct_return_ratio'];
$rarityLabels=\Plugin\NexoraRoulette\NexoraRoulette::rarityLabels();
$probById=array();
foreach($activePrizes as $p) $probById[(int)$p['id']]=(float)$p['probability'];
$campaignState=$studio->campaignState($cfg);
?>
<style>
.nxr-ps-grid{display:grid;grid-template-columns:minmax(0,1.45fr) minmax(320px,.8fr);gap:18px}.nxr-ps-card{background:#fff;border:1px solid #ddd;border-radius:5px;margin-bottom:18px}.nxr-ps-card-h{padding:14px 16px;border-bottom:1px solid #e6e6e6;display:flex;align-items:center;justify-content:space-between;gap:12px}.nxr-ps-card-b{padding:16px}.nxr-ps-muted{color:#777}.nxr-ps-live{display:grid;place-items:center;min-height:340px;background:radial-gradient(circle at center,#1c1530 0,#0c1018 68%,#080b11 100%);border-radius:5px;overflow:hidden}.nxr-ps-wheel{position:relative;width:270px;height:270px;border-radius:50%;border:8px solid #c99a3d;box-shadow:0 0 0 4px #572e8e,0 0 45px rgba(119,71,199,.35);background:conic-gradient(#272137 0 45deg,#171e2b 45deg 90deg,#252035 90deg 135deg,#151c28 135deg 180deg,#252035 180deg 225deg,#171e2b 225deg 270deg,#252035 270deg 315deg,#151c28 315deg 360deg)}.nxr-ps-wheel:after{content:'NEXORA';position:absolute;inset:82px;border-radius:50%;display:grid;place-items:center;background:#0d1119;border:3px solid #c99a3d;color:#e7c56e;font-weight:800;letter-spacing:.12em}.nxr-ps-preview-list{margin-top:14px;color:#d5d9e2;font-size:12px;display:grid;gap:5px;width:min(360px,90%)}.nxr-ps-preview-list span{display:flex;justify-content:space-between;gap:10px}.nxr-ps-table tbody tr{cursor:grab}.nxr-ps-table tbody tr.is-dragging{opacity:.45}.nxr-ps-icon{width:42px;height:42px;object-fit:contain;filter:drop-shadow(0 4px 7px rgba(0,0,0,.25))}.nxr-ps-rarity{display:inline-block;padding:3px 7px;border-radius:10px;background:#f1f1f1}.nxr-ps-alert-good{border-left:4px solid #2ea65b}.nxr-ps-alert-warn{border-left:4px solid #d49b27}.nxr-ps-sim{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}.nxr-ps-sim>div{border:1px solid #ddd;border-radius:5px;padding:12px}.nxr-ps-sim small{display:block;color:#777}.nxr-ps-sim strong{font-size:18px}.nxr-ps-snapshot{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid #eee}.nxr-ps-snapshot:last-child{border:0}@media(max-width:1100px){.nxr-ps-grid{grid-template-columns:1fr}.nxr-ps-sim{grid-template-columns:repeat(2,1fr)}}
</style>
<h1 class="page-header">Pool Studio <small><?php echo nxrPoolStudioEsc($realmLabel); ?></small></h1>
<p class="lead">Configura la presentación de campaña, ordena el pool, duplica premios, guarda copias y valida el retorno antes de publicar cambios.</p>

<div class="nxr-ps-grid">
<div>
<div class="nxr-ps-card">
<div class="nxr-ps-card-h"><strong>Campaña visible</strong><span class="label label-<?php echo $campaignState==='active'?'success':($campaignState==='scheduled'?'info':'default'); ?>"><?php echo nxrPoolStudioEsc(strtoupper($campaignState)); ?></span></div>
<div class="nxr-ps-card-b">
<form method="post">
<div class="row">
<div class="col-md-6 form-group"><label>Nombre del pool / campaña</label><input class="form-control" name="campaign_title" maxlength="80" value="<?php echo nxrPoolStudioEsc($cfg['campaign_title']); ?>"></div>
<div class="col-md-6 form-group"><label>Premio destacado</label><select class="form-control" name="featured_prize_id"><option value="0">Automático (Legendario primero)</option><?php foreach($activePrizes as $p){ ?><option value="<?php echo (int)$p['id']; ?>" <?php echo (int)$cfg['featured_prize_id']===(int)$p['id']?'selected':''; ?>><?php echo nxrPoolStudioEsc($p['name']); ?></option><?php } ?></select></div>
</div>
<div class="form-group"><label>Descripción corta</label><input class="form-control" name="campaign_subtitle" maxlength="220" value="<?php echo nxrPoolStudioEsc($cfg['campaign_subtitle']); ?>"></div>
<div class="row"><div class="col-md-6 form-group"><label>Inicio</label><input class="form-control" type="datetime-local" name="campaign_starts_at" value="<?php echo nxrPoolStudioEsc($cfg['campaign_starts_at']); ?>"></div><div class="col-md-6 form-group"><label>Fin</label><input class="form-control" type="datetime-local" name="campaign_ends_at" value="<?php echo nxrPoolStudioEsc($cfg['campaign_ends_at']); ?>"></div></div>
<div class="row"><div class="col-md-4 form-group"><label>Modo por defecto</label><select class="form-control" name="default_spin_mode"><option value="cinematic" <?php echo $cfg['default_spin_mode']==='cinematic'?'selected':''; ?>>Cinemático</option><option value="quick" <?php echo $cfg['default_spin_mode']==='quick'?'selected':''; ?>>Rápido</option></select></div><div class="col-md-4 form-group"><label>Duración modo rápido (ms)</label><input class="form-control" type="number" min="1200" max="3000" name="quick_spin_ms" value="<?php echo (int)$cfg['quick_spin_ms']; ?>"></div><div class="col-md-4 form-group"><label>Alerta retorno directo máximo (%)</label><input class="form-control" type="number" step="0.1" min="5" max="100" name="max_direct_return_ratio" value="<?php echo nxrPoolStudioEsc(number_format((float)$cfg['max_direct_return_ratio']*100,1,'.','')); ?>"></div></div>
<div class="checkbox"><label><input type="checkbox" name="show_campaign" value="1" <?php echo !empty($cfg['show_campaign'])?'checked':''; ?>> Mostrar campaña y cuenta regresiva</label></div>
<div class="checkbox"><label><input type="checkbox" name="show_featured" value="1" <?php echo !empty($cfg['show_featured'])?'checked':''; ?>> Mostrar premio destacado</label></div>
<div class="checkbox"><label><input type="checkbox" name="show_probability_modal" value="1" <?php echo !empty($cfg['show_probability_modal'])?'checked':''; ?>> Mostrar panel de probabilidades en la ruleta</label></div>
<button class="btn btn-primary" name="save_poolstudio" value="1"><i class="fa fa-save"></i> Guardar Pool Studio</button>
</form>
</div></div>

<div class="nxr-ps-card">
<div class="nxr-ps-card-h"><strong>Pool activo · arrastra para ordenar</strong><span><?php echo count($activePrizes); ?> premios</span></div>
<div class="nxr-ps-card-b table-responsive">
<form method="post" id="nxrPoolOrderForm"><input type="hidden" name="ordered_ids" id="nxrOrderedIds"><button class="btn btn-default btn-sm" name="save_order" value="1" style="margin-bottom:10px"><i class="fa fa-sort"></i> Guardar orden visual</button></form>
<table class="table table-striped nxr-ps-table" id="nxrPoolTable"><thead><tr><th></th><th>Premio</th><th>Imagen</th><th>Rareza</th><th>Peso</th><th>% real</th><th>Stock diario</th><th>Cuenta/día</th><th>Estado</th><th></th></tr></thead><tbody>
<?php foreach($activePrizes as $p){ $av=$availability[(int)$p['id']]??array(); ?>
<tr draggable="true" data-id="<?php echo (int)$p['id']; ?>"><td><i class="fa fa-bars text-muted"></i></td><td><strong><?php echo nxrPoolStudioEsc($p['name']); ?></strong><br><small>#<?php echo (int)$p['id']; ?></small></td><td><img class="nxr-ps-icon" src="<?php echo nxrPoolStudioEsc(nxrPoolStudioIcon($roulette,$p)); ?>" alt=""></td><td><span class="nxr-ps-rarity"><?php echo nxrPoolStudioEsc($rarityLabels[$p['rarity']]??$p['rarity']); ?></span></td><td><?php echo number_format((int)$p['weight']); ?></td><td><strong><?php echo number_format((float)$p['probability'],2); ?>%</strong></td><td><?php echo (int)($av['global_limit']??0)>0?number_format((int)($av['global_remaining']??0)).' / '.number_format((int)$av['global_limit']):'∞'; ?></td><td><?php echo (int)($av['account_limit']??0)>0?number_format((int)$av['account_limit']):'∞'; ?></td><td><span class="label label-success">Activo</span></td><td><form method="post"><button class="btn btn-default btn-xs" name="duplicate_prize" value="<?php echo (int)$p['id']; ?>" title="Duplicar como inactivo"><i class="fa fa-copy"></i></button></form></td></tr>
<?php } ?>
</tbody></table>
</div></div>

<div class="nxr-ps-card">
<div class="nxr-ps-card-h"><strong>Simulación económica</strong><span>Motor actual + pity + progresión</span></div><div class="nxr-ps-card-b">
<?php $analyticWarn=$expectedRatio!==null && $expectedRatio>(float)$cfg['max_direct_return_ratio']; ?>
<div class="alert <?php echo $analyticWarn?'alert-warning nxr-ps-alert-warn':'alert-success nxr-ps-alert-good'; ?>">Retorno directo analítico actual: <strong><?php echo $expectedRatio===null?'—':number_format($expectedRatio*100,2).'%'; ?></strong> · Umbral del estudio: <?php echo number_format((float)$cfg['max_direct_return_ratio']*100,1); ?>%</div>
<form method="post"><button class="btn btn-warning" name="simulate_100k" value="1"><i class="fa fa-flask"></i> Simular 100.000 giros</button></form>
<?php if(is_array($simulation)){ $warn=(float)$simulation['return_ratio']>(float)$cfg['max_direct_return_ratio']; ?>
<hr><div class="alert <?php echo $warn?'alert-danger':'alert-success'; ?>"><?php echo $warn?'ALERTA: el retorno simulado supera el límite definido.':'Simulación dentro del límite de retorno definido.'; ?></div>
<div class="nxr-ps-sim"><div><small>Giros</small><strong><?php echo number_format((int)$simulation['spins']); ?></strong></div><div><small>Saldo consumido</small><strong><?php echo number_format((int)$simulation['spent']); ?></strong></div><div><small>Saldo retornado</small><strong><?php echo number_format((int)$simulation['wallet_return']); ?></strong></div><div><small>Retorno directo</small><strong><?php echo number_format((float)$simulation['return_ratio']*100,2); ?>%</strong></div><div><small>Fragmentos emitidos</small><strong><?php echo number_format((int)$simulation['fragments']); ?></strong></div><div><small>Giros gratis otorgados</small><strong><?php echo number_format((int)$simulation['free_spins_awarded']); ?></strong></div></div>
<?php } ?>
</div></div>
</div>

<div>
<div class="nxr-ps-card"><div class="nxr-ps-card-h"><strong>Vista previa</strong><span>Sectores simétricos</span></div><div class="nxr-ps-card-b nxr-ps-live"><div class="nxr-ps-wheel"></div><div class="nxr-ps-preview-list" id="nxrPreviewList"><?php foreach($activePrizes as $p){ ?><span><b><?php echo nxrPoolStudioEsc($p['name']); ?></b><em><?php echo number_format((float)$p['probability'],2); ?>%</em></span><?php } ?></div></div></div>
<div class="nxr-ps-card"><div class="nxr-ps-card-h"><strong>Copias del pool</strong><span><?php echo count($cfg['snapshots']); ?>/12</span></div><div class="nxr-ps-card-b"><form method="post" class="form-inline" style="margin-bottom:12px"><input class="form-control" name="snapshot_label" placeholder="Ej. Septiembre v1"><button class="btn btn-info" name="save_snapshot" value="1"><i class="fa fa-camera"></i> Guardar copia</button></form>
<?php if(empty($cfg['snapshots'])){ ?><p class="nxr-ps-muted">Todavía no hay copias guardadas.</p><?php } ?>
<?php foreach($cfg['snapshots'] as $snap){ ?><div class="nxr-ps-snapshot"><div><strong><?php echo nxrPoolStudioEsc($snap['label']); ?></strong><br><small><?php echo nxrPoolStudioEsc($snap['created_at']); ?> · <?php echo count((array)$snap['prizes']); ?> premios</small></div><div><form method="post" style="display:inline"><label style="font-weight:normal;font-size:11px"><input type="checkbox" name="confirm_restore" value="1"> confirmar</label> <button class="btn btn-default btn-xs" name="restore_snapshot" value="<?php echo nxrPoolStudioEsc($snap['id']); ?>">Restaurar</button></form> <form method="post" style="display:inline"><button class="btn btn-danger btn-xs" name="delete_snapshot" value="<?php echo nxrPoolStudioEsc($snap['id']); ?>" onclick="return confirm('¿Eliminar esta copia?')"><i class="fa fa-trash"></i></button></form></div></div><?php } ?>
</div></div>
<div class="nxr-ps-card"><div class="nxr-ps-card-h"><strong>Reglas de publicación</strong></div><div class="nxr-ps-card-b"><p><strong>Stock:</strong> los límites diarios del premio se descuentan con giros reales y se reinician con la ventana diaria del motor.</p><p><strong>Orden:</strong> mover una fila sólo cambia la posición visual. No altera pesos ni probabilidades.</p><p><strong>Copiar premio:</strong> la copia nace inactiva para no modificar el retorno del pool sin revisión.</p><p><strong>Campaña:</strong> las fechas controlan su presentación pública y cuenta regresiva; no cambian por sí mismas el RNG.</p></div></div>
</div>
</div>
<script>
(function(){
 var table=document.getElementById('nxrPoolTable'), hidden=document.getElementById('nxrOrderedIds'), form=document.getElementById('nxrPoolOrderForm'); if(!table||!hidden||!form)return;
 var dragging=null;
 function sync(){hidden.value=Array.prototype.map.call(table.querySelectorAll('tbody tr'),function(r){return r.getAttribute('data-id');}).join(',');}
 sync();
 table.addEventListener('dragstart',function(e){var tr=e.target.closest('tr');if(!tr)return;dragging=tr;tr.classList.add('is-dragging');});
 table.addEventListener('dragend',function(){if(dragging)dragging.classList.remove('is-dragging');dragging=null;sync();});
 table.addEventListener('dragover',function(e){e.preventDefault();if(!dragging)return;var tr=e.target.closest('tr');if(!tr||tr===dragging)return;var box=tr.getBoundingClientRect();var before=e.clientY<box.top+box.height/2;tr.parentNode.insertBefore(dragging,before?tr:tr.nextSibling);});
 form.addEventListener('submit',sync);
})();
</script>
