<?php
/**
 * staff.php
 *
 * Moodle-launched staff print queue for requests created in search.php.
 * Moodle is the only identity and access authority. This page has no local
 * accounts, passwords, registration, or staff-user repository.
 */

declare(strict_types=1);

require_once __DIR__ . '/config.php';
require_once __DIR__ . '/lib.php';

header('X-Content-Type-Options: nosniff');
header('Referrer-Policy: no-referrer');
header('Content-Type: text/html; charset=UTF-8');
header("Content-Security-Policy: frame-ancestors 'self' https://www.maxxlms.com https://maxxlms.com");

error_reporting(E_ALL);
ini_set('display_errors', '0');

session_set_cookie_params([
    'lifetime' => 0,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);
session_start();

function valid_moodle_identifier(mixed $value): ?string
{
    if (!is_string($value)) {
        return null;
    }

    $value = trim($value);
    if ($value === '' || !preg_match('/^[A-Za-z0-9._@-]{1,128}$/', $value)) {
        return null;
    }

    return $value;
}

function staff_csrf_ok(): bool
{
    $posted = $_POST['csrf_token'] ?? '';
    $stored = $_SESSION['staff_csrf_token'] ?? '';

    return is_string($posted)
        && is_string($stored)
        && $posted !== ''
        && hash_equals($stored, $posted);
}

function current_moodle_staff_identifier(): ?string
{
    if (($_SESSION['staff_launch_authorized'] ?? false) !== true) {
        return null;
    }

    return valid_moodle_identifier($_SESSION['moodle_staff_identifier'] ?? null);
}

// ---------------------------------------------------------------------------
// Initial launch from the hidden Moodle staff URL activity
// ---------------------------------------------------------------------------

$hasLaunchParameters = array_key_exists('staff_key', $_GET) || array_key_exists('username', $_GET);
if ($hasLaunchParameters) {
    $providedKey = $_GET['staff_key'] ?? null;
    $moodleStaffIdentifier = valid_moodle_identifier($_GET['username'] ?? null);
    $validKey = is_string($providedKey)
        && defined('STAFF_LAUNCH_TOKEN')
        && STAFF_LAUNCH_TOKEN !== ''
        && hash_equals(STAFF_LAUNCH_TOKEN, $providedKey);

    if ($validKey && $moodleStaffIdentifier !== null) {
        session_regenerate_id(true);
        $_SESSION['staff_launch_authorized'] = true;
        $_SESSION['moodle_staff_identifier'] = $moodleStaffIdentifier;
        $_SESSION['staff_csrf_token'] = bin2hex(random_bytes(32));

        // Remove the private key from the visible iframe address after the
        // session has been established.
        header('Location: https://lawlibrary.maxxlms.com/staff.php');
        exit;
    }

    unset(
        $_SESSION['staff_launch_authorized'],
        $_SESSION['moodle_staff_identifier'],
        $_SESSION['staff_csrf_token']
    );
}

$staffIdentifier = current_moodle_staff_identifier();
$accessDenied = $staffIdentifier === null;
if ($accessDenied) {
    http_response_code(403);
}

if (!$accessDenied && empty($_SESSION['staff_csrf_token'])) {
    $_SESSION['staff_csrf_token'] = bin2hex(random_bytes(32));
}

// ---------------------------------------------------------------------------
// Authenticated staff actions
// ---------------------------------------------------------------------------

$actionError = null;
if (
    !$accessDenied
    && $_SERVER['REQUEST_METHOD'] === 'POST'
    && in_array(($_POST['action'] ?? ''), ['mark_printed', 'mark_cancelled'], true)
) {
    if (!staff_csrf_ok()) {
        $actionError = 'Your staff session expired. Please reopen this activity from Moodle.';
    } else {
        $requestId = filter_var($_POST['request_id'] ?? '', FILTER_VALIDATE_INT);
        if ($requestId !== false) {
            $newStatus = $_POST['action'] === 'mark_printed' ? 'printed' : 'cancelled';
            update_print_request_status((int) $requestId, $newStatus, (string) $staffIdentifier);
        }

        $returnStatus = $_GET['status'] ?? 'pending';
        if (!in_array($returnStatus, ['pending', 'printed', 'cancelled', 'all'], true)) {
            $returnStatus = 'pending';
        }
        header('Location: https://lawlibrary.maxxlms.com/staff.php?status=' . urlencode($returnStatus));
        exit;
    }
}

// ---------------------------------------------------------------------------
// Queue data
// ---------------------------------------------------------------------------

$requestedStatus = $_GET['status'] ?? 'pending';
$statusFilter = in_array($requestedStatus, ['pending', 'printed', 'cancelled', 'all'], true)
    ? (string) $requestedStatus
    : 'pending';

$printRequests = [];
$printDoc = null;
$printRequestRow = null;
$printError = null;

if (!$accessDenied) {
    $printId = filter_var($_GET['print'] ?? null, FILTER_VALIDATE_INT);
    if ($printId !== false) {
        $printRequestRow = get_print_request((int) $printId);
        if ($printRequestRow === null) {
            $printError = 'That print request could not be found.';
        } elseif (!file_exists(VENDOR_AUTOLOAD)) {
            $printError = 'The search backend is not configured on this server.';
        } else {
            require_once VENDOR_AUTOLOAD;
            try {
                $client = new \Meilisearch\Client(
                    MEILI_HOST,
                    MEILI_API_KEY !== '' ? MEILI_API_KEY : null
                );
                $printDoc = $client->index(MEILI_INDEX)->getDocument($printRequestRow['opinion_id']);
            } catch (\Throwable $exception) {
                error_log('[staff.php] getDocument error: ' . $exception->getMessage());
                $printError = 'Could not load the full opinion text right now.';
            }
        }
    } else {
        $printRequests = list_print_requests($statusFilter);
    }
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
<title>Staff Print Queue</title>
<style>
  :root {
    --color-bg: #f7f7f5;
    --color-surface: #ffffff;
    --color-border: #d6d3ce;
    --color-text: #1a1a1a;
    --color-muted: #4b4b4b;
    --color-primary: #1c4e80;
    --color-primary-dark: #123452;
    --color-focus: #ff8c00;
    --color-warn: #b3261e;
    --radius: 6px;
  }
  * { box-sizing: border-box; }
  html, body {
    margin: 0;
    padding: 0;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    font-size: 17px;
    line-height: 1.5;
  }
  a { color: var(--color-primary); }
  *:focus-visible { outline: 3px solid var(--color-focus); outline-offset: 2px; }
  header.site-header {
    background: var(--color-primary-dark);
    color: #fff;
    padding: 16px 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
  }
  header.site-header h1 { margin: 0; font-size: 1.4rem; }
  .wrap { max-width: 1100px; margin: 24px auto; padding: 0 16px 40px; }
  .notice, .empty-state {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 24px;
    text-align: center;
    color: var(--color-muted);
  }
  .notice.denied { border-color: var(--color-warn); color: var(--color-warn); }
  .error-text { color: var(--color-warn); font-weight: 600; }
  .tabs { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
  .tabs a {
    padding: 8px 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    text-decoration: none;
    background: var(--color-surface);
  }
  .tabs a.active {
    background: var(--color-primary);
    color: #fff;
    border-color: var(--color-primary);
  }
  table.queue { width: 100%; border-collapse: collapse; background: var(--color-surface); }
  table.queue th, table.queue td {
    text-align: left;
    padding: 10px 12px;
    border-bottom: 1px solid var(--color-border);
    vertical-align: top;
  }
  table.queue th { background: #eef1f4; }
  .status-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 700;
  }
  .status-pending { background: #fff1a8; color: #6b5900; }
  .status-printed { background: #d4edda; color: #1e6b3c; }
  .status-cancelled { background: #f1f1f1; color: #666; }
  .row-actions, .print-toolbar { display: flex; gap: 8px; flex-wrap: wrap; }
  .row-actions form { margin: 0; }
  .btn {
    padding: 8px 12px;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    cursor: pointer;
    font-size: 0.9rem;
    text-decoration: none;
    color: var(--color-text);
    min-height: 44px;
  }
  .btn-primary { background: var(--color-primary); color: #fff; border-color: var(--color-primary); }
  .btn-danger { background: #fdecea; color: var(--color-warn); border-color: var(--color-warn); }
  .opinion-detail {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 24px;
  }
  .opinion-text { white-space: pre-wrap; line-height: 1.7; margin-top: 16px; }
  .back-link { display: inline-block; margin-bottom: 16px; font-weight: 600; }
  .print-toolbar { margin-bottom: 16px; }
  @media (max-width: 760px) {
    table.queue, table.queue thead, table.queue tbody, table.queue th, table.queue td, table.queue tr {
      display: block;
    }
    table.queue thead { position: absolute; left: -9999px; }
    table.queue tr { border: 1px solid var(--color-border); margin-bottom: 12px; }
    table.queue td { border-bottom: 1px solid var(--color-border); }
  }
  @media print {
    header.site-header, .back-link, .print-toolbar, .tabs { display: none; }
  }
</style>
</head>
<body>

<header class="site-header">
  <h1>Staff Print Queue</h1>
  <?php if (!$accessDenied): ?>
    <div>Moodle staff: <strong><?= h($staffIdentifier) ?></strong></div>
  <?php endif; ?>
</header>

<div class="wrap">
<?php if ($accessDenied): ?>

  <div class="notice denied">
    <h2>Access denied</h2>
    <p>Open the hidden Staff Print Queue activity from Moodle.</p>
  </div>

<?php elseif ($printRequestRow !== null): ?>

  <a class="back-link" href="https://lawlibrary.maxxlms.com/staff.php?status=<?= h($statusFilter) ?>">&larr; Back to queue</a>

  <?php if ($printError !== null): ?>
    <div class="empty-state"><p><?= h($printError) ?></p></div>
  <?php else: ?>
    <div class="print-toolbar">
      <button class="btn btn-primary" onclick="window.print()" type="button">Print this opinion</button>
      <?php if ($printRequestRow['status'] === 'pending'): ?>
        <form method="post" action="https://lawlibrary.maxxlms.com/staff.php?print=<?= (int) $printRequestRow['id'] ?>&amp;status=<?= h($statusFilter) ?>">
          <input type="hidden" name="csrf_token" value="<?= h($_SESSION['staff_csrf_token']) ?>">
          <input type="hidden" name="request_id" value="<?= (int) $printRequestRow['id'] ?>">
          <input type="hidden" name="action" value="mark_printed">
          <button class="btn btn-primary" type="submit">Mark as Printed</button>
        </form>
      <?php endif; ?>
    </div>

    <article class="opinion-detail">
      <h2><?= h($printDoc['case_name'] ?? $printRequestRow['case_name'] ?? 'Untitled opinion') ?></h2>
      <p>
        <strong>Court:</strong> <?= h($printDoc['court_name'] ?? $printRequestRow['court_name'] ?? 'Unknown') ?>
        &nbsp;|&nbsp;
        <strong>Date filed:</strong> <?= h($printDoc['date_filed'] ?? $printRequestRow['date_filed'] ?? 'Unknown') ?>
        &nbsp;|&nbsp;
        <strong>Requested by:</strong> <?= h($printRequestRow['username']) ?>
      </p>
      <div class="opinion-text"><?= h(strip_external_references($printDoc['text'] ?? $printDoc['html_lawbox'] ?? null) ?? 'Full text is not available for this opinion.') ?></div>
    </article>
  <?php endif; ?>

<?php else: ?>

  <?php if ($actionError !== null): ?><p class="error-text"><?= h($actionError) ?></p><?php endif; ?>

  <nav class="tabs" aria-label="Print-request status">
    <a href="https://lawlibrary.maxxlms.com/staff.php?status=pending" class="<?= $statusFilter === 'pending' ? 'active' : '' ?>">Pending</a>
    <a href="https://lawlibrary.maxxlms.com/staff.php?status=printed" class="<?= $statusFilter === 'printed' ? 'active' : '' ?>">Printed</a>
    <a href="https://lawlibrary.maxxlms.com/staff.php?status=cancelled" class="<?= $statusFilter === 'cancelled' ? 'active' : '' ?>">Cancelled</a>
    <a href="https://lawlibrary.maxxlms.com/staff.php?status=all" class="<?= $statusFilter === 'all' ? 'active' : '' ?>">All</a>
  </nav>

  <?php if (empty($printRequests)): ?>
    <div class="empty-state"><p>No <?= $statusFilter === 'all' ? '' : h($statusFilter) . ' ' ?>print requests right now.</p></div>
  <?php else: ?>
    <table class="queue">
      <thead>
        <tr>
          <th>Learner</th><th>Case</th><th>Court</th><th>Date filed</th><th>Requested</th><th>Status</th><th></th>
        </tr>
      </thead>
      <tbody>
      <?php foreach ($printRequests as $request): ?>
        <tr>
          <td><?= h($request['username']) ?></td>
          <td><?= h($request['case_name'] ?? 'Untitled opinion') ?></td>
          <td><?= h($request['court_name'] ?? '') ?></td>
          <td><?= h($request['date_filed'] ?? '') ?></td>
          <td><?= h(substr((string) $request['requested_at'], 0, 16)) ?></td>
          <td><span class="status-badge status-<?= h($request['status']) ?>"><?= h($request['status']) ?></span></td>
          <td>
            <div class="row-actions">
              <a class="btn" href="https://lawlibrary.maxxlms.com/staff.php?print=<?= (int) $request['id'] ?>&amp;status=<?= h($statusFilter) ?>">View / Print</a>
              <?php if ($request['status'] === 'pending'): ?>
                <form method="post" action="https://lawlibrary.maxxlms.com/staff.php?status=<?= h($statusFilter) ?>">
                  <input type="hidden" name="csrf_token" value="<?= h($_SESSION['staff_csrf_token']) ?>">
                  <input type="hidden" name="request_id" value="<?= (int) $request['id'] ?>">
                  <input type="hidden" name="action" value="mark_printed">
                  <button class="btn btn-primary" type="submit">Mark Printed</button>
                </form>
                <form method="post" action="https://lawlibrary.maxxlms.com/staff.php?status=<?= h($statusFilter) ?>">
                  <input type="hidden" name="csrf_token" value="<?= h($_SESSION['staff_csrf_token']) ?>">
                  <input type="hidden" name="request_id" value="<?= (int) $request['id'] ?>">
                  <input type="hidden" name="action" value="mark_cancelled">
                  <button class="btn btn-danger" type="submit">Cancel</button>
                </form>
              <?php endif; ?>
            </div>
          </td>
        </tr>
      <?php endforeach; ?>
      </tbody>
    </table>
  <?php endif; ?>

<?php endif; ?>
</div>
</body>
</html>