<?php
function nxrExchangeImageDir() {
    return __PATH_TEMPLATE_ROOT__ . 'img/nexoraroulette/exchange/';
}
function nxrExchangeStoreImage($file) {
    if(!is_array($file)) return '';
    $error=isset($file['error'])?(int)$file['error']:UPLOAD_ERR_NO_FILE;
    $tmp=isset($file['tmp_name'])?trim((string)$file['tmp_name']):'';
    $name=isset($file['name'])?trim((string)$file['name']):'';
    if($error===UPLOAD_ERR_NO_FILE || $tmp==='' || $name==='') return '';
    if($error!==UPLOAD_ERR_OK) throw new Exception('La imagen personalizada no pudo cargarse. Código: '.$error);
    if((int)$file['size']<1 || (int)$file['size']>5*1024*1024) throw new Exception('La imagen personalizada debe pesar menos de 5 MB.');
    if(!is_uploaded_file($tmp)) throw new Exception('La carga de imagen personalizada no es válida.');
    $info=@getimagesize($tmp);
    $map=array('image/jpeg'=>'jpg','image/png'=>'png','image/webp'=>'webp');
    $mime=is_array($info)?strtolower((string)($info['mime']??'')):'';
    if(!$info || !isset($map[$mime])) throw new Exception('Formatos permitidos para la imagen: JPG, PNG y WebP.');
    if((int)$info[0]<1 || (int)$info[1]<1 || (int)$info[0]>4096 || (int)$info[1]>4096) throw new Exception('Dimensiones máximas para la imagen: 4096 × 4096 px.');
    $dir=nxrExchangeImageDir();
    if(!is_dir($dir) && !@mkdir($dir,0755,true)) throw new Exception('No se pudo crear la carpeta de imágenes del catálogo.');
    if(!is_writable($dir)) throw new Exception('La carpeta de imágenes del catálogo no tiene permisos de escritura.');
    $filename='reward-'.date('YmdHis').'-'.bin2hex(random_bytes(4)).'.'.$map[$mime];
    if(!@move_uploaded_file($tmp,$dir.$filename)) throw new Exception('No se pudo guardar la imagen personalizada.');
    @chmod($dir.$filename,0644);
    return $filename;
}
function nxrExchangeDeleteImage($filename) {
    $filename=basename(trim((string)$filename));
    if($filename==='') return;
    $path=nxrExchangeImageDir().$filename;
    if(is_file($path)) @unlink($path);
}
$roulette=new \Plugin\NexoraRoulette\NexoraRoulette();

if(isset($_POST['save_exchange_settings'])) {
    try {
        $roulette->saveExchangeSettings($_POST);
        message('success','Configuración del canje guardada para '.$roulette->getRealmLabel().'.');
    } catch(Throwable $e) { message('error',$e->getMessage()); }
}

if(isset($_POST['save_exchange_reward'])) {
    try {
        $previousImage=trim((string)($_POST['current_image_file']??''));
        $imageFile=$previousImage;
        if(!empty($_POST['remove_custom_image'])) {
            nxrExchangeDeleteImage($previousImage);
            $imageFile='';
        }
        if(isset($_FILES['custom_image'])) {
            $uploaded=nxrExchangeStoreImage($_FILES['custom_image']);
            if($uploaded!=='') {
                if($previousImage!=='' && $previousImage!==$uploaded) nxrExchangeDeleteImage($previousImage);
                $imageFile=$uploaded;
            }
        }
        $_POST['image_file']=$imageFile;
        $id=$roulette->saveExchangeReward($_POST);
        message('success','Recompensa de canje #'.$id.' guardada.');
    } catch(Throwable $e) { message('error',$e->getMessage()); }
}

if(isset($_POST['retire_exchange_id'])) {
    try {
        $roulette->retireExchangeReward((int)$_POST['retire_exchange_id']);
        message('success','Recompensa retirada del catálogo. Los canjes anteriores permanecen protegidos.');
    } catch(Throwable $e) { message('error',$e->getMessage()); }
}

