<?php
session_start();

define('PASSWORD',    'password');
define('FILES_DIR',   __DIR__ . '/avj2305');
define('ACTIVE_FILE', __DIR__ . '/active.txt');

// =============================================================================
// HELPERS
// =============================================================================

function redirect(string $url): never {
    header('Location: ' . $url);
    exit;
}

function require_auth(): void {
    if (empty($_SESSION['auth'])) redirect('?login');
}

function get_active(): string {
    if (!file_exists(ACTIVE_FILE)) return '';
    $v = trim(file_get_contents(ACTIVE_FILE));
    return $v !== '' ? $v : '';
}

function set_active(string $filename): void {
    file_put_contents(ACTIVE_FILE, $filename);
}

function get_bin_files(): array {
    $files = glob(FILES_DIR . '/*.bin');
    return $files ? array_map('basename', $files) : [];
}

function safe_filename(string $name): bool {
    return $name === basename($name)
        && str_ends_with($name, '.bin')
        && !str_contains($name, "\0");
}

function has_png(string $bin_basename): bool {
    $png = substr($bin_basename, 0, -4) . '.png';
    return file_exists(FILES_DIR . '/' . $png);
}

function png_path(string $bin_basename): string {
    return FILES_DIR . '/' . substr($bin_basename, 0, -4) . '.png';
}

// =============================================================================
// ACTIONS  (POST handlers - redirect, never render)
// =============================================================================

function action_login(): never {
    if (hash_equals(PASSWORD, $_POST['password'] ?? '')) {
        $_SESSION['auth'] = true;
        redirect('?edit');
    }
    redirect('?login&err=1');
}

function action_set_file(): never {
    require_auth();
    $f = $_POST['file'] ?? '';
    if (safe_filename($f) && file_exists(FILES_DIR . '/' . $f)) {
        set_active($f);
    }
    redirect('?edit');
}

// =============================================================================
// RENDERERS  (GET handlers - output HTML, never redirect)
// =============================================================================

function render_login(): never {
    $err = !empty($_GET['err']); ?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Login</title>
<style>
  body{font:14px monospace;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#111;color:#eee}
  form{display:flex;flex-direction:column;gap:8px;width:220px}
  input[type=password]{padding:6px;background:#222;border:1px solid #555;color:#eee}
  button{padding:6px;background:#444;border:none;color:#eee;cursor:pointer}
  button:hover{background:#555}
  .err{color:#f66;font-size:12px}
</style>
</head>
<body>
<form method="post" action="?login">
  <label>Password</label>
  <input type="password" name="password" autofocus>
  <button type="submit">Login</button>
  <?php if ($err): ?><span class="err">Wrong password.</span><?php endif; ?>
</form>
</body></html>
<?php exit; }

function render_edit(): never {
    require_auth();
    $files  = get_bin_files();
    $active = get_active(); ?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Select File</title>
<style>
  body{font:14px monospace;background:#111;color:#eee;padding:24px;margin:0}
  h2{margin:0 0 16px}
  ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px}
  li form{margin:0}
  .row{display:flex;align-items:center;gap:10px}
  button{padding:6px 12px;background:#333;border:1px solid #555;color:#eee;cursor:pointer;flex:1;text-align:left}
  button:hover{background:#444}
  button.active{border-color:#6af;color:#6af}
  .thumb{width:480px;height:270px;object-fit:cover;border:1px solid #444;background:#222;flex-shrink:0}
  .nothumb{width:64px;height:64px;flex-shrink:0}
  .none{color:#888}
</style>
</head>
<body>
<h2>Live file selector</h2>
<p>Active: <strong><?= $active !== '' ? htmlspecialchars($active) : '<span class="none">none</span>' ?></strong></p>
<?php if ($files): ?>
<ul>
<?php foreach ($files as $f): ?>
  <li>
    <form method="post" action="?edit">
      <div class="row">
        <?php if (has_png($f)): ?>
          <img class="thumb" src="?img=<?= urlencode($f) ?>" alt="">
        <?php else: ?>
          <div class="nothumb"></div>
        <?php endif; ?>
        <input type="hidden" name="file" value="<?= htmlspecialchars($f) ?>">
        <button type="submit"<?= $f === $active ? ' class="active"' : '' ?>><?= htmlspecialchars($f) ?></button>
      </div>
    </form>
  </li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p class="none">No .bin files found in avj2305/</p>
<?php endif; ?>
</body></html>
<?php exit; }

// =============================================================================
// FILE SERVER  (default route)
// =============================================================================

function serve_png(): never {
    require_auth();
    $f = $_GET['img'] ?? '';
    if (!safe_filename($f)) {
        http_response_code(400); exit('Invalid filename.');
    }
    $path = png_path($f);
    if (!file_exists($path)) {
        http_response_code(404); exit('No preview.');
    }
    header('Content-Type: image/png');
    header('Content-Length: ' . filesize($path));
    readfile($path);
    exit;
}

function serve_active_file(): never {
    $active = get_active();

    if ($active === '') {
        http_response_code(404); exit('No active file set.');
    }
    if (!safe_filename($active)) {
        http_response_code(500); exit('Invalid filename.');
    }

    $path = FILES_DIR . '/' . $active;

    if (!file_exists($path)) {
        http_response_code(404); exit('File not found.');
    }

    header('Content-Type: application/octet-stream');
    header('Content-Disposition: inline; filename="' . addslashes($active) . '"');
    header('Content-Length: ' . filesize($path));
    readfile($path);
    exit;
}


// =============================================================================
// ROUTES
// =============================================================================
//
//   GET  /live.php           -> serve active .bin file
//   GET  /live.php?login    -> login page
//   POST /live.php?login    -> process login
//   GET  /live.php?edit     -> file picker             [auth required]
//   POST /live.php?edit     -> set active file         [auth required]
//   GET  /live.php?img=x.bin -> serve x.png preview   [auth required]
//
// =============================================================================

$method = $_SERVER['REQUEST_METHOD'];
$route  = array_key_first($_GET) ?? '';

match (true) {
    $method === 'POST' && $route === 'login' => action_login(),
    $method === 'POST' && $route === 'edit'  => action_set_file(),
    $method === 'GET'  && $route === 'login' => render_login(),
    $method === 'GET'  && $route === 'edit'  => render_edit(),
    $method === 'GET'  && $route === 'img'   => serve_png(),
    default                                  => serve_active_file(),
};
