// src/hooks.server.ts
import { optima } from "$lib";
import { isInvalidSignatureError } from "$lib/optima-api/errorHandler";
import { redirect, type Handle } from "@sveltejs/kit";
import api from "$lib/optima-api/axios";

function apiUnreachablePage(): Response {
  const html = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Service Unavailable — Project Optima</title>
  <style>
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
    body {
      min-height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      background: #0f1117;
      color: #e4e4e7;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    }
    .container {
      text-align: center;
      max-width: 480px;
      padding: 2rem;
    }
    .icon {
      margin-bottom: 1.5rem;
    }
    .icon svg {
      width: 96px;
      height: 96px;
    }
    h1 {
      font-size: 1.75rem;
      font-weight: 700;
      margin-bottom: 0.75rem;
      color: #f87171;
    }
    p {
      font-size: 1rem;
      line-height: 1.6;
      color: #a1a1aa;
      margin-bottom: 1.5rem;
    }
    .retry-btn {
      display: inline-flex;
      align-items: center;
      gap: 0.5rem;
      padding: 0.65rem 1.5rem;
      background: #dc2626;
      color: #fff;
      border: none;
      border-radius: 8px;
      font-size: 0.95rem;
      font-weight: 600;
      cursor: pointer;
      transition: background 0.15s;
      text-decoration: none;
    }
    .retry-btn:hover { background: #b91c1c; }
    .status {
      margin-top: 2rem;
      font-size: 0.8rem;
      color: #52525b;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="icon">
      <svg viewBox="0 0 96 96" fill="none" xmlns="http://www.w3.org/2000/svg">
        <circle cx="48" cy="48" r="44" stroke="#dc2626" stroke-width="3" opacity="0.2"/>
        <circle cx="48" cy="48" r="32" fill="#1c1c22"/>
        <path d="M36 36L60 60M60 36L36 60" stroke="#dc2626" stroke-width="4" stroke-linecap="round"/>
      </svg>
    </div>
    <h1>Unable to Reach API</h1>
    <p>
      Project Optima cannot connect to the API server. This may be due to a
      network issue or the API server being temporarily unavailable.
    </p>
    <a class="retry-btn" onclick="window.location.reload()" role="button" tabindex="0">
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
        <polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/>
      </svg>
      Retry
    </a>
    <p class="status">If this persists, contact your system administrator.</p>
  </div>
</body>
</html>`;

  return new Response(html, {
    status: 503,
    headers: { "Content-Type": "text/html; charset=utf-8" },
  });
}

export const handle: Handle = async ({ event, resolve }) => {
  // Let Kubernetes health probes pass without hitting the external API
  if (event.url.pathname === "/healthz") {
    return await resolve(event);
  }

  // Health-check the API before doing anything else.
  // /v1/teapot returns 418 when the API is alive.
  try {
    const health = await api.get("/v1/teapot", {
      timeout: 5000,
      validateStatus: () => true,
    });
    if (health.status !== 418) throw new Error("Unexpected status");
  } catch {
    return apiUnreachablePage();
  }

  const accessToken = event.cookies.get("accessToken") || null;
  const refreshToken = event.cookies.get("refreshToken") || null;

  if (event.url.pathname === "/logout") {
    event.cookies.delete("accessToken", { path: "/" });
    event.cookies.delete("refreshToken", { path: "/" });

    return redirect(303, "/login");
  }

  if (
    event.url.pathname.startsWith("/login") &&
    optima.user.isLoggedInServer(event)
  ) {
    return redirect(303, "/");
  }

  if (event.url.pathname.startsWith("/login")) {
    return await resolve(event);
  }

  if (!accessToken && !refreshToken) {
    optima.user.logout(event);
    redirect(303, "/login");
  }

  // Check if the access token is expired or near expiry and refresh if needed
  let currentAccessToken = accessToken;
  let currentRefreshToken = refreshToken;

  if (currentAccessToken) {
    try {
      const [, payload] = currentAccessToken.split(".");
      const decoded = JSON.parse(
        Buffer.from(payload, "base64url").toString("utf8")
      );
      const nowSec = Math.floor(Date.now() / 1000);
      const thresholdSec = 60; // refresh if < 60s remaining

      if (!decoded?.exp || decoded.exp - nowSec < thresholdSec) {
        // Token is expired or about to expire — try to refresh
        if (currentRefreshToken) {
          const refreshed = await optima.user.refreshSession(
            currentRefreshToken
          );
          currentAccessToken = refreshed.accessToken;
          currentRefreshToken = refreshed.refreshToken ?? currentRefreshToken;
        } else {
          // No refresh token available, force re-login
          optima.user.logout(event);
          return redirect(303, "/login");
        }
      }
    } catch (err) {
      // Invalid signature means tokens are fundamentally bad — don't attempt refresh
      if (isInvalidSignatureError(err)) {
        console.warn("Invalid token signature detected — forcing logout.");
        optima.user.logout(event);
        return redirect(303, "/login");
      }
      // Token is malformed or refresh failed — try refresh as fallback
      if (currentRefreshToken) {
        try {
          const refreshed = await optima.user.refreshSession(
            currentRefreshToken
          );
          currentAccessToken = refreshed.accessToken;
          currentRefreshToken = refreshed.refreshToken ?? currentRefreshToken;
        } catch (refreshErr) {
          if (isInvalidSignatureError(refreshErr)) {
            console.warn("Invalid refresh token signature — forcing logout.");
          }
          // Refresh also failed, force re-login
          optima.user.logout(event);
          return redirect(303, "/login");
        }
      } else {
        optima.user.logout(event);
        return redirect(303, "/login");
      }
    }
  } else if (currentRefreshToken) {
    // No access token but have a refresh token — try to get a new one
    try {
      const refreshed = await optima.user.refreshSession(currentRefreshToken);
      currentAccessToken = refreshed.accessToken;
      currentRefreshToken = refreshed.refreshToken ?? currentRefreshToken;
    } catch (err) {
      if (isInvalidSignatureError(err)) {
        console.warn("Invalid refresh token signature — forcing logout.");
      }
      optima.user.logout(event);
      return redirect(303, "/login");
    }
  }

  const setTokens = async (accessToken: string, refreshToken: string) => {
    event.cookies.set("accessToken", accessToken, { path: "/" });
    event.cookies.set("refreshToken", refreshToken, { path: "/" });

    event.locals.session = { accessToken, refreshToken, set: setTokens };

    return;
  };

  // Persist any refreshed tokens into cookies
  await setTokens(currentAccessToken!, currentRefreshToken!);

  const response = await resolve(event);
  return response;
};
