import { Config } from "effect"

function getEnv(key: string): string | undefined {
  if (key.startsWith("WOOZLIT_CODE_")) {
    const woozlitKey = key.replace("WOOZLIT_CODE_", "WOOZLITCODE_")
    return process.env[woozlitKey] || process.env[key]
  }
  return process.env[key]
}

function truthy(key: string) {
  const value = getEnv(key)?.toLowerCase()
  return value === "true" || value === "1"
}

function falsy(key: string) {
  const value = getEnv(key)?.toLowerCase()
  return value === "false" || value === "0"
}

function number(key: string) {
  const value = getEnv(key)
  if (!value) return undefined
  const parsed = Number(value)
  return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined
}

const WOOZLIT_CODE_EXPERIMENTAL = truthy("WOOZLIT_CODE_EXPERIMENTAL")

// Defaults to false. When enabled, WOOZLIT_CODE runs in pure-mimo mode:
//   — does NOT inherit Claude Code's settings (CLAUDE.md, ~/.claude/skills, etc.)
//   — does NOT pick up provider API keys from environment variables
//   — falls back to the mimo-auto model as the default
// Set WOOZLIT_CODE_MIMO_ONLY=true to disable .claude inheritance and env-based
// provider auto-detection.
const WOOZLIT_CODE_MIMO_ONLY = truthy("WOOZLIT_CODE_MIMO_ONLY")
const WOOZLIT_CODE_DISABLE_CLAUDE_CODE_ENV = truthy("WOOZLIT_CODE_DISABLE_CLAUDE_CODE")
const WOOZLIT_CODE_DISABLE_CLAUDE_CODE = WOOZLIT_CODE_MIMO_ONLY || WOOZLIT_CODE_DISABLE_CLAUDE_CODE_ENV

const WOOZLIT_CODE_DISABLE_EXTERNAL_SKILLS = truthy("WOOZLIT_CODE_DISABLE_EXTERNAL_SKILLS")
const WOOZLIT_CODE_DISABLE_CLAUDE_CODE_SKILLS =
  WOOZLIT_CODE_DISABLE_EXTERNAL_SKILLS || WOOZLIT_CODE_DISABLE_CLAUDE_CODE || truthy("WOOZLIT_CODE_DISABLE_CLAUDE_CODE_SKILLS")
const copy = getEnv("WOOZLIT_CODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT")

export const Flag = {
  OTEL_EXPORTER_OTLP_ENDPOINT: process.env["OTEL_EXPORTER_OTLP_ENDPOINT"],
  OTEL_EXPORTER_OTLP_HEADERS: process.env["OTEL_EXPORTER_OTLP_HEADERS"],

  WOOZLIT_CODE_AUTO_SHARE: truthy("WOOZLIT_CODE_AUTO_SHARE"),
  WOOZLIT_CODE_AUTO_HEAP_SNAPSHOT: truthy("WOOZLIT_CODE_AUTO_HEAP_SNAPSHOT"),
  WOOZLIT_CODE_GIT_BASH_PATH: getEnv("WOOZLIT_CODE_GIT_BASH_PATH"),
  WOOZLIT_CODE_CONFIG: getEnv("WOOZLIT_CODE_CONFIG"),
  WOOZLIT_CODE_CONFIG_CONTENT: getEnv("WOOZLIT_CODE_CONFIG_CONTENT"),

  WOOZLIT_CODE_DISABLE_AUTOUPDATE: truthy("WOOZLIT_CODE_DISABLE_AUTOUPDATE"),

  // Defaults to true (analytics enabled). Set WOOZLIT_CODE_ENABLE_ANALYSIS=false
  // to opt out of POSTing model_call/tool_call/agent_request metrics.
  WOOZLIT_CODE_ENABLE_ANALYSIS: !falsy("WOOZLIT_CODE_ENABLE_ANALYSIS"),
  WOOZLIT_CODE_ALWAYS_NOTIFY_UPDATE: truthy("WOOZLIT_CODE_ALWAYS_NOTIFY_UPDATE"),
  WOOZLIT_CODE_DISABLE_PRUNE: truthy("WOOZLIT_CODE_DISABLE_PRUNE"),
  WOOZLIT_CODE_DISABLE_TERMINAL_TITLE: truthy("WOOZLIT_CODE_DISABLE_TERMINAL_TITLE"),
  WOOZLIT_CODE_SHOW_TTFD: truthy("WOOZLIT_CODE_SHOW_TTFD"),
  WOOZLIT_CODE_PERMISSION: getEnv("WOOZLIT_CODE_PERMISSION"),
  WOOZLIT_CODE_DISABLE_DEFAULT_PLUGINS: truthy("WOOZLIT_CODE_DISABLE_DEFAULT_PLUGINS"),
  WOOZLIT_CODE_DISABLE_LSP_DOWNLOAD: truthy("WOOZLIT_CODE_DISABLE_LSP_DOWNLOAD"),
  WOOZLIT_CODE_ENABLE_EXPERIMENTAL_MODELS: truthy("WOOZLIT_CODE_ENABLE_EXPERIMENTAL_MODELS"),
  WOOZLIT_CODE_DISABLE_AUTOCOMPACT: truthy("WOOZLIT_CODE_DISABLE_AUTOCOMPACT"),
  WOOZLIT_CODE_DISABLE_MODELS_FETCH: truthy("WOOZLIT_CODE_DISABLE_MODELS_FETCH"),
  WOOZLIT_CODE_DISABLE_MOUSE: truthy("WOOZLIT_CODE_DISABLE_MOUSE"),
  WOOZLIT_CODE_OUTPUT_LENGTH_CONTINUATION_LIMIT: number("WOOZLIT_CODE_OUTPUT_LENGTH_CONTINUATION_LIMIT") ?? 3,
  WOOZLIT_CODE_INVALID_OUTPUT_CONTINUATION_LIMIT: number("WOOZLIT_CODE_INVALID_OUTPUT_CONTINUATION_LIMIT") ?? 2,

  // Caps applied to image attachments before a prompt is sent. Both default to
  // undefined (no limit). WOOZLIT_CODE_MAX_PROMPT_IMAGES bounds how many images may
  // be sent per request (oldest excess images are dropped); WOOZLIT_CODE_MAX_PROMPT_IMAGE_SIZE
  // bounds the decoded byte size of a single image. Values must be positive integers.
  WOOZLIT_CODE_MAX_PROMPT_IMAGES: number("WOOZLIT_CODE_MAX_PROMPT_IMAGES"),
  WOOZLIT_CODE_MAX_PROMPT_IMAGE_SIZE: number("WOOZLIT_CODE_MAX_PROMPT_IMAGE_SIZE"),
  WOOZLIT_CODE_MIMO_ONLY,
  WOOZLIT_CODE_DISABLE_PROVIDER_ENV: WOOZLIT_CODE_MIMO_ONLY || truthy("WOOZLIT_CODE_DISABLE_PROVIDER_ENV"),
  WOOZLIT_CODE_DISABLE_CLAUDE_CODE,
  get WOOZLIT_CODE_DISABLE_CLAUDE_CODE_MCP() {
    // MCP compatibility stays on in mimo-only mode so users can reuse Claude Code
    // MCP servers without inheriting prompts, skills, or provider env keys.
    return WOOZLIT_CODE_DISABLE_CLAUDE_CODE_ENV || truthy("WOOZLIT_CODE_DISABLE_CLAUDE_CODE_MCP")
  },
  WOOZLIT_CODE_DISABLE_CLAUDE_CODE_PROMPT: WOOZLIT_CODE_DISABLE_CLAUDE_CODE || truthy("WOOZLIT_CODE_DISABLE_CLAUDE_CODE_PROMPT"),
  // Defaults to false (enabled): markdown commands under ~/.claude/commands and
  // {project}/.claude/commands load as slash commands. Independent of the
  // mimo-only master switch. Set WOOZLIT_CODE_DISABLE_CLAUDE_CODE_COMMANDS=true to disable.
  WOOZLIT_CODE_DISABLE_CLAUDE_CODE_COMMANDS: truthy("WOOZLIT_CODE_DISABLE_CLAUDE_CODE_COMMANDS"),
  WOOZLIT_CODE_DISABLE_CLAUDE_CODE_SKILLS,
  WOOZLIT_CODE_DISABLE_EXTERNAL_SKILLS,
  WOOZLIT_CODE_DISABLE_CODEX_SKILLS: WOOZLIT_CODE_DISABLE_EXTERNAL_SKILLS || truthy("WOOZLIT_CODE_DISABLE_CODEX_SKILLS"),
  WOOZLIT_CODE_DISABLE_OPENCODE_SKILLS: WOOZLIT_CODE_DISABLE_EXTERNAL_SKILLS || truthy("WOOZLIT_CODE_DISABLE_OPENCODE_SKILLS"),
  WOOZLIT_CODE_FAKE_VCS: getEnv("WOOZLIT_CODE_FAKE_VCS"),

  // When enabled, skips all git subprocess calls during project discovery
  // (which git, rev-parse --git-common-dir, rev-parse --show-toplevel) and
  // branch detection. The project is treated as a non-git directory rooted at
  // the working directory. Use to avoid touching git in restricted/sandboxed
  // environments or where git startup probing is undesirable.
  WOOZLIT_CODE_DISABLE_GIT: truthy("WOOZLIT_CODE_DISABLE_GIT"),
  WOOZLIT_CODE_SERVER_PASSWORD: getEnv("WOOZLIT_CODE_SERVER_PASSWORD"),
  WOOZLIT_CODE_SERVER_USERNAME: getEnv("WOOZLIT_CODE_SERVER_USERNAME"),
  WOOZLIT_CODE_ENABLE_QUESTION_TOOL: truthy("WOOZLIT_CODE_ENABLE_QUESTION_TOOL"),

  // Experimental
  WOOZLIT_CODE_EXPERIMENTAL,
  WOOZLIT_CODE_EXPERIMENTAL_FILEWATCHER: Config.boolean("WOOZLIT_CODE_EXPERIMENTAL_FILEWATCHER").pipe(
    Config.withDefault(false),
  ),
  WOOZLIT_CODE_EXPERIMENTAL_DISABLE_FILEWATCHER: Config.boolean("WOOZLIT_CODE_EXPERIMENTAL_DISABLE_FILEWATCHER").pipe(
    Config.withDefault(false),
  ),
  WOOZLIT_CODE_EXPERIMENTAL_ICON_DISCOVERY: WOOZLIT_CODE_EXPERIMENTAL || truthy("WOOZLIT_CODE_EXPERIMENTAL_ICON_DISCOVERY"),
  WOOZLIT_CODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT:
    copy === undefined ? process.platform === "win32" : truthy("WOOZLIT_CODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT"),
  WOOZLIT_CODE_ENABLE_EXA: truthy("WOOZLIT_CODE_ENABLE_EXA") || WOOZLIT_CODE_EXPERIMENTAL || truthy("WOOZLIT_CODE_EXPERIMENTAL_EXA"),
  WOOZLIT_CODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS: number("WOOZLIT_CODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS"),
  WOOZLIT_CODE_EXPERIMENTAL_OUTPUT_TOKEN_MAX: number("WOOZLIT_CODE_EXPERIMENTAL_OUTPUT_TOKEN_MAX"),
  WOOZLIT_CODE_EXPERIMENTAL_OXFMT: WOOZLIT_CODE_EXPERIMENTAL || truthy("WOOZLIT_CODE_EXPERIMENTAL_OXFMT"),
  WOOZLIT_CODE_EXPERIMENTAL_LSP_TY: truthy("WOOZLIT_CODE_EXPERIMENTAL_LSP_TY"),
  WOOZLIT_CODE_EXPERIMENTAL_LSP_TOOL: WOOZLIT_CODE_EXPERIMENTAL || truthy("WOOZLIT_CODE_EXPERIMENTAL_LSP_TOOL"),
  WOOZLIT_CODE_EXPERIMENTAL_WORKFLOW_TOOL: WOOZLIT_CODE_EXPERIMENTAL || truthy("WOOZLIT_CODE_EXPERIMENTAL_WORKFLOW_TOOL"),
  WOOZLIT_CODE_EXPERIMENTAL_MARKDOWN: !falsy("WOOZLIT_CODE_EXPERIMENTAL_MARKDOWN"),
  WOOZLIT_CODE_MODELS_URL: getEnv("WOOZLIT_CODE_MODELS_URL"),
  WOOZLIT_CODE_MODELS_PATH: getEnv("WOOZLIT_CODE_MODELS_PATH"),
  WOOZLIT_CODE_DISABLE_EMBEDDED_WEB_UI: truthy("WOOZLIT_CODE_DISABLE_EMBEDDED_WEB_UI"),
  WOOZLIT_CODE_DB: getEnv("WOOZLIT_CODE_DB"),

  // Defaults to true — all channels share a single WOOZLIT_CODE.db. The per-channel
  // DB isolation (WOOZLIT_CODE-{channel}.db) is unnecessary for WOOZLIT_CODE since we
  // don't ship multiple release channels yet. Use WOOZLIT_CODE_HOME to isolate dev
  // environments instead. Set WOOZLIT_CODE_DISABLE_CHANNEL_DB=false to restore
  // per-channel isolation.
  WOOZLIT_CODE_DISABLE_CHANNEL_DB: !falsy("WOOZLIT_CODE_DISABLE_CHANNEL_DB"),
  WOOZLIT_CODE_SKIP_MIGRATIONS: truthy("WOOZLIT_CODE_SKIP_MIGRATIONS"),
  WOOZLIT_CODE_STRICT_CONFIG_DEPS: truthy("WOOZLIT_CODE_STRICT_CONFIG_DEPS"),

  WOOZLIT_CODE_WORKSPACE_ID: getEnv("WOOZLIT_CODE_WORKSPACE_ID"),
  WOOZLIT_CODE_EXPERIMENTAL_HTTPAPI: truthy("WOOZLIT_CODE_EXPERIMENTAL_HTTPAPI"),
  WOOZLIT_CODE_EXPERIMENTAL_WORKSPACES: WOOZLIT_CODE_EXPERIMENTAL || truthy("WOOZLIT_CODE_EXPERIMENTAL_WORKSPACES"),

  // Evaluated at access time (not module load) because tests, the CLI, and
  // external tooling set these env vars at runtime.
  get WOOZLIT_CODE_DISABLE_COMPOSE_SKILLS() {
    return truthy("WOOZLIT_CODE_DISABLE_COMPOSE_SKILLS")
  },
  get WOOZLIT_CODE_DISABLE_PROJECT_CONFIG() {
    return truthy("WOOZLIT_CODE_DISABLE_PROJECT_CONFIG")
  },
  get WOOZLIT_CODE_TUI_CONFIG() {
    return getEnv("WOOZLIT_CODE_TUI_CONFIG")
  },
  get WOOZLIT_CODE_CONFIG_DIR() {
    return getEnv("WOOZLIT_CODE_CONFIG_DIR")
  },
  get WOOZLIT_CODE_HOME() {
    return getEnv("WOOZLIT_CODE_HOME")
  },
  get WOOZLIT_CODE_PURE() {
    return truthy("WOOZLIT_CODE_PURE")
  },
  get WOOZLIT_CODE_PLUGIN_META_FILE() {
    return getEnv("WOOZLIT_CODE_PLUGIN_META_FILE")
  },
  get WOOZLIT_CODE_CLIENT() {
    return getEnv("WOOZLIT_CODE_CLIENT") ?? "cli"
  },
}
