<?php
declare(strict_types=1);

require_once __DIR__ . '/app/bootstrap.php';

$config = $GLOBALS['IMASTORAGE']['config'];
$db = $GLOBALS['IMASTORAGE']['db'];

$route = $_GET['route'] ?? 'home';
$user = current_user();
$broadcast = null;
if ($user) {
  $broadcast = get_unread_broadcast($db, (int)$user['id']);
}

function render(string $view, array $vars = []): void {
  $user = current_user();
  $broadcast = null;
  if ($user) {
    $db = $GLOBALS['IMASTORAGE']['db'];
    $broadcast = get_unread_broadcast($db, (int)$user['id']);

    // Prevent "crazy" repeated popups: show at most once per session,
    // and mark as read on the server BEFORE rendering.
    if ($broadcast) {
      $shown = $_SESSION['last_broadcast_shown'] ?? null;
      if ((string)$shown === (string)$broadcast['id']) {
        $broadcast = null;
      } else {
        try { mark_broadcast_read($db, (int)$user['id'], (int)$broadcast['id']); } catch (Throwable $e) {}
$_SESSION['last_broadcast_shown'] = (string)$broadcast['id'];
      }
    }
  }
  extract($vars);
  ob_start();
  require __DIR__ . '/app/views/' . $view . '.php';
  $content = ob_get_clean();
  $title = $vars['title'] ?? 'IMAStorage';
  require __DIR__ . '/app/views/layout.php';
}

