import { existsSync } from "node:fs";
import { homedir } from "node:os";
import { join } from "node:path";

export type AgentId = "claude" | "codex" | "cursor" | "windsurf";

export interface DetectedAgent {
  id: AgentId;
  name: string;
  detected: boolean;
  globalPath: string | null;
  localPath: string | null;
  description: string;
  hint: string;
}

interface AgentDefinition {
  id: AgentId;
  name: string;
  description: string;
  hint: string;
  globalPaths: string[];
  localPaths: string[];
}

const AGENT_DEFINITIONS: AgentDefinition[] = [
  {
    id: "claude",
    name: "Claude Code",
    description: "Anthropic CLI agent",
    hint: "/hmy <card>",
    globalPaths: [join(homedir(), ".claude")],
    localPaths: [".claude"],
  },
  {
    id: "codex",
    name: "Codex",
    description: "OpenAI coding agent",
    hint: "/prompts:hmy <card>",
    globalPaths: [join(homedir(), ".codex")],
    localPaths: ["AGENTS.md"],
  },
  {
    id: "cursor",
    name: "Cursor",
    description: "AI-powered IDE",
    hint: "MCP tools available automatically",
    globalPaths: [],
    localPaths: [".cursor", ".cursorrules"],
  },
  {
    id: "windsurf",
    name: "Windsurf",
    description: "Codeium AI IDE",
    hint: "MCP tools available automatically",
    globalPaths: [join(homedir(), ".codeium", "windsurf")],
    localPaths: [".windsurf", ".windsurfrules"],
  },
];

/**
 * Detect installed agents by checking for config directories
 */
export function detectAgents(cwd: string = process.cwd()): DetectedAgent[] {
  return AGENT_DEFINITIONS.map((def) => {
    // Check global paths
    const globalPath = def.globalPaths.find((p) => existsSync(p)) || null;

    // Check local paths
    const localPath =
      def.localPaths.find((p) => existsSync(join(cwd, p))) || null;

    return {
      id: def.id,
      name: def.name,
      detected: !!(globalPath || localPath),
      globalPath,
      localPath: localPath ? join(cwd, localPath) : null,
      description: def.description,
      hint: def.hint,
    };
  });
}

/**
 * Get agent by ID
 */
export function getAgentById(id: AgentId): AgentDefinition | undefined {
  return AGENT_DEFINITIONS.find((def) => def.id === id);
}

/**
 * Get all supported agent IDs
 */
export function getSupportedAgentIds(): AgentId[] {
  return AGENT_DEFINITIONS.map((def) => def.id);
}

/**
 * Get config paths that will be created for an agent
 */
export function getAgentConfigPaths(
  agentId: AgentId,
  cwd: string = process.cwd(),
): { global: string[]; local: string[] } {
  const home = homedir();

  switch (agentId) {
    case "claude":
      return {
        global: [join(home, ".claude", "settings.json")],
        local: [join(cwd, ".claude", "skills", "hmy", "SKILL.md")],
      };
    case "codex":
      return {
        global: [
          join(home, ".codex", "config.toml"),
          join(home, ".codex", "prompts", "hmy.md"),
        ],
        local: [join(cwd, "AGENTS.md")],
      };
    case "cursor":
      return {
        global: [],
        local: [
          join(cwd, ".cursor", "mcp.json"),
          join(cwd, ".cursor", "rules", "harmony.mdc"),
        ],
      };
    case "windsurf":
      return {
        global: [join(home, ".codeium", "windsurf", "mcp_config.json")],
        local: [join(cwd, ".windsurf", "rules", "harmony.md")],
      };
    default:
      return { global: [], local: [] };
  }
}

/**
 * Format agent for display in selection
 */
export function formatAgentOption(agent: DetectedAgent): {
  value: AgentId;
  label: string;
  hint: string;
} {
  const status = agent.detected ? "(detected)" : "(not detected)";
  return {
    value: agent.id,
    label: `${agent.name}`,
    hint: `${agent.description} ${status}`,
  };
}
