<?php
// =============================================================================
// admin/roleta_salvar.php — salva roleta + assets + segmentos e gera o arquivo
// =============================================================================
declare(strict_types=1);
ini_set('display_errors','1');
error_reporting(E_ALL);

require __DIR__ . '/../db/config.php';          // $pdo (PDO conectado)
require __DIR__ . '/../inc/generator.php';      // function generate_roulette_file(PDO $pdo, int $rouletteId): string

// ----------------- helpers -----------------
/** Garante que um diretório exista. */
function ensure_dir(string $path): void {
  if (!is_dir($path) && !@mkdir($path, 0775, true) && !is_dir($path)) {
    throw new RuntimeException("Falha ao criar diretório: $path");
  }
}

/** Slug simples (para URLs/arquivos). */
function sanitize_slug(string $s): string {
  $s = strtolower(trim($s));
  $s = preg_replace('~[^\p{L}\p{N}\-]+~u', '-', $s);
  $s = preg_replace('~-+~', '-', $s);
  return trim($s, '-');
}

/**
 * Salva upload e retorna caminho RELATIVO à raiz de /public (ex.: uploads/roulette_12/arquivo.ext).
 * Retorna null quando nenhum arquivo foi enviado para o campo informado.
 */
function save_uploaded(string $field, string $subdir, array $allowExt): ?string {
  if (empty($_FILES[$field]) || ($_FILES[$field]['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE) {
    return null;
  }
  $f = $_FILES[$field];
  if (($f['error'] ?? UPLOAD_ERR_OK) !== UPLOAD_ERR_OK) {
    throw new RuntimeException("Upload falhou em $field (código {$f['error']}).");
  }
  $ext = strtolower((string)pathinfo($f['name'], PATHINFO_EXTENSION));
  if (!in_array($ext, $allowExt, true)) {
    throw new RuntimeException("Extensão inválida em $field: .$ext");
  }
  $root = realpath(__DIR__ . '/../public');
  if ($root === false) {
    throw new RuntimeException('Diretório /public inválido');
  }
  $targetDir = $root . '/uploads/' . $subdir;
  ensure_dir($targetDir);

  $base = pathinfo($f['name'], PATHINFO_FILENAME);
  $name = uniqid($base . '_', true) . '.' . $ext;
  $dest = $targetDir . '/' . $name;
  if (!move_uploaded_file($f['tmp_name'], $dest)) {
    throw new RuntimeException("Não foi possível mover o arquivo de $field.");
  }
  return 'uploads/' . $subdir . '/' . $name;
}

/**
 * Apaga um arquivo salvo em /public a partir de seu caminho relativo (ex.: uploads/...).
 * Aceita também caminhos começando por public/ e apenas basenames (nesse caso reconstrói com roulette_id).
 */
function delete_public_file(string $path, int $rid = 0): bool {
  $rel = trim($path);
  if ($rel === '') return false;
  $rel = ltrim($rel, '/');
  // normaliza variações antigas
  $rel = preg_replace('#^public/#i', '', $rel);
  if (stripos($rel, 'uploads/') !== 0) {
    // quando veio só o basename, reconstroi para a pasta da roleta
    if ($rid > 0) $rel = 'uploads/roulette_' . $rid . '/' . basename($rel);
  }
  $absPublic = realpath(__DIR__ . '/../public');
  if ($absPublic === false) return false;
  $abs = $absPublic . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $rel);
  return is_file($abs) ? @unlink($abs) : false;
}

// Função auxiliar para validar cores hexadecimais
function isValidColor(string $color): bool {
    return (bool)preg_match('/^#[0-9A-Fa-f]{6}$/i', $color);
}

// ----------------- coleta de dados principais -----------------
$id                = isset($_POST['id']) ? (int)$_POST['id'] : 0;
$name              = trim($_POST['name'] ?? '');
$slug              = sanitize_slug((string)($_POST['slug'] ?? ''));
$subtitle          = trim($_POST['subtitle'] ?? '');
$is_active         = (int)($_POST['is_active'] ?? 1);
$force_pattern     = (string)($_POST['force_pattern'] ?? 'none');
$anim_spins        = (int)($_POST['anim_spins'] ?? 12);
$anim_speed        = (float)($_POST['anim_speed'] ?? 1.0);
$spin_button_text  = trim($_POST['spin_button_text'] ?? 'GIRAR');
$title_color       = (string)($_POST['title_color'] ?? '#ffffff');
$title_size        = (int)($_POST['title_size'] ?? 30);
$subtitle_color    = (string)($_POST['subtitle_color'] ?? '#eef3ff');
$subtitle_size     = (int)($_POST['subtitle_size'] ?? 16);
$spin_text_color   = (string)($_POST['spin_text_color'] ?? '#ffffff');
$spin_text_size    = (int)($_POST['spin_text_size'] ?? 24);
$spin_button_color = (string)($_POST['spin_button_color'] ?? '#f59e0b');
$pointer_color     = (string)($_POST['pointer_color'] ?? '#A855F7');
$pointer_position  = (string)($_POST['pointer_position'] ?? 'right');
$font_family       = trim((string)($_POST['font_family'] ?? 'Poppins'));
$wheel_scale_pct   = (int)($_POST['wheel_scale_pct'] ?? 100);

// Novos campos para margens e ocultação
$wheel_margin_top_desktop    = (int)($_POST['wheel_margin_top_desktop'] ?? 0);
$wheel_margin_bottom_desktop = (int)($_POST['wheel_margin_bottom_desktop'] ?? 0);
$wheel_margin_top_mobile     = (int)($_POST['wheel_margin_top_mobile'] ?? 0);
$wheel_margin_bottom_mobile  = (int)($_POST['wheel_margin_bottom_mobile'] ?? 0);
$hide_title_mobile           = (int)($_POST['hide_title_mobile'] ?? 0);
$hide_subtitle_mobile        = (int)($_POST['hide_subtitle_mobile'] ?? 0);
$hide_title_desktop          = (int)($_POST['hide_title_desktop'] ?? 0);
$hide_subtitle_desktop       = (int)($_POST['hide_subtitle_desktop'] ?? 0);

// Validar valores máximos das margens
$wheel_margin_top_desktop    = min(250, max(0, $wheel_margin_top_desktop));
$wheel_margin_bottom_desktop = min(250, max(0, $wheel_margin_bottom_desktop));
$wheel_margin_top_mobile     = min(250, max(0, $wheel_margin_top_mobile));
$wheel_margin_bottom_mobile  = min(250, max(0, $wheel_margin_bottom_mobile));

// Novos campos para o aro da roleta
$rim_style        = (string)($_POST['rim_style'] ?? 'gradient');
$rim_light_color  = (string)($_POST['rim_light_color'] ?? '#c3cad6');
$rim_mid_color    = (string)($_POST['rim_mid_color'] ?? '#7b8396');
$rim_dark_color   = (string)($_POST['rim_dark_color'] ?? '#3b4356');
$rim_solid_color  = (string)($_POST['rim_solid_color'] ?? '#3b4356');

$disable_inspect   = (int)($_POST['disable_inspect'] ?? 0);

// Validar cores do aro
if (!isValidColor($rim_light_color)) $rim_light_color = '#c3cad6';
if (!isValidColor($rim_mid_color)) $rim_mid_color = '#7b8396';
if (!isValidColor($rim_dark_color)) $rim_dark_color = '#3b4356';
if (!isValidColor($rim_solid_color)) $rim_solid_color = '#3b4356';
if (!in_array($rim_style, ['gradient', 'solid'])) $rim_style = 'gradient';

// coletores para deleção segura após commit
$SEG_IMAGES_TO_DELETE = [];
$ASSET_FILES_TO_DELETE = [];

$pdo->beginTransaction();

// --------- UPSERT da roleta (inclui novos campos do aro e margens) ---------
if ($id > 0) {
  $sql = "UPDATE roulettes SET
            name=:name, slug=:slug, subtitle=:subtitle,
            is_active=:is_active, force_pattern=:force_pattern,
            anim_spins=:anim_spins, anim_speed=:anim_speed,
            spin_button_text=:spin_button_text,
            title_color=:title_color, title_size=:title_size,
            subtitle_color=:subtitle_color, subtitle_size=:subtitle_size,
            spin_text_color=:spin_text_color, spin_text_size=:spin_text_size,
            spin_button_color=:spin_button_color,
            pointer_color=:pointer_color, pointer_position=:pointer_position,
            font_family=:font_family, wheel_scale_pct=:wheel_scale_pct,
            rim_style=:rim_style, rim_light_color=:rim_light_color,
            rim_mid_color=:rim_mid_color, rim_dark_color=:rim_dark_color,
            rim_solid_color=:rim_solid_color,
            wheel_margin_top_desktop=:wheel_margin_top_desktop,
            wheel_margin_bottom_desktop=:wheel_margin_bottom_desktop,
            wheel_margin_top_mobile=:wheel_margin_top_mobile,
            wheel_margin_bottom_mobile=:wheel_margin_bottom_mobile,
            hide_title_mobile=:hide_title_mobile,
            hide_subtitle_mobile=:hide_subtitle_mobile,
            hide_title_desktop=:hide_title_desktop,
            hide_subtitle_desktop=:hide_subtitle_desktop,
            disable_inspect=:disable_inspect,
            updated_at=CURRENT_TIMESTAMP
          WHERE id=:id";
  $st = $pdo->prepare($sql);
  $st->execute([
    ':name'=>$name, ':slug'=>$slug, ':subtitle'=>$subtitle,
    ':is_active'=>$is_active, ':force_pattern'=>$force_pattern,
    ':anim_spins'=>$anim_spins, ':anim_speed'=>$anim_speed,
    ':spin_button_text'=>$spin_button_text,
    ':title_color'=>$title_color, ':title_size'=>$title_size,
    ':subtitle_color'=>$subtitle_color, ':subtitle_size'=>$subtitle_size,
    ':spin_text_color'=>$spin_text_color, ':spin_text_size'=>$spin_text_size,
    ':spin_button_color'=>$spin_button_color,
    ':pointer_color'=>$pointer_color, ':pointer_position'=>$pointer_position,
    ':font_family'=>$font_family, ':wheel_scale_pct'=>$wheel_scale_pct,
    ':rim_style'=>$rim_style, ':rim_light_color'=>$rim_light_color,
    ':rim_mid_color'=>$rim_mid_color, ':rim_dark_color'=>$rim_dark_color,
    ':rim_solid_color'=>$rim_solid_color,
    ':wheel_margin_top_desktop'=>$wheel_margin_top_desktop,
    ':wheel_margin_bottom_desktop'=>$wheel_margin_bottom_desktop,
    ':wheel_margin_top_mobile'=>$wheel_margin_top_mobile,
    ':wheel_margin_bottom_mobile'=>$wheel_margin_bottom_mobile,
    ':hide_title_mobile'=>$hide_title_mobile,
    ':hide_subtitle_mobile'=>$hide_subtitle_mobile,
    ':hide_title_desktop'=>$hide_title_desktop,
    ':hide_subtitle_desktop'=>$hide_subtitle_desktop,
    ':disable_inspect'=>$disable_inspect,
    ':id'=>$id
  ]);
  $rouletteId = $id;
} else {
  $sql = "INSERT INTO roulettes
            (name, slug, subtitle, is_active, force_pattern,
             anim_spins, anim_speed, spin_button_text,
             title_color, title_size, subtitle_color, subtitle_size,
             spin_text_color, spin_text_size, spin_button_color,
             pointer_color, pointer_position, font_family, wheel_scale_pct,
             rim_style, rim_light_color, rim_mid_color, rim_dark_color, rim_solid_color,
             wheel_margin_top_desktop, wheel_margin_bottom_desktop,
             wheel_margin_top_mobile, wheel_margin_bottom_mobile,
             hide_title_desktop, hide_subtitle_desktop,
             hide_title_mobile, hide_subtitle_mobile,
             disable_inspect,
             created_at, updated_at)
          VALUES
            (:name,:slug,:subtitle,:is_active,:force_pattern,
             :anim_spins,:anim_speed,:spin_button_text,
             :title_color,:title_size,:subtitle_color,:subtitle_size,
             :spin_text_color,:spin_text_size,:spin_button_color,
             :pointer_color,:pointer_position,:font_family,:wheel_scale_pct,
             :rim_style,:rim_light_color,:rim_mid_color,:rim_dark_color,:rim_solid_color,
             :wheel_margin_top_desktop,:wheel_margin_bottom_desktop,
             :wheel_margin_top_mobile,:wheel_margin_bottom_mobile,
             :hide_title_desktop,:hide_subtitle_desktop,
             :hide_title_mobile,:hide_subtitle_mobile,
             :disable_inspect,
             CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)";
  $st = $pdo->prepare($sql);
  $st->execute([
    ':name'=>$name, ':slug'=>$slug, ':subtitle'=>$subtitle,
    ':is_active'=>$is_active, ':force_pattern'=>$force_pattern,
    ':anim_spins'=>$anim_spins, ':anim_speed'=>$anim_speed,
    ':spin_button_text'=>$spin_button_text,
    ':title_color'=>$title_color, ':title_size'=>$title_size,
    ':subtitle_color'=>$subtitle_color, ':subtitle_size'=>$subtitle_size,
    ':spin_text_color'=>$spin_text_color, ':spin_text_size'=>$spin_text_size,
    ':spin_button_color'=>$spin_button_color,
    ':pointer_color'=>$pointer_color, ':pointer_position'=>$pointer_position,
    ':font_family'=>$font_family, ':wheel_scale_pct'=>$wheel_scale_pct,
    ':rim_style'=>$rim_style, ':rim_light_color'=>$rim_light_color,
    ':rim_mid_color'=>$rim_mid_color, ':rim_dark_color'=>$rim_dark_color,
    ':rim_solid_color'=>$rim_solid_color,
    ':wheel_margin_top_desktop'=>$wheel_margin_top_desktop,
    ':wheel_margin_bottom_desktop'=>$wheel_margin_bottom_desktop,
    ':wheel_margin_top_mobile'=>$wheel_margin_top_mobile,
    ':wheel_margin_bottom_mobile'=>$wheel_margin_bottom_mobile,
    ':hide_title_mobile'=>$hide_title_mobile,
    ':hide_subtitle_mobile'=>$hide_subtitle_mobile,
    ':hide_title_desktop'=>$hide_title_desktop,
    ':hide_subtitle_desktop'=>$hide_subtitle_desktop,
    ':disable_inspect'=>$disable_inspect
  ]);
  $rouletteId = (int)$pdo->lastInsertId();
}

// diretório para uploads desta roleta
$subdir = 'roulette_' . $rouletteId;

// --------- Assets (áudios + background) ---------
$assetKeys = [
  'music'      => ['mp3','wav','ogg','m4a'],
  'tick'       => ['mp3','wav','ogg','m4a'],
  'inicio'     => ['mp3','wav','ogg','m4a'],
  'ganhou'     => ['mp3','wav','ogg','m4a'],
  'perdeu'     => ['mp3','wav','ogg','m4a'],
  'background' => ['jpg','jpeg','png','webp'],
  'background_mobile' => ['jpg','jpeg','png','webp']
];

// mapa dos assets atuais (asset_key => file_path)
$oldAssets = [];
$st0 = $pdo->prepare("SELECT asset_key, file_path FROM roulette_assets WHERE roulette_id=?");
$st0->execute([$rouletteId]);
foreach ($st0->fetchAll(PDO::FETCH_ASSOC) as $a) {
  $oldAssets[$a['asset_key']] = $a['file_path'] ?? null;
}

foreach ($assetKeys as $key => $exts) {
  $newPath = save_uploaded($key, $subdir, $exts);      // null se não enviou
  $delFlag = !empty($_POST[$key . '_delete']);         // opcional: se tiver checkbox no form
  $oldPath = $oldAssets[$key] ?? null;

  if ($newPath !== null) {
    // Se veio arquivo novo e havia antigo diferente → agendar deleção
    if ($oldPath && $oldPath !== $newPath) {
      $ASSET_FILES_TO_DELETE[] = ['path'=>$oldPath, 'rid'=>$rouletteId];
    }
    // Upsert com novo caminho
    $stA = $pdo->prepare("
      INSERT INTO roulette_assets (roulette_id, asset_key, file_path)
      VALUES (:rid, :k, :p)
      ON DUPLICATE KEY UPDATE file_path = VALUES(file_path)
    ");
    $stA->execute([':rid'=>$rouletteId, ':k'=>$key, ':p'=>$newPath]);

  } elseif ($delFlag && $oldPath) {
    // Excluir manualmente sem novo upload
    $ASSET_FILES_TO_DELETE[] = ['path'=>$oldPath, 'rid'=>$rouletteId];
    $stA = $pdo->prepare("UPDATE roulette_assets SET file_path = NULL WHERE roulette_id=:rid AND asset_key=:k");
    $stA->execute([':rid'=>$rouletteId, ':k'=>$key]);
  }
}

// --------- Segmentos ---------
$postedSegments = $_POST['segments'] ?? [];
$keepIds = [];

// ids existentes (para exclusão posterior)
$stE = $pdo->prepare("SELECT id FROM roulette_segments WHERE roulette_id=?");
$stE->execute([$rouletteId]);
$existingIds = array_map('intval', $stE->fetchAll(PDO::FETCH_COLUMN) ?: []);

foreach ($postedSegments as $i => $seg) {
  $segId  = (int)($seg['id'] ?? 0);
  $order  = (int)($seg['segment_order'] ?? ($i + 1));
  $type   = strtoupper(trim((string)($seg['type'] ?? 'LOSE')));

  $labelP = trim((string)($seg['label_primary'] ?? ''));
  $labelU = trim((string)($seg['label_unit'] ?? ''));
  $spinCt = (int)($seg['spin_count'] ?? 0);
  $color  = (string)($seg['color'] ?? '#ffffff');
  $weight = (int)($seg['weight'] ?? 0);
  $game   = trim((string)($seg['game_name'] ?? ''));
  $url    = trim((string)($seg['game_url'] ?? ''));

  $text_color     = (string)($seg['text_color'] ?? '#ffffff');
  $text_size      = (int)($seg['text_size'] ?? 24);
  $unit_text_size = (int)($seg['unit_text_size'] ?? 13);
  
  // NOVO CAMPO: hide_text_all
  $hide_text_all  = (int)($seg['hide_text_all'] ?? 0);

  // IMAGEM -------------------------------------------------------
  $existingPath = trim((string)($seg['image_path_existing'] ?? ''));
  $deleteFlag   = (int)($seg['image_delete'] ?? 0) === 1;
  $pathImg      = null;

  // Reembala $_FILES['segments'][i]['image_file']
  if (!empty($_FILES['segments']) && isset($_FILES['segments']['name'][$i]['image_file'])) {
    $tmp = [
      'name'     => $_FILES['segments']['name'][$i]['image_file'],
      'type'     => $_FILES['segments']['type'][$i]['image_file'],
      'tmp_name' => $_FILES['segments']['tmp_name'][$i]['image_file'],
      'error'    => $_FILES['segments']['error'][$i]['image_file'],
      'size'     => $_FILES['segments']['size'][$i]['image_file'],
    ];
    $key = "__seg_$i";
    $_FILES[$key] = $tmp;
    $pathImg = save_uploaded($key, $subdir, ['jpg','jpeg','png','webp']);
    unset($_FILES[$key]);

    // Trocou a imagem? agendar exclusão da antiga
    if ($pathImg && $existingPath && $pathImg !== $existingPath) {
      $SEG_IMAGES_TO_DELETE[] = ['path'=>$existingPath, 'rid'=>$rouletteId];
    }
  }

  // Exclusão manual marcada
  if ($deleteFlag && $existingPath) {
    $SEG_IMAGES_TO_DELETE[] = ['path'=>$existingPath, 'rid'=>$rouletteId];
    $existingPath = '';
  }

  if ($pathImg === null) {
    // mantém a existente (se não foi removida)
    $pathImg = ($existingPath !== '') ? $existingPath : null;
  }
  // -------------------------------------------------------------

  if ($segId > 0) {
    $sql = "UPDATE roulette_segments SET
              segment_order=:ord, type=:type, label_primary=:lp, label_unit=:lu,
              spin_count=:spins, color=:color, weight=:weight,
              game_name=:game, game_url=:url,
              image_path=:img, image_fit=:fit, image_opacity=:opac,
              text_color=:text_color, text_size=:text_size, unit_text_size=:unit_text_size,
              hide_text_all=:hide_text_all
            WHERE id=:id AND roulette_id=:rid";
    $stS = $pdo->prepare($sql);
    $stS->execute([
      ':ord'=>$order, ':type'=>$type, ':lp'=>$labelP, ':lu'=>$labelU,
      ':spins'=>$spinCt, ':color'=>$color, ':weight'=>$weight,
      ':game'=>$game, ':url'=>$url,
      ':img'=>$pathImg, ':fit'=>($seg['image_fit'] ?? 'cover'),
      ':opac'=>(int)($seg['image_opacity'] ?? 95),
      ':text_color'=>$text_color, ':text_size'=>$text_size, ':unit_text_size'=>$unit_text_size,
      ':hide_text_all'=>$hide_text_all,
      ':id'=>$segId, ':rid'=>$rouletteId
    ]);
    $keepIds[] = $segId;
  } else {
    $sql = "INSERT INTO roulette_segments
              (roulette_id, segment_order, type, label_primary, label_unit, spin_count,
               color, weight, game_name, game_url,
               image_path, image_fit, image_opacity,
               text_color, text_size, unit_text_size, hide_text_all)
            VALUES
              (:rid, :ord, :type, :lp, :lu, :spins,
               :color, :weight, :game, :url,
               :img, :fit, :opac,
               :text_color, :text_size, :unit_text_size, :hide_text_all)";
    $stS = $pdo->prepare($sql);
    $stS->execute([
      ':rid'=>$rouletteId, ':ord'=>$order, ':type'=>$type, ':lp'=>$labelP, ':lu'=>$labelU, ':spins'=>$spinCt,
      ':color'=>$color, ':weight'=>$weight, ':game'=>$game, ':url'=>$url,
      ':img'=>$pathImg, ':fit'=>($seg['image_fit'] ?? 'cover'),
      ':opac'=>(int)($seg['image_opacity'] ?? 95),
      ':text_color'=>$text_color, ':text_size'=>$text_size, ':unit_text_size'=>$unit_text_size,
      ':hide_text_all'=>$hide_text_all
    ]);
    $keepIds[] = (int)$pdo->lastInsertId();
  }
}

// remove segmentos não enviados (apagar arquivos antes de deletar rows)
if ($existingIds) {
  $toDelete = array_diff($existingIds, $keepIds);
  if ($toDelete) {
    $in = implode(',', array_map('intval', $toDelete));

    // buscar caminhos para agendar deleção
    $rows = $pdo->query("SELECT id, image_path FROM roulette_segments WHERE roulette_id={$rouletteId} AND id IN ($in)")
                ->fetchAll(PDO::FETCH_ASSOC);
    foreach ($rows as $r) {
      if (!empty($r['image_path'])) {
        $SEG_IMAGES_TO_DELETE[] = ['path'=>$r['image_path'], 'rid'=>$rouletteId];
      }
    }
    // apagar linhas
    $pdo->exec("DELETE FROM roulette_segments WHERE roulette_id={$rouletteId} AND id IN ($in)");
  }
}

$pdo->commit();

// ------- deleção física no disco (somente após commit bem-sucedido) -------
if (!empty($SEG_IMAGES_TO_DELETE)) {
  foreach ($SEG_IMAGES_TO_DELETE as $it) {
    delete_public_file((string)$it['path'], (int)$it['rid']);
  }
}
if (!empty($ASSET_FILES_TO_DELETE)) {
  foreach ($ASSET_FILES_TO_DELETE as $it) {
    delete_public_file((string)$it['path'], (int)$it['rid']);
  }
}

// gera o arquivo público (normaliza caminhos dentro do template)
$outfile = generate_roulette_file($pdo, $rouletteId);

// redireciona de volta para edição
header('Location: nova_roleta.php?id=' . $rouletteId);
exit;