<?php
/**
 * LUPMIS2 PWA — Authenticated entry point
 *
 * This file replaces a plain index.html as the directory index in production.
 * It:
 *   1. Picks up the LUSPA SSO cookie (sso_auth_token) set by the central
 *      login at https://lupmis4luspa.org/sso/.
 *   2. Validates the token server-side against the SSO endpoint.
 *   3. Populates a PHP session with the authenticated user's profile
 *      (user_id, district_id, region_id, full_name, ua_id, …).
 *   4. Reads the built index.html that Vite produces and injects the
 *      session payload as a JavaScript global `window.LUPMIS_SESSION` —
 *      the PWA reads this on startup (see src/remotedb.js) to scope every
 *      API call to the logged-in user's district.
 *
 * In local development (Vite serves index.html directly without PHP) the
 * global is absent and the PWA falls back to a hard-coded district for
 * testing. See remotedb.js getApiCredentials().
 *
 * Adapted from auth code provided by the LUSPA authentication team
 * (FromKwesi / 20260527 / index.php).
 */
session_start();

// ────────────────────────────────────────────────────────────────────────────
// Logout — end the PWA's OWN session, then hand off to the central SSO logout
// ────────────────────────────────────────────────────────────────────────────
// The PWA keeps its own PHP session (PHPSESSID on this host), independent of
// the central SSO portal, so the previous user's fields (incl. district_id)
// persist until this session is destroyed. We do that here, then redirect to
// the portal's `/user-logout`, which performs the FULL SSO logout (invalidates
// the token server-side and clears the sso_auth_token cookie itself).
//
// Important: we deliberately do NOT clear `sso_auth_token` here. `/user-logout`
// needs that cookie to identify which SSO session to terminate — expiring it
// first would leave the SSO session alive on the server. Redirecting to the
// bare landing page (the old behaviour) only dropped the user on a page that
// then blocked them; it never logged them out of SSO.
//
// Triggered by `/?logout=1` from the in-app menu.
if (isset($_GET['logout'])) {
    $_SESSION = [];
    // Expire the PWA's own session cookie (PHPSESSID).
    if (ini_get('session.use_cookies')) {
        $cp = session_get_cookie_params();
        setcookie(session_name(), '', time() - 42000,
            $cp['path'], $cp['domain'], $cp['secure'], $cp['httponly']);
    }
    session_destroy();
    // Hand off to the central SSO logout (full logout: invalidates the token
    // and clears sso_auth_token). Keep the cookie intact so it can do so.
    header('Location: https://lupmis4luspa.org/user-logout', true, 302);
    exit;
}

// ────────────────────────────────────────────────────────────────────────────
// SSO authentication — validate once per session, at login
// ────────────────────────────────────────────────────────────────────────────
// A user's district changes only when they are transferred — a rare event — so
// the validated fields (district_id, region_id, name, …) are valid for the
// whole session. We therefore validate the SSO token only when there is no
// session yet (i.e. at login) and do NOT re-poll SSO on every load.
//
// A transfer is picked up the next time the user logs out and back in: the
// Logout endpoint above destroys the PHP session, so the subsequent login has
// no session and re-validates, fetching the new district_id. This is correct
// precisely because logout now tears the session down (previously it only
// cleared the SSO cookie, which left the stale district pinned).
if (!isset($_SESSION['user_id']) && isset($_COOKIE['sso_auth_token'])) {
    $plainToken = $_COOKIE['sso_auth_token'];
    $validate_url = 'https://lupmis4luspa.org/sso/validate?token=' . urlencode($plainToken);

    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL            => $validate_url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING       => "",
        CURLOPT_MAXREDIRS      => 10,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST  => "GET",
        CURLOPT_HTTPHEADER     => [ "Content-Type: application/xml" ],
    ]);
    $response = curl_exec($curl);
    $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);

    if ($httpCode === 200) {
        $data = json_decode($response, true);
        if (
            is_array($data)
            && isset($data['valid']) && $data['valid'] === true
            && isset($data['logged_in_user']) && is_array($data['logged_in_user'])
        ) {
            // Copy all returned user fields into the session
            foreach ($data['logged_in_user'] as $key => $value) {
                $_SESSION[$key] = $value;
            }
        }
    } else {
        // Token rejected by the SSO server — clear the stale cookie so the
        // browser stops sending it. Domain `.lupmis4luspa.org` covers all
        // subdomains (so SSO logout works from the PWA too).
        setcookie('sso_auth_token', '', time() - 3600, '/', '.lupmis4luspa.org');
    }
}

// ────────────────────────────────────────────────────────────────────────────
// Production access guard
// ────────────────────────────────────────────────────────────────────────────
// On the public production host, calling this file without a valid SSO session
// is not allowed — bounce the visitor to the central LUSPA login portal. On
// local development (any host that is not *.lupmis4luspa.org, e.g. localhost,
// 127.0.0.1, a developer's .local hostname) the guard is bypassed so the PHP
// entry point can still be exercised directly during testing.
$host = $_SERVER['HTTP_HOST'] ?? '';
$isProduction = (bool) preg_match('/(^|\.)lupmis4luspa\.org$/i', $host);
if ($isProduction && !isset($_SESSION['user_id'])) {
    header('Location: https://lupmis4luspa.org/', true, 302);
    exit;
}

// ────────────────────────────────────────────────────────────────────────────
// Build the payload exposed to the PWA as window.LUPMIS_SESSION
// ────────────────────────────────────────────────────────────────────────────
$payload = [];
if (isset($_SESSION['user_id'])) {
    $payload = [
        'user_id'     => $_SESSION['user_id']     ?? null,
        'ua_id'       => $_SESSION['ua_id']       ?? null,
        'username'    => $_SESSION['username']    ?? null,
        'title'       => $_SESSION['title']       ?? null,
        'full_name'   => $_SESSION['full_name']   ?? null,
        'email'       => $_SESSION['email']       ?? null,
        'user_type'   => $_SESSION['user_type']   ?? null,
        'phone'       => $_SESSION['phone']       ?? null,
        'ua_position' => $_SESSION['ua_position'] ?? null,
        'region_id'   => $_SESSION['region_id']   ?? null,
        'district_id' => $_SESSION['district_id'] ?? null,
    ];
}

// ────────────────────────────────────────────────────────────────────────────
// Read the built index.html and inject the session as a JS global
// ────────────────────────────────────────────────────────────────────────────
$indexPath = __DIR__ . '/index.html';
$html = is_readable($indexPath)
    ? file_get_contents($indexPath)
    : '<!DOCTYPE html><html><body><h1>LUPMIS2 PWA</h1><p>index.html is missing from this deployment.</p></body></html>';

// Encode safely for inline <script> — the JSON flags below escape
// characters that could break the HTML parser (<, >, &, ', ").
$sessionJson = json_encode(
    $payload,
    JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT
);
$inject = "<script>window.LUPMIS_SESSION = {$sessionJson};</script>";

// Insert right after the opening <head> tag
$html = preg_replace('/<head\b[^>]*>/i', '$0' . "\n  " . $inject, $html, 1);

// ────────────────────────────────────────────────────────────────────────────
// Serve
// ────────────────────────────────────────────────────────────────────────────
header('Content-Type: text/html; charset=utf-8');
// Don't let intermediaries cache an authenticated response — the next visit
// might be a different user. Asset hashes still let static files be cached.
header('Cache-Control: no-store, must-revalidate');
header('Pragma: no-cache');

echo $html;