try {
  switch ($route) {
    case 'home':
      render('home', ['title'=>'IMAStorage', 'user'=>$user]);
      break;

    case 'register':
      if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        require_post(); csrf_verify($_POST['csrf'] ?? null);
        auth_register($db, $_POST['username'] ?? '', $_POST['email'] ?? '', $_POST['password'] ?? '');
        $_SESSION['flash_ok'] = "Cuenta creada. Bienvenido/a.";
        header('Location: index.php?route=files'); exit;
      }
      render('register', ['title'=>'Registro']);
      break;

    case 'login':
      if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        require_post(); csrf_verify($_POST['csrf'] ?? null);
        auth_login($db, $_POST['login'] ?? '', $_POST['password'] ?? '');
        $_SESSION['flash_ok'] = "Sesión iniciada.";
        header('Location: index.php?route=files'); exit;
      }
      render('login', ['title'=>'Entrar']);
      break;

    case 'logout':
      auth_logout();
      header('Location: index.php'); exit;

    case 'profile':
      $me = require_login();
      render('profile', ['title'=>'Perfil', 'user'=>$me]);
      break;

    case 'profile_update':
      $me = require_login();
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      auth_update_profile($db, (int)$me['id'], $_POST['username'] ?? '', $_POST['email'] ?? '');
      auth_refresh_session($db, (int)$me['id']);
      $_SESSION['flash_ok'] = "Perfil actualizado.";
      header('Location: index.php?route=profile'); exit;

    case 'profile_password':
      $me = require_login();
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      auth_change_password($db, (int)$me['id'], $_POST['current'] ?? '', $_POST['new'] ?? '');
      $_SESSION['flash_ok'] = "Contraseña cambiada.";
      header('Location: index.php?route=profile'); exit;

    case 'files':
      $me = require_login();
      if (!(int)$me['can_read']) { throw new Exception("Tu cuenta no tiene permisos de lectura."); }
      $folderId = isset($_GET['folder']) ? (int)$_GET['folder'] : null;
      $folder = get_folder($db, (int)$me['id'], $folderId);
      $crumbs = folder_breadcrumb($db, (int)$me['id'], (int)$folder['id']);
      $listing = list_folder($db, (int)$me['id'], (int)$folder['id']);
      render('files', [
        'title'=>'Mis archivos',
        'user'=>$me,
        'folder'=>$folder,
        'crumbs'=>$crumbs,
        'listing'=>$listing
      ]);
      break;

    case 'folder_create':
      $me = require_login();
      if (!(int)$me['can_write']) throw new Exception("No tienes permisos de escritura.");
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      $parentId = (int)($_POST['parent_id'] ?? 0);
      create_folder($db, (int)$me['id'], $parentId, $_POST['name'] ?? '');
      $_SESSION['flash_ok'] = "Carpeta creada.";
      header('Location: index.php?route=files&folder=' . $parentId); exit;

    case 'folder_rename':
      $me = require_login();
      if (!(int)$me['can_write']) throw new Exception("No tienes permisos de escritura.");
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      rename_folder($db, (int)$me['id'], (int)($_POST['id'] ?? 0), $_POST['name'] ?? '');
      $_SESSION['flash_ok'] = "Carpeta renombrada.";
      header('Location: ' . ($_SERVER['HTTP_REFERER'] ?? 'index.php?route=files')); exit;

    case 'folder_move':
      $me = require_login();
      if (!(int)$me['can_write']) throw new Exception("No tienes permisos de escritura.");
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      $id = (int)($_POST['id'] ?? 0);
      $dest = (int)($_POST['dest'] ?? 0);
      move_folder($db, (int)$me['id'], $id, $dest);
      $_SESSION['flash_ok'] = "Carpeta movida.";
      header('Location: ' . ($_SERVER['HTTP_REFERER'] ?? 'index.php?route=files')); exit;

    case 'folder_delete':
      $me = require_login();
      if (!(int)$me['can_write']) throw new Exception("No tienes permisos de escritura.");
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      delete_folder($db, (int)$me['id'], (int)($_POST['id'] ?? 0));
      $_SESSION['flash_ok'] = "Carpeta borrada.";
      header('Location: index.php?route=files'); exit;

    case 'file_upload':
      $me = require_login();
      if (!(int)$me['can_write']) throw new Exception("No tienes permisos de escritura.");
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      $folderId = (int)($_POST['folder_id'] ?? 0);
      upload_file($db, $config, (int)$me['id'], $folderId, $_FILES['file'] ?? []);
      $_SESSION['flash_ok'] = "Archivo subido.";
      header('Location: index.php?route=files&folder=' . $folderId); exit;

    case 'file_delete':
      $me = require_login();
      if (!(int)$me['can_write']) throw new Exception("No tienes permisos de escritura.");
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      delete_file($db, (int)$me['id'], (int)($_POST['id'] ?? 0));
      $_SESSION['flash_ok'] = "Archivo borrado.";
      header('Location: ' . ($_SERVER['HTTP_REFERER'] ?? 'index.php?route=files')); exit;

    case 'file_rename':
      $me = require_login();
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      rename_file($db, (int)$me['id'], (int)($_POST['id'] ?? 0), $_POST['name'] ?? '');
      $_SESSION['flash_ok'] = "Archivo renombrado.";
      header('Location: ' . ($_SERVER['HTTP_REFERER'] ?? 'index.php?route=files')); exit;

    case 'file_move':
      $me = require_login();
      if (!(int)$me['can_write']) throw new Exception("No tienes permisos de escritura.");
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      move_file($db, (int)$me['id'], (int)($_POST['id'] ?? 0), (int)($_POST['dest'] ?? 0));
      $_SESSION['flash_ok'] = "Archivo movido.";
      header('Location: ' . ($_SERVER['HTTP_REFERER'] ?? 'index.php?route=files')); exit;

    case 'file_preview':
      $me = require_login();
      $id = (int)($_GET['id'] ?? 0);
      if (!user_can_access_file($db,(int)$me['id'],$id,'read')) { http_response_code(403); exit('No autorizado'); }
      $file = get_file($db,$id);
      if (!$file) { http_response_code(404); exit('No encontrado'); }
      render('file_preview', ['title'=>'Vista previa', 'file'=>$file, 'user'=>$me]);
      break;

    case 'file_stream':
      $me = require_login();
      $id = (int)($_GET['id'] ?? 0);
      stream_file($db, $config, (int)$me['id'], $id, false);
      break;

    case 'file_download':
      $me = require_login();
      $id = (int)($_GET['id'] ?? 0);
      stream_file($db, $config, (int)$me['id'], $id, true);
      break;

    case 'file_share':
      $me = require_login();
      $id = (int)($_GET['id'] ?? 0);
      $file = get_file($db,$id);
      if (!$file) throw new Exception("Archivo no encontrado.");
      if ((int)$file['owner_user_id'] !== (int)$me['id']) throw new Exception("Solo el dueño puede compartir.");
      $shares = list_shares_of_my_file($db,(int)$me['id'],$id);
      render('file_share', ['title'=>'Compartir', 'file'=>$file, 'shares'=>$shares, 'user'=>$me]);
      break;

    case 'file_share_save':
      $me = require_login();
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      $fileId = (int)($_POST['file_id'] ?? 0);
      $q = trim($_POST['q'] ?? '');
      $perm = $_POST['perm'] ?? 'read';
      $matches = search_users($db, $q, 1);
      if (empty($matches)) throw new Exception("No se encontró usuario para: " . $q);
      $to = (int)$matches[0]['id'];
      share_file($db, (int)$me['id'], $fileId, $to, $perm);
      $_SESSION['flash_ok'] = "Compartido con " . $matches[0]['username'] . " (" . $perm . ")";
      header('Location: index.php?route=file_share&id=' . $fileId); exit;

    case 'file_share_revoke':
      $me = require_login();
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      $fileId = (int)($_POST['file_id'] ?? 0);
      $toUserId = (int)($_POST['to_user_id'] ?? 0);
      revoke_share($db, (int)$me['id'], $fileId, $toUserId);
      $_SESSION['flash_ok'] = "Acceso revocado.";
      header('Location: index.php?route=file_share&id=' . $fileId); exit;

    case 'shared':
      $me = require_login();
      $shared = list_shared_with_me($db, (int)$me['id']);
      render('shared', ['title'=>'Compartidos', 'shared'=>$shared, 'user'=>$me]);
      break;

    case 'messages':
      $me = require_login();
      $inbox = list_inbox($db,(int)$me['id'],50);
      $sent = list_sent($db,(int)$me['id'],50);
      // mark inbox as read (simple: mark all displayed)
      foreach ($inbox as $m) {
        if (!(int)$m['is_read']) mark_message_read($db,(int)$me['id'], (int)$m['id']);
      }
      render('messages', ['title'=>'Mensajes', 'user'=>$me, 'inbox'=>$inbox, 'sent'=>$sent]);
      break;

    case 'message_send':
      $me = require_login();
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      $to = trim($_POST['to'] ?? '');
      $matches = search_users($db, $to, 1);
      if (empty($matches)) throw new Exception("No se encontró usuario: " . $to);
      send_message($db, (int)$me['id'], (int)$matches[0]['id'], $_POST['body'] ?? '');
      $_SESSION['flash_ok'] = "Mensaje enviado a " . $matches[0]['username'];
      header('Location: index.php?route=messages'); exit;


case 'message_delete':
  $me = require_login();
  require_post(); csrf_verify($_POST['csrf'] ?? null);
  delete_message($db, (int)$me['id'], (int)($_POST['id'] ?? 0));
  $_SESSION['flash_ok'] = "Mensaje borrado.";
  header('Location: ' . ($_SERVER['HTTP_REFERER'] ?? 'index.php?route=messages')); exit;

case 'admin_broadcasts':
  $me = require_admin();
  $broadcasts = list_broadcasts($db, 300);
  render('admin_broadcasts', ['title'=>'Admin Broadcasts', 'user'=>$me, 'me'=>$me, 'broadcasts'=>$broadcasts]);
  break;

case 'admin_broadcast_toggle':
  $me = require_admin();
  require_post(); csrf_verify($_POST['csrf'] ?? null);
  $id = (int)($_POST['id'] ?? 0);
  $active = (int)($_POST['active'] ?? 1) === 1;
  set_broadcast_active($db, $id, $active);
  $_SESSION['flash_ok'] = $active ? "Broadcast reactivado." : "Broadcast anulado.";
  header('Location: index.php?route=admin_broadcasts'); exit;

case 'admin_broadcast_delete':
  $me = require_admin();
  require_post(); csrf_verify($_POST['csrf'] ?? null);
  $id = (int)($_POST['id'] ?? 0);
  delete_broadcast($db, $id);
  $_SESSION['flash_ok'] = "Broadcast eliminado.";
  header('Location: index.php?route=admin_broadcasts'); exit;

    case 'broadcast_send':
      $me = require_admin();
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      admin_broadcast($db, (int)$me['id'], $_POST['title'] ?? '', $_POST['body'] ?? '');
      $_SESSION['flash_ok'] = "Mensaje global enviado.";
      header('Location: index.php?route=messages'); exit;

    case 'broadcast_read':
      $me = require_login();
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      try { mark_broadcast_read($db, (int)$me['id'], (int)($_POST['id'] ?? 0)); } catch (Throwable $e) {}
header('Content-Type: application/json'); echo json_encode(['ok'=>true]); exit;

    case 'admin_users':
      $me = require_admin();
      $users = admin_list_users($db);
      render('admin_users', ['title'=>'Admin Usuarios', 'users'=>$users, 'me'=>$me, 'user'=>$me]);
      break;

    case 'admin_user_create':
      $me = require_admin();
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      admin_create_user($db, $_POST['username'] ?? '', $_POST['email'] ?? '', $_POST['password'] ?? '', $_POST['role'] ?? 'user');
      $_SESSION['flash_ok'] = "Usuario creado.";
      header('Location: index.php?route=admin_users'); exit;

    case 'admin_user_update':
      $me = require_admin();
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      $id = (int)($_POST['id'] ?? 0);
      admin_update_user_perms($db, $id, (int)($_POST['can_read'] ?? 1), (int)($_POST['can_write'] ?? 1), $_POST['role'] ?? 'user');
      if ($id === (int)$me['id']) auth_refresh_session($db, $id);
      $_SESSION['flash_ok'] = "Usuario actualizado.";
      header('Location: index.php?route=admin_users'); exit;

    case 'admin_user_delete':
      $me = require_admin();
      require_post(); csrf_verify($_POST['csrf'] ?? null);
      $id = (int)($_POST['id'] ?? 0);
      if ($id === (int)$me['id']) throw new Exception("No puedes borrarte.");
      admin_delete_user($db, $config, $id);
      $_SESSION['flash_ok'] = "Usuario eliminado.";
      header('Location: index.php?route=admin_users'); exit;

    default:
      http_response_code(404);
      echo "Ruta no encontrada.";
  }
} catch (Throwable $e) {
  $_SESSION['flash_err'] = $e->getMessage();
  $back = $_SERVER['HTTP_REFERER'] ?? 'index.php';
  // Avoid redirect loops on login/register POST
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    header('Location: ' . $back);
    exit;
  }
  render('home', ['title'=>'Error', 'user'=>$user]);
}
