import { Router, type IRouter } from "express";
import semver from "semver";
import { requireAdmin } from "../middlewares/auth";
import versionFile from "../../../../version.json" with { type: "json" };
import { GetSystemVersionResponse } from "@workspace/api-zod";

const router: IRouter = Router();

const CURRENT_VERSION: string = versionFile.version;
const CURRENT_BUILD: string = versionFile.build;

// Captured once at module load — frozen for the lifetime of the
// process. The admin "System Updates" panel renders this so the user
// gets a visible signal whenever the container actually restarts
// (independent of build/version, which only change on rebuild).
const SERVER_STARTED_AT: string = new Date().toISOString();

const LATEST_URL = process.env.LATEST_VERSION_URL ?? "";
const FETCH_TIMEOUT_MS = 5000;

type LatestPayload = {
  version?: unknown;
  build?: unknown;
};

router.get("/system/version", requireAdmin, async (_req, res): Promise<void> => {
  const checkedAt = new Date().toISOString();

  if (!LATEST_URL) {
    res.json(
      GetSystemVersionResponse.parse({
        current: { version: CURRENT_VERSION, build: CURRENT_BUILD },
        latest: null,
        status: "not-configured",
        errorMessage: null,
        checkedAt,
        configured: false,
          startedAt: SERVER_STARTED_AT,
      }),
    );
    return;
  }

  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
  try {
    const response = await fetch(LATEST_URL, {
      signal: controller.signal,
      headers: { Accept: "application/json" },
    });
    if (!response.ok) {
      res.json(
        GetSystemVersionResponse.parse({
          current: { version: CURRENT_VERSION, build: CURRENT_BUILD },
          latest: null,
          status: "error",
          errorMessage: `HTTP ${response.status}`,
          checkedAt,
          configured: true,
          startedAt: SERVER_STARTED_AT,
        }),
      );
      return;
    }
    const body = (await response.json()) as LatestPayload;
    const rawVersion = typeof body.version === "string" ? body.version : "";
    const rawBuild = typeof body.build === "string" ? body.build : "";
    const cleaned = semver.valid(semver.coerce(rawVersion));
    const localCleaned = semver.valid(semver.coerce(CURRENT_VERSION));
    if (!cleaned || !localCleaned) {
      res.json(
        GetSystemVersionResponse.parse({
          current: { version: CURRENT_VERSION, build: CURRENT_BUILD },
          latest: { version: rawVersion, build: rawBuild },
          status: "error",
          errorMessage: "Invalid version format",
          checkedAt,
          configured: true,
          startedAt: SERVER_STARTED_AT,
        }),
      );
      return;
    }
    // semver.gt: strictly greater → update available. Equal or older →
    // up to date (we never tell the user to "downgrade" — the desktop
    // build is the source of truth for that scenario).
    const status = semver.gt(cleaned, localCleaned)
      ? "update-available"
      : "up-to-date";
    res.json(
      GetSystemVersionResponse.parse({
        current: { version: CURRENT_VERSION, build: CURRENT_BUILD },
        latest: { version: rawVersion, build: rawBuild },
        status,
        errorMessage: null,
        checkedAt,
        configured: true,
          startedAt: SERVER_STARTED_AT,
      }),
    );
  } catch (err) {
    const message =
      err instanceof Error
        ? err.name === "AbortError"
          ? "Request timed out"
          : err.message
        : "Unknown error";
    res.json(
      GetSystemVersionResponse.parse({
        current: { version: CURRENT_VERSION, build: CURRENT_BUILD },
        latest: null,
        status: "error",
        errorMessage: message,
        checkedAt,
        configured: true,
          startedAt: SERVER_STARTED_AT,
      }),
    );
  } finally {
    clearTimeout(timer);
  }
});

export default router;