if(isset($_POST['deliver_exchange_manual'])) {
    try {
        $roulette->markExchangeManualDelivered((int)$_POST['deliver_exchange_manual'],(string)($_POST['admin_note']??''));
        message('success','Canje manual marcado como entregado.');
    } catch(Throwable $e) { message('error',$e->getMessage()); }
}

$edit=null;
if(isset($_GET['edit'])) $edit=$roulette->getExchangeReward((int)$_GET['edit']);
$settings=$roulette->exchangeSettings();
$types=\Plugin\NexoraRoulette\NexoraRoulette::exchangeTypeLabels();
$credits=$roulette->creditConfigs();
$items=$roulette->itemshopItems();
$rewards=$roulette->getExchangeRewards(false);
$usage=$roulette->exchangeUsage();
$history=$roulette->exchangeHistory(100);
$itemNames=array();
foreach($items as $item) $itemNames[(int)$item['id']]=(string)$item['name'];
$defaults=array(
    'id'=>0,'name'=>'','description'=>'','reward_type'=>'credits','fragment_cost'=>50,'amount'=>0,
    'credit_config_id'=>0,'item_id'=>0,'image_file'=>'','global_limit'=>0,'account_limit'=>0,'active'=>1,'sort_order'=>100,
);
$f=is_array($edit)?array_merge($defaults,$edit):$defaults;
$statusLabels=array(
    'credited'=>'Acreditado','pending_item'=>'Pendiente de Arsenal','claimed'=>'Entregado al baúl',
    'pending_manual'=>'Pendiente de staff','manual_delivered'=>'Entrega manual completada',
);
?>
<style>
.nxr-exchange-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-bottom:18px}.nxr-exchange-summary .panel{margin:0;min-height:108px}.nxr-exchange-summary small{display:block;color:#777;text-transform:uppercase;letter-spacing:.08em;font-size:10px}.nxr-exchange-summary h3{margin:7px 0 3px}.nxr-exchange-cost{font-size:18px;font-weight:700;color:#8a681e}.nxr-stock-ok{color:#2c8a55}.nxr-stock-low{color:#c27b16}.nxr-stock-out{color:#b13a3a}.nxr-exchange-help{background:#f7f8fa;border:1px solid #e4e7eb;border-radius:5px;padding:12px;margin-bottom:15px}.nxr-type-chip{display:inline-block;padding:3px 7px;border-radius:9px;background:#eef1f5;font-size:11px;font-weight:600}.nxr-fragment-mark{color:#a77a17;font-weight:800}.nxr-custom-image-current,.nxr-custom-image-preview{margin-top:10px;display:flex;align-items:center;gap:12px;padding:10px;border:1px solid #e6e8ec;border-radius:6px;background:#fafbfc}.nxr-custom-image-current img,.nxr-custom-image-preview img{width:92px;height:92px;object-fit:contain;border-radius:6px;background:#11151b;padding:6px}@media(max-width:1000px){.nxr-exchange-summary{grid-template-columns:repeat(2,1fr)}}
</style>
<h1 class="page-header">Canje de Fragmentos <small><?php echo htmlspecialchars($roulette->getRealmLabel(),ENT_QUOTES,'UTF-8'); ?></small></h1>
<div class="alert alert-info"><strong>Separación económica:</strong> los Fragmentos NXR se generan por progresión y se consumen aquí. Un canje confirmado crea una referencia auditable; los ítems de Arsenal usan entrega idempotente para que un reintento no pueda duplicar el premio.</div>

<?php
$totalCatalog=count($rewards); $activeCatalog=0; $globalRedemptions=0; $spentFragments=0;
foreach($rewards as $r){ if((int)$r['active']===1)$activeCatalog++; $globalRedemptions+=(int)($usage['global'][(int)$r['id']]??0); }
foreach($history as $row) $spentFragments+=(int)$row['fragment_cost'];
?>
<div class="nxr-exchange-summary">
<div class="panel panel-default"><div class="panel-body"><small>Catálogo</small><h3><?php echo number_format($activeCatalog); ?></h3><span><?php echo number_format($totalCatalog); ?> configuradas</span></div></div>
<div class="panel panel-default"><div class="panel-body"><small>Canjes visibles en muestra</small><h3><?php echo number_format(count($history)); ?></h3><span>Últimos 100 registros</span></div></div>
<div class="panel panel-default"><div class="panel-body"><small>Fragmentos consumidos</small><h3><?php echo number_format($spentFragments); ?> ◆</h3><span>Últimos 100 canjes</span></div></div>
<div class="panel panel-<?php echo !empty($settings['exchange_enabled'])?'success':'default'; ?>"><div class="panel-body"><small>Estado público</small><h3><?php echo !empty($settings['exchange_enabled'])?'Activo':'Pausado'; ?></h3><span><?php echo !empty($settings['show_exchange'])?'Visible al jugador':'Oculto en /roulette'; ?></span></div></div>
</div>

<form method="post">
<div class="panel panel-primary">
<div class="panel-heading"><strong>Disponibilidad del sistema</strong></div>
<div class="panel-body">
<div class="row">
<div class="col-md-4">
<div class="checkbox"><label><input type="checkbox" name="exchange_enabled" value="1" <?php echo !empty($settings['exchange_enabled'])?'checked':''; ?>> Activar canje de Fragmentos</label></div>
<div class="checkbox"><label><input type="checkbox" name="show_exchange" value="1" <?php echo !empty($settings['show_exchange'])?'checked':''; ?>> Mostrar catálogo en la ruleta</label></div>
</div>
<div class="col-md-4"><div class="form-group"><label>Título público</label><input class="form-control" name="exchange_title" maxlength="120" value="<?php echo htmlspecialchars($settings['exchange_title'],ENT_QUOTES,'UTF-8'); ?>"></div></div>
<div class="col-md-4"><div class="form-group"><label>Descripción pública</label><textarea class="form-control" name="exchange_description" rows="2" maxlength="500"><?php echo htmlspecialchars($settings['exchange_description'],ENT_QUOTES,'UTF-8'); ?></textarea></div></div>
</div>
</div>
<div class="panel-footer"><button type="submit" class="btn btn-success" name="save_exchange_settings" value="1"><i class="fa fa-save"></i> Guardar disponibilidad</button></div>
</div>
</form>

<div class="row">
<div class="col-lg-5">
<div class="panel panel-warning">
<div class="panel-heading"><strong><?php echo (int)$f['id']>0?'Editar recompensa #'.(int)$f['id']:'Nueva recompensa de canje'; ?></strong></div>
<div class="panel-body">
<form method="post" enctype="multipart/form-data" id="nxrExchangeRewardForm">
<input type="hidden" name="id" value="<?php echo (int)$f['id']; ?>">
<input type="hidden" name="current_image_file" value="<?php echo htmlspecialchars((string)$f['image_file'],ENT_QUOTES,'UTF-8'); ?>">
<div class="form-group"><label>Nombre visible</label><input class="form-control" name="name" maxlength="120" required value="<?php echo htmlspecialchars($f['name'],ENT_QUOTES,'UTF-8'); ?>"></div>
<div class="form-group"><label>Descripción</label><textarea class="form-control" name="description" maxlength="400" rows="2"><?php echo htmlspecialchars($f['description'],ENT_QUOTES,'UTF-8'); ?></textarea></div>
<div class="form-group">
<label>Imagen personalizada del catálogo</label>
<input type="file" class="form-control" name="custom_image" id="nxrExchangeCustomImage" accept="image/png,image/jpeg,image/webp">
<span class="help-block">Opcional. JPG, PNG o WebP · máximo 5 MB · 4096 × 4096 px. Si existe, tendrá prioridad sobre la imagen automática de Arsenal.</span>
<?php if(trim((string)$f['image_file'])!=='') { ?>
<div class="nxr-custom-image-current">
<img src="<?php echo htmlspecialchars(__PATH_TEMPLATE__.'img/nexoraroulette/exchange/'.basename((string)$f['image_file']),ENT_QUOTES,'UTF-8'); ?>" alt="Vista previa">
<label class="checkbox-inline"><input type="checkbox" name="remove_custom_image" value="1"> Eliminar imagen personalizada</label>
</div>
<?php } ?>
<div id="nxrExchangeCustomImagePreview" class="nxr-custom-image-preview" style="display:none"><img alt="Vista previa nueva"></div>
</div>
<div class="row">
<div class="col-sm-6"><div class="form-group"><label>Tipo de entrega</label><select class="form-control" name="reward_type" id="nxrExchangeRewardType"><?php foreach($types as $key=>$label){ ?><option value="<?php echo $key; ?>" <?php echo $f['reward_type']===$key?'selected':''; ?>><?php echo htmlspecialchars($label,ENT_QUOTES,'UTF-8'); ?></option><?php } ?></select></div></div>
<div class="col-sm-6"><div class="form-group"><label>Costo en Fragmentos</label><div class="input-group"><input type="number" min="1" max="1000000000" class="form-control" name="fragment_cost" value="<?php echo (int)$f['fragment_cost']; ?>"><span class="input-group-addon">◆</span></div></div></div>
</div>
<div id="nxrExchangeCreditsFields"><div class="form-group"><label>Moneda a acreditar</label><select class="form-control" name="credit_config_id"><option value="0">— Seleccionar —</option><?php foreach($credits as $cfg){ ?><option value="<?php echo (int)$cfg['config_id']; ?>" <?php echo (int)$f['credit_config_id']===(int)$cfg['config_id']?'selected':''; ?>>#<?php echo (int)$cfg['config_id']; ?> · <?php echo htmlspecialchars($cfg['config_title'],ENT_QUOTES,'UTF-8'); ?></option><?php } ?></select></div></div>
<div id="nxrExchangeAmountFields"><div class="form-group"><label>Cantidad entregada</label><input type="number" min="0" class="form-control" name="amount" value="<?php echo (int)$f['amount']; ?>"><span class="help-block">Saldo o cantidad de giros, según el tipo seleccionado.</span></div></div>
<div id="nxrExchangeItemFields">
<div class="form-group"><label>Buscar en Arsenal</label><input type="text" class="form-control" id="nxrExchangeItemFilter" placeholder="Nombre, sección o ID"></div>
<div class="form-group"><label>Ítem de Arsenal</label><select class="form-control" size="7" name="item_id" id="nxrExchangeItemSelect"><option value="0">— Seleccionar —</option><?php foreach($items as $item){ $label='#'.(int)$item['id'].' · '.(string)$item['name'].' · '.$item['item_section'].':'.$item['item_index']; ?><option value="<?php echo (int)$item['id']; ?>" data-search="<?php echo htmlspecialchars(mb_strtolower($label),ENT_QUOTES,'UTF-8'); ?>" <?php echo (int)$f['item_id']===(int)$item['id']?'selected':''; ?>><?php echo htmlspecialchars($label,ENT_QUOTES,'UTF-8'); ?></option><?php } ?></select><span class="help-block">El canje reserva una referencia única. Si la cuenta está conectada, la entrega queda pendiente hasta que el jugador reclame.</span></div>
</div>
<hr>
<div class="row">
<div class="col-sm-6"><div class="form-group"><label>Stock global</label><input type="number" min="0" class="form-control" name="global_limit" value="<?php echo (int)$f['global_limit']; ?>"><span class="help-block">0 = ilimitado.</span></div></div>
<div class="col-sm-6"><div class="form-group"><label>Límite por cuenta</label><input type="number" min="0" class="form-control" name="account_limit" value="<?php echo (int)$f['account_limit']; ?>"><span class="help-block">0 = ilimitado.</span></div></div>
</div>
<div class="row"><div class="col-sm-6"><div class="form-group"><label>Orden visual</label><input type="number" class="form-control" name="sort_order" value="<?php echo (int)$f['sort_order']; ?>"></div></div><div class="col-sm-6"><div class="checkbox" style="margin-top:28px"><label><input type="checkbox" name="active" value="1" <?php echo !empty($f['active'])?'checked':''; ?>> Recompensa activa</label></div></div></div>
<button type="submit" class="btn btn-success" name="save_exchange_reward" value="1"><i class="fa fa-save"></i> Guardar recompensa</button>
<?php if((int)$f['id']>0){ ?><a class="btn btn-default" href="<?php echo admincp_base('nexoraroulette&page=exchange'); ?>">Cancelar edición</a><?php } ?>
</form>
</div>
</div>
</div>

<div class="col-lg-7">
<div class="panel panel-default"><div class="panel-heading"><strong>Catálogo configurado</strong></div><div class="table-responsive"><table class="table table-striped table-hover" style="margin:0"><thead><tr><th>Recompensa</th><th>Costo</th><th>Entrega</th><th>Uso</th><th>Estado</th><th></th></tr></thead><tbody>
<?php if(!$rewards){ ?><tr><td colspan="6" class="text-muted">Todavía no hay recompensas de canje.</td></tr><?php } ?>
<?php foreach($rewards as $r){
    $used=(int)($usage['global'][(int)$r['id']]??0); $limit=(int)$r['global_limit']; $remaining=$limit>0?max(0,$limit-$used):null;
    $detail=''; if($r['reward_type']==='credits')$detail=number_format((int)$r['amount']).' créditos'; elseif($r['reward_type']==='free_spins')$detail=number_format((int)$r['amount']).' giro(s)'; elseif($r['reward_type']==='itemshop')$detail=$itemNames[(int)$r['item_id']]??('Ítem #'.(int)$r['item_id']); else $detail='Entrega staff';
?>
<tr>
<td><div style="display:flex;align-items:center;gap:10px"><?php if(trim((string)($r['image_file']??''))!==''){ ?><img src="<?php echo htmlspecialchars(__PATH_TEMPLATE__.'img/nexoraroulette/exchange/'.basename((string)$r['image_file']),ENT_QUOTES,'UTF-8'); ?>" alt="" style="width:42px;height:42px;object-fit:contain;border-radius:5px;background:#11151b;padding:3px"><?php } ?><div><strong><?php echo htmlspecialchars($r['name'],ENT_QUOTES,'UTF-8'); ?></strong><br><small>#<?php echo (int)$r['id']; ?> · orden <?php echo (int)$r['sort_order']; ?><?php echo trim((string)($r['image_file']??''))!==''?' · imagen propia':''; ?></small></div></div></td>
<td><span class="nxr-exchange-cost"><?php echo number_format((int)$r['fragment_cost']); ?> ◆</span></td>
<td><span class="nxr-type-chip"><?php echo htmlspecialchars($types[$r['reward_type']]??$r['reward_type'],ENT_QUOTES,'UTF-8'); ?></span><br><small><?php echo htmlspecialchars($detail,ENT_QUOTES,'UTF-8'); ?></small></td>
<td><small>Canjes: <?php echo number_format($used); ?><br>Stock: <?php echo $limit>0?number_format($remaining).' / '.number_format($limit):'Ilimitado'; ?><br>Cuenta: <?php echo (int)$r['account_limit']>0?'máx. '.number_format((int)$r['account_limit']):'Ilimitado'; ?></small></td>
<td><?php echo (int)$r['active']===1?'<span class="label label-success">Activa</span>':'<span class="label label-default">Retirada</span>'; ?><?php if($remaining!==null&&$remaining===0){ ?> <span class="label label-danger">Agotada</span><?php } ?></td>
<td style="white-space:nowrap"><a class="btn btn-xs btn-primary" href="<?php echo admincp_base('nexoraroulette&page=exchange&edit='.(int)$r['id']); ?>">Editar</a> <?php if((int)$r['active']===1){ ?><form method="post" style="display:inline"><button class="btn btn-xs btn-danger" name="retire_exchange_id" value="<?php echo (int)$r['id']; ?>" onclick="return confirm('¿Retirar esta recompensa del catálogo? Los canjes ya registrados no se perderán.');">Retirar</button></form><?php } ?></td>
</tr>
<?php } ?>
</tbody></table></div></div>
</div>
</div>

<div class="panel panel-default">
<div class="panel-heading"><strong>Últimos 100 canjes</strong></div>
<div class="table-responsive"><table class="table table-striped table-hover" style="margin:0"><thead><tr><th>ID</th><th>Cuenta</th><th>Recompensa</th><th>Fragmentos</th><th>Estado</th><th>Fecha</th><th>Operación</th></tr></thead><tbody>
<?php if(!$history){ ?><tr><td colspan="7" class="text-muted">Aún no existen canjes en este reino.</td></tr><?php } ?>
<?php foreach($history as $row){ ?>
<tr>
<td>#<?php echo (int)$row['id']; ?></td>
<td><strong><?php echo htmlspecialchars($row['account_username'],ENT_QUOTES,'UTF-8'); ?></strong><br><small>UID <?php echo (int)$row['user_id']; ?></small></td>
<td><strong><?php echo htmlspecialchars($row['reward_name'],ENT_QUOTES,'UTF-8'); ?></strong><br><small><?php echo htmlspecialchars($types[$row['reward_type']]??$row['reward_type'],ENT_QUOTES,'UTF-8'); ?></small></td>
<td><strong>-<?php echo number_format((int)$row['fragment_cost']); ?> ◆</strong><br><small><?php echo number_format((int)$row['fragments_before']); ?> → <?php echo number_format((int)$row['fragments_after']); ?></small></td>
<td><?php $st=(string)$row['status']; $cls=in_array($st,array('credited','claimed','manual_delivered'),true)?'success':(strpos($st,'pending')===0?'warning':'default'); ?><span class="label label-<?php echo $cls; ?>"><?php echo htmlspecialchars($statusLabels[$st]??$st,ENT_QUOTES,'UTF-8'); ?></span></td>
<td><small><?php echo htmlspecialchars((string)$row['created_at'],ENT_QUOTES,'UTF-8'); ?></small></td>
<td><?php if($row['status']==='pending_manual'){ ?><form method="post" class="form-inline"><input type="text" class="form-control input-sm" name="admin_note" maxlength="500" placeholder="Nota de entrega"><button type="submit" class="btn btn-xs btn-success" name="deliver_exchange_manual" value="<?php echo (int)$row['id']; ?>" onclick="return confirm('¿Confirmar entrega manual de este canje?');">Marcar entregado</button></form><?php } elseif($row['status']==='pending_item'){ ?><small class="text-warning">El jugador debe reclamar al desconectarse.</small><?php } else { ?><small class="text-muted">Sin acción</small><?php } ?></td>
</tr>
<?php } ?>
</tbody></table></div>
</div>

<div class="nxr-exchange-help"><strong>Regla de operación:</strong> nunca reutilices el mismo premio cambiando su significado después de que haya recibido canjes. Si quieres cambiar una recompensa de forma sustancial, retírala y crea una nueva; el historial mantiene nombre, costo, tipo e IDs usados en el momento de la redención.</div>
<script>
(function(){
var type=document.getElementById('nxrExchangeRewardType'),credits=document.getElementById('nxrExchangeCreditsFields'),amount=document.getElementById('nxrExchangeAmountFields'),items=document.getElementById('nxrExchangeItemFields');
function sync(){if(!type)return;var v=type.value;if(credits)credits.style.display=v==='credits'?'block':'none';if(amount)amount.style.display=(v==='credits'||v==='free_spins')?'block':'none';if(items)items.style.display=v==='itemshop'?'block':'none';}
if(type){type.addEventListener('change',sync);sync();}
var filter=document.getElementById('nxrExchangeItemFilter'),select=document.getElementById('nxrExchangeItemSelect');
if(filter&&select)filter.addEventListener('input',function(){var q=this.value.toLowerCase().trim();Array.prototype.forEach.call(select.options,function(o,i){if(i===0)return;o.hidden=q!==''&&(o.getAttribute('data-search')||'').indexOf(q)===-1;});});
var imageInput=document.getElementById('nxrExchangeCustomImage'),preview=document.getElementById('nxrExchangeCustomImagePreview');
if(imageInput&&preview){imageInput.addEventListener('change',function(){var file=this.files&&this.files[0];if(!file){preview.style.display='none';return;}var reader=new FileReader();reader.onload=function(e){var img=preview.querySelector('img');if(img)img.src=e.target.result;preview.style.display='flex';};reader.readAsDataURL(file);});}
})();
</script>
