import test from "node:test"
import assert from "node:assert/strict"
import type {
  AppConfig,
  GatewayStatus,
  RuntimeCloudStatus,
  RuntimeStatus
} from "@qjclaw/shared-types"

import { buildChatSummary } from "../src/main/workspace-startup.ts"

function makeConfig(): AppConfig {
  return {
    setupMode: "employee-key",
    provider: "openai",
    baseUrl: "https://example.test/v1",
    apiKeyConfigured: true,
    gatewayTokenConfigured: false,
    authTokenConfigured: false,
    defaultModel: "test-model",
    workspacePath: "/tmp/qjc-workspace",
    gatewayUrl: "ws://127.0.0.1:18889",
    cloudApiBaseUrl: "https://cloud.example.test",
    runtimeCloudApiBaseUrl: "https://runtime.example.test",
    runtimeMode: "bundled-runtime",
    expertModelConfig: {
      image: { baseUrl: "", apiKeyConfigured: false, modelId: "" },
      video: { baseUrl: "", apiKeyConfigured: false, modelId: "" },
      copywriting: { baseUrl: "https://example.test/v1", apiKeyConfigured: true, modelId: "test-model" },
      digitalHuman: {
        volcAccessKeyConfigured: false,
        volcSecretKeyConfigured: false,
        qiniuAccessKeyConfigured: false,
        qiniuSecretKeyConfigured: false
      }
    },
    douyinRuntimeConfig: {
      videoAnalyzer: { baseUrl: "", apiKeyConfigured: false, modelId: "" },
      replicationBrief: { baseUrl: "", apiKeyConfigured: false, modelId: "" },
      vectcut: { baseUrl: "", fileBaseUrl: "", apiKeyConfigured: false }
    },
    xhsFeishuConfig: {
      appIdConfigured: false,
      appSecretConfigured: false,
      appTokenConfigured: false,
      tableIdConfigured: false
    }
  }
}

function makeRuntime(processState: RuntimeStatus["processState"], gatewayUrl = "ws://127.0.0.1:51079"): RuntimeStatus {
  return {
    requestedMode: "bundled-runtime",
    selectedMode: "bundled-runtime",
    activeMode: processState === "running" || processState === "starting" ? "bundled-runtime" : "external-gateway",
    payloadState: "ready",
    processState,
    runtimeDir: "/runtime",
    nodeExecutable: "/runtime/node/bin/node",
    openClawEntry: "/runtime/openclaw/index.js",
    defaultConfigPath: "/runtime/config/openclaw.json",
    runtimeDataDir: "/runtime-data",
    runtimeStateDir: "/runtime-data/state",
    runtimeLogsDir: "/runtime-data/logs",
    logFilePath: "/runtime-data/logs/runtime.log",
    gatewayUrl,
    gatewayTokenConfigured: true,
    message: processState === "running" ? "Managed bundled runtime process is running and Gateway is ready." : "Runtime stopped.",
    modeReason: "test",
    detectedFiles: [],
    missingFiles: []
  }
}

function makeRuntimeCloud(): RuntimeCloudStatus {
  return {
    state: "ready",
    baseUrl: "https://runtime.example.test",
    apiKeyConfigured: true
  }
}

function makeGatewayError(gatewayUrl = "ws://127.0.0.1:18889"): GatewayStatus {
  const parsedGatewayUrl = new URL(gatewayUrl)
  return {
    state: "error",
    url: gatewayUrl,
    host: parsedGatewayUrl.hostname,
    port: Number(parsedGatewayUrl.port),
    version: "unknown",
    transport: "websocket",
    lastError: "Gateway closed during connect (1006)."
  }
}

function summarize(input: {
  runtimeStatus: RuntimeStatus;
  gatewayStatus: GatewayStatus;
  warmupInFlight?: boolean;
}) {
  return buildChatSummary({
    config: makeConfig(),
    runtimeStatus: input.runtimeStatus,
    runtimeCloudStatus: makeRuntimeCloud(),
    gatewayStatus: input.gatewayStatus,
    warmupInFlight: input.warmupInFlight ?? false,
    runtimeCloudRefreshInFlight: false,
    runtimeCloudConfigSyncInFlight: false,
    isPackaged: false
  })
}

test("stopped bundled runtime with stale transient gateway error does not stay in startup state", () => {
  const summary = summarize({
    runtimeStatus: makeRuntime("stopped"),
    gatewayStatus: makeGatewayError()
  })

  assert.equal(summary.chatLaunchState, "error")
  assert.equal(summary.startupPhase, "error")
})

test("running bundled runtime with stale transient gateway error remains in gateway startup state", () => {
  const summary = summarize({
    runtimeStatus: makeRuntime("running"),
    gatewayStatus: makeGatewayError()
  })

  assert.equal(summary.chatLaunchState, "starting")
  assert.equal(summary.startupPhase, "connecting-gateway")
})

test("running bundled runtime with transient gateway error on current target reports an error", () => {
  const summary = summarize({
    runtimeStatus: makeRuntime("running", "ws://127.0.0.1:51079"),
    gatewayStatus: makeGatewayError("ws://127.0.0.1:51079")
  })

  assert.equal(summary.chatLaunchState, "error")
  assert.equal(summary.startupPhase, "error")
})

test("starting bundled runtime with transient gateway error remains in gateway startup state", () => {
  const summary = summarize({
    runtimeStatus: makeRuntime("starting", "ws://127.0.0.1:51079"),
    gatewayStatus: makeGatewayError("ws://127.0.0.1:51079")
  })

  assert.equal(summary.chatLaunchState, "starting")
  assert.equal(summary.startupPhase, "connecting-gateway")
})
