/**
 * Self-check for Smartcar OAuth state parsing (no server).
 * Run: npx ts-node src/scripts/testSmartcarCallbackUser.ts
 */
import "../loadEnv";

function assert(cond: boolean, msg: string) {
  if (!cond) throw new Error(msg);
}

async function main(): Promise<void> {
  process.env.JWT_SECRET ||= "smartcar-callback-test-secret-min-32-xxxx";

  const {
    parseTankUserIdFromOAuthState,
    parseTankUserIdFromSmartcarOAuthSession,
    signSmartcarOauthStateTankUserId,
    resolveTankTrackUserIdFromSmartcarRedirectState,
    trySmartcarSimulatorTankTrackUserFromEnv,
  } = await import("../utils/smartcarCallbackUser");

  const validId = "507f1f77bcf86cd799439011";

  assert(parseTankUserIdFromOAuthState(validId) === validId, "valid state");
  assert(
    parseTankUserIdFromOAuthState(encodeURIComponent(validId)) === validId,
    "decoded state still valid"
  );
  assert(parseTankUserIdFromOAuthState(undefined) === null, "missing state");
  assert(parseTankUserIdFromOAuthState("") === null, "empty state");
  assert(
    parseTankUserIdFromOAuthState("not-a-mongo-id") === null,
    "reject non hex"
  );

  const signed = signSmartcarOauthStateTankUserId(validId);
  assert(Boolean(signed && signed.includes(".")), "signed state looks like JWT");
  assert(resolveTankTrackUserIdFromSmartcarRedirectState(signed!) === validId, "JWT state round-trip");
  assert(
    resolveTankTrackUserIdFromSmartcarRedirectState("not-a-jwt") === null,
    "reject bogus JWT state string"
  );

  const sessOk = {
    smartcar_oauth_user_id: validId,
    smartcar_oauth_started_at: Date.now(),
  };
  assert(
    parseTankUserIdFromSmartcarOAuthSession(sessOk) === validId,
    "session fallback"
  );

  assert(
    parseTankUserIdFromSmartcarOAuthSession({
      smartcar_oauth_user_id: validId,
      smartcar_oauth_started_at:
        Date.now() - (13 * 60 * 60 * 1000),
    }) === null,
    "session expired"
  );

  const prevMode = process.env.SMARTCAR_MODE;
  const prevSimId = process.env.SMARTCAR_SIMULATOR_TANK_TRACK_USER_ID;
  const prevBridge = process.env.SMARTCAR_SIMULATOR_BRIDGE;
  try {
    process.env.SMARTCAR_MODE = "test";
    process.env.SMARTCAR_SIMULATOR_TANK_TRACK_USER_ID = validId;
    assert(
      trySmartcarSimulatorTankTrackUserFromEnv() === validId,
      "simulator env in non-live mode"
    );

    process.env.SMARTCAR_MODE = "live";
    delete process.env.SMARTCAR_SIMULATOR_BRIDGE;
    assert(trySmartcarSimulatorTankTrackUserFromEnv() === null, "live blocks without bridge");

    process.env.SMARTCAR_SIMULATOR_BRIDGE = "true";
    assert(
      trySmartcarSimulatorTankTrackUserFromEnv() === validId,
      "SMARTCAR_SIMULATOR_BRIDGE=true allows live"
    );

    delete process.env.SMARTCAR_SIMULATOR_TANK_TRACK_USER_ID;
    assert(trySmartcarSimulatorTankTrackUserFromEnv() === null, "no simulator id");
  } finally {
    if (prevMode === undefined) delete process.env.SMARTCAR_MODE;
    else process.env.SMARTCAR_MODE = prevMode;
    if (prevSimId === undefined)
      delete process.env.SMARTCAR_SIMULATOR_TANK_TRACK_USER_ID;
    else process.env.SMARTCAR_SIMULATOR_TANK_TRACK_USER_ID = prevSimId;
    if (prevBridge === undefined) delete process.env.SMARTCAR_SIMULATOR_BRIDGE;
    else process.env.SMARTCAR_SIMULATOR_BRIDGE = prevBridge;
  }

  console.log("smartcarCallbackUser tests: OK");
}

void main().catch((e) => {
  console.error(e instanceof Error ? e.message : e);
  process.exit(1);
});
