import { readFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import type { RuntimeModePreference } from "@qjclaw/shared-types";

const DEFAULT_GATEWAY_URL = "ws://127.0.0.1:18789";

interface OpenClawGatewayConfigShape {
  auth?: {
    token?: string;
  };
  bind?: string;
  host?: string;
  port?: number;
}

interface OpenClawConfigShape {
  gateway?: OpenClawGatewayConfigShape;
}

export interface LocalOpenClawGatewayConfig {
  sourcePath: string;
  gatewayUrl?: string;
  gatewayToken?: string;
}

export async function loadLocalOpenClawGatewayConfig(): Promise<LocalOpenClawGatewayConfig | null> {
  if (process.env.QJCLAW_DISABLE_LOCAL_OPENCLAW_GATEWAY === "1") {
    return null;
  }

  const sourcePath = path.join(os.homedir(), ".openclaw", "openclaw.json");

  try {
    const raw = await readFile(sourcePath, "utf8");
    const parsed = JSON.parse(raw) as OpenClawConfigShape;
    const gateway = parsed.gateway;
    if (!gateway) {
      return null;
    }

    return {
      sourcePath,
      gatewayUrl: buildGatewayUrl(gateway),
      gatewayToken: typeof gateway.auth?.token === "string" && gateway.auth.token.trim()
        ? gateway.auth.token
        : undefined
    };
  } catch {
    return null;
  }
}

export function shouldUseLocalOpenClawGateway(
  isPackaged: boolean,
  runtimeMode: RuntimeModePreference
): boolean {
  return !isPackaged || runtimeMode === "external-gateway";
}

export function resolveEffectiveGatewayUrl(
  configuredUrl: string,
  discoveredUrl?: string
): string {
  if (!discoveredUrl) {
    return configuredUrl;
  }

  if (!configuredUrl || configuredUrl === DEFAULT_GATEWAY_URL) {
    return discoveredUrl;
  }

  return configuredUrl;
}

export function resolveEffectiveGatewayToken(
  configuredToken?: string,
  discoveredToken?: string
): string | undefined {
  if (configuredToken && configuredToken.trim()) {
    return configuredToken;
  }

  if (discoveredToken && discoveredToken.trim()) {
    return discoveredToken;
  }

  return undefined;
}

function buildGatewayUrl(config: OpenClawGatewayConfigShape): string {
  const port = typeof config.port === "number" ? config.port : 18789;
  const host = resolveHost(config);
  return `ws://${host}:${port}`;
}

function resolveHost(config: OpenClawGatewayConfigShape): string {
  if (typeof config.host === "string" && config.host.trim()) {
    return config.host;
  }

  if (config.bind === "loopback") {
    return "127.0.0.1";
  }

  return "127.0.0.1";
}
