import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
import { buildWorkspaceSkillStatus, } from "../agents/skills-status.js";
import { loadConfig } from "../config/config.js";
import { defaultRuntime } from "../runtime.js";
import { formatDocsLink } from "../terminal/links.js";
import { renderTable } from "../terminal/table.js";
import { theme } from "../terminal/theme.js";
import { shortenHomePath } from "../utils.js";
import { formatCliCommand } from "./command-format.js";
function appendClawdHubHint(output, json) {
    if (json)
        return output;
    return `${output}\n\nTip: use \`npx clawdhub\` to search, install, and sync skills.`;
}
function formatSkillStatus(skill) {
    if (skill.eligible)
        return theme.success("✓ ready");
    if (skill.disabled)
        return theme.warn("⏸ disabled");
    if (skill.blockedByAllowlist)
        return theme.warn("🚫 blocked");
    return theme.error("✗ missing");
}
function formatSkillName(skill) {
    const emoji = skill.emoji ?? "📦";
    return `${emoji} ${theme.command(skill.name)}`;
}
function formatSkillMissingSummary(skill) {
    const missing = [];
    if (skill.missing.bins.length > 0) {
        missing.push(`bins: ${skill.missing.bins.join(", ")}`);
    }
    if (skill.missing.anyBins.length > 0) {
        missing.push(`anyBins: ${skill.missing.anyBins.join(", ")}`);
    }
    if (skill.missing.env.length > 0) {
        missing.push(`env: ${skill.missing.env.join(", ")}`);
    }
    if (skill.missing.config.length > 0) {
        missing.push(`config: ${skill.missing.config.join(", ")}`);
    }
    if (skill.missing.os.length > 0) {
        missing.push(`os: ${skill.missing.os.join(", ")}`);
    }
    return missing.join("; ");
}
/**
 * Format the skills list output
 */
export function formatSkillsList(report, opts) {
    const skills = opts.eligible ? report.skills.filter((s) => s.eligible) : report.skills;
    if (opts.json) {
        const jsonReport = {
            workspaceDir: report.workspaceDir,
            managedSkillsDir: report.managedSkillsDir,
            skills: skills.map((s) => ({
                name: s.name,
                description: s.description,
                emoji: s.emoji,
                eligible: s.eligible,
                disabled: s.disabled,
                blockedByAllowlist: s.blockedByAllowlist,
                source: s.source,
                primaryEnv: s.primaryEnv,
                homepage: s.homepage,
                missing: s.missing,
            })),
        };
        return JSON.stringify(jsonReport, null, 2);
    }
    if (skills.length === 0) {
        const message = opts.eligible
            ? `No eligible skills found. Run \`${formatCliCommand("openclaw-cn skills list")}\` to see all skills.`
            : "No skills found.";
        return appendClawdHubHint(message, opts.json);
    }
    const eligible = skills.filter((s) => s.eligible);
    const tableWidth = Math.max(60, (process.stdout.columns ?? 120) - 1);
    const rows = skills.map((skill) => {
        const missing = formatSkillMissingSummary(skill);
        return {
            Status: formatSkillStatus(skill),
            Skill: formatSkillName(skill),
            Description: theme.muted(skill.description),
            Source: skill.source ?? "",
            Missing: missing ? theme.warn(missing) : "",
        };
    });
    const columns = [
        { key: "Status", header: "Status", minWidth: 10 },
        { key: "Skill", header: "Skill", minWidth: 18, flex: true },
        { key: "Description", header: "Description", minWidth: 24, flex: true },
        { key: "Source", header: "Source", minWidth: 10 },
    ];
    if (opts.verbose) {
        columns.push({ key: "Missing", header: "Missing", minWidth: 18, flex: true });
    }
    const lines = [];
    lines.push(`${theme.heading("Skills")} ${theme.muted(`(${eligible.length}/${skills.length} ready)`)}`);
    lines.push(renderTable({
        width: tableWidth,
        columns,
        rows,
    }).trimEnd());
    return appendClawdHubHint(lines.join("\n"), opts.json);
}
/**
 * Format detailed info for a single skill
 */
export function formatSkillInfo(report, skillName, opts) {
    const skill = report.skills.find((s) => s.name === skillName || s.skillKey === skillName);
    if (!skill) {
        if (opts.json) {
            return JSON.stringify({ error: "not found", skill: skillName }, null, 2);
        }
        return appendClawdHubHint(`Skill "${skillName}" not found. Run \`${formatCliCommand("openclaw-cn skills list")}\` to see available skills.`, opts.json);
    }
    if (opts.json) {
        return JSON.stringify(skill, null, 2);
    }
    const lines = [];
    const emoji = skill.emoji ?? "📦";
    const status = skill.eligible
        ? theme.success("✓ Ready")
        : skill.disabled
            ? theme.warn("⏸ Disabled")
            : skill.blockedByAllowlist
                ? theme.warn("🚫 Blocked by allowlist")
                : theme.error("✗ Missing requirements");
    lines.push(`${emoji} ${theme.heading(skill.name)} ${status}`);
    lines.push("");
    lines.push(skill.description);
    lines.push("");
    // Details
    lines.push(theme.heading("Details:"));
    lines.push(`${theme.muted("  Source:")} ${skill.source}`);
    lines.push(`${theme.muted("  Path:")} ${shortenHomePath(skill.filePath)}`);
    if (skill.homepage) {
        lines.push(`${theme.muted("  Homepage:")} ${skill.homepage}`);
    }
    if (skill.primaryEnv) {
        lines.push(`${theme.muted("  Primary env:")} ${skill.primaryEnv}`);
    }
    // Requirements
    const hasRequirements = skill.requirements.bins.length > 0 ||
        skill.requirements.anyBins.length > 0 ||
        skill.requirements.env.length > 0 ||
        skill.requirements.config.length > 0 ||
        skill.requirements.os.length > 0;
    if (hasRequirements) {
        lines.push("");
        lines.push(theme.heading("Requirements:"));
        if (skill.requirements.bins.length > 0) {
            const binsStatus = skill.requirements.bins.map((bin) => {
                const missing = skill.missing.bins.includes(bin);
                return missing ? theme.error(`✗ ${bin}`) : theme.success(`✓ ${bin}`);
            });
            lines.push(`${theme.muted("  Binaries:")} ${binsStatus.join(", ")}`);
        }
        if (skill.requirements.anyBins.length > 0) {
            const anyBinsMissing = skill.missing.anyBins.length > 0;
            const anyBinsStatus = skill.requirements.anyBins.map((bin) => {
                const missing = anyBinsMissing;
                return missing ? theme.error(`✗ ${bin}`) : theme.success(`✓ ${bin}`);
            });
            lines.push(`${theme.muted("  Any binaries:")} ${anyBinsStatus.join(", ")}`);
        }
        if (skill.requirements.env.length > 0) {
            const envStatus = skill.requirements.env.map((env) => {
                const missing = skill.missing.env.includes(env);
                return missing ? theme.error(`✗ ${env}`) : theme.success(`✓ ${env}`);
            });
            lines.push(`${theme.muted("  Environment:")} ${envStatus.join(", ")}`);
        }
        if (skill.requirements.config.length > 0) {
            const configStatus = skill.requirements.config.map((cfg) => {
                const missing = skill.missing.config.includes(cfg);
                return missing ? theme.error(`✗ ${cfg}`) : theme.success(`✓ ${cfg}`);
            });
            lines.push(`${theme.muted("  Config:")} ${configStatus.join(", ")}`);
        }
        if (skill.requirements.os.length > 0) {
            const osStatus = skill.requirements.os.map((osName) => {
                const missing = skill.missing.os.includes(osName);
                return missing ? theme.error(`✗ ${osName}`) : theme.success(`✓ ${osName}`);
            });
            lines.push(`${theme.muted("  OS:")} ${osStatus.join(", ")}`);
        }
    }
    // Install options
    if (skill.install.length > 0 && !skill.eligible) {
        lines.push("");
        lines.push(theme.heading("Install options:"));
        for (const inst of skill.install) {
            lines.push(`  ${theme.warn("→")} ${inst.label}`);
        }
    }
    return appendClawdHubHint(lines.join("\n"), opts.json);
}
/**
 * Format a check/summary of all skills status
 */
export function formatSkillsCheck(report, opts) {
    const eligible = report.skills.filter((s) => s.eligible);
    const disabled = report.skills.filter((s) => s.disabled);
    const blocked = report.skills.filter((s) => s.blockedByAllowlist && !s.disabled);
    const missingReqs = report.skills.filter((s) => !s.eligible && !s.disabled && !s.blockedByAllowlist);
    if (opts.json) {
        return JSON.stringify({
            summary: {
                total: report.skills.length,
                eligible: eligible.length,
                disabled: disabled.length,
                blocked: blocked.length,
                missingRequirements: missingReqs.length,
            },
            eligible: eligible.map((s) => s.name),
            disabled: disabled.map((s) => s.name),
            blocked: blocked.map((s) => s.name),
            missingRequirements: missingReqs.map((s) => ({
                name: s.name,
                missing: s.missing,
                install: s.install,
            })),
        }, null, 2);
    }
    const lines = [];
    lines.push(theme.heading("Skills Status Check"));
    lines.push("");
    lines.push(`${theme.muted("Total:")} ${report.skills.length}`);
    lines.push(`${theme.success("✓")} ${theme.muted("Eligible:")} ${eligible.length}`);
    lines.push(`${theme.warn("⏸")} ${theme.muted("Disabled:")} ${disabled.length}`);
    lines.push(`${theme.warn("🚫")} ${theme.muted("Blocked by allowlist:")} ${blocked.length}`);
    lines.push(`${theme.error("✗")} ${theme.muted("Missing requirements:")} ${missingReqs.length}`);
    if (eligible.length > 0) {
        lines.push("");
        lines.push(theme.heading("Ready to use:"));
        for (const skill of eligible) {
            const emoji = skill.emoji ?? "📦";
            lines.push(`  ${emoji} ${skill.name}`);
        }
    }
    if (missingReqs.length > 0) {
        lines.push("");
        lines.push(theme.heading("Missing requirements:"));
        for (const skill of missingReqs) {
            const emoji = skill.emoji ?? "📦";
            const missing = [];
            if (skill.missing.bins.length > 0) {
                missing.push(`bins: ${skill.missing.bins.join(", ")}`);
            }
            if (skill.missing.anyBins.length > 0) {
                missing.push(`anyBins: ${skill.missing.anyBins.join(", ")}`);
            }
            if (skill.missing.env.length > 0) {
                missing.push(`env: ${skill.missing.env.join(", ")}`);
            }
            if (skill.missing.config.length > 0) {
                missing.push(`config: ${skill.missing.config.join(", ")}`);
            }
            if (skill.missing.os.length > 0) {
                missing.push(`os: ${skill.missing.os.join(", ")}`);
            }
            lines.push(`  ${emoji} ${skill.name} ${theme.muted(`(${missing.join("; ")})`)}`);
        }
    }
    return appendClawdHubHint(lines.join("\n"), opts.json);
}
/**
 * Register the skills CLI commands
 */
export function registerSkillsCli(program) {
    const skills = program
        .command("skills")
        .description("列出和检查可用的技能")
        .addHelpText("after", () => `\n${theme.muted("文档：")} ${formatDocsLink("/cli/skills", "docs.clawd.bot/cli/skills")}\n`);
    skills
        .command("list")
        .description("列出所有可用技能")
        .option("--json", "输出 JSON", false)
        .option("--eligible", "仅显示符合条件（可使用）的技能", false)
        .option("-v, --verbose", "显示更多详情，包括缺失的需求", false)
        .action(async (opts) => {
        try {
            const config = loadConfig();
            const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config));
            const report = buildWorkspaceSkillStatus(workspaceDir, { config });
            defaultRuntime.log(formatSkillsList(report, opts));
        }
        catch (err) {
            defaultRuntime.error(String(err));
            defaultRuntime.exit(1);
        }
    });
    skills
        .command("info")
        .description("显示技能的详细信息")
        .argument("<name>", "技能名称")
        .option("--json", "输出 JSON", false)
        .action(async (name, opts) => {
        try {
            const config = loadConfig();
            const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config));
            const report = buildWorkspaceSkillStatus(workspaceDir, { config });
            defaultRuntime.log(formatSkillInfo(report, name, opts));
        }
        catch (err) {
            defaultRuntime.error(String(err));
            defaultRuntime.exit(1);
        }
    });
    skills
        .command("check")
        .description("检查哪些技能已就绪 vs 缺失需求")
        .option("--json", "输出 JSON", false)
        .action(async (opts) => {
        try {
            const config = loadConfig();
            const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config));
            const report = buildWorkspaceSkillStatus(workspaceDir, { config });
            defaultRuntime.log(formatSkillsCheck(report, opts));
        }
        catch (err) {
            defaultRuntime.error(String(err));
            defaultRuntime.exit(1);
        }
    });
    // Default action (no subcommand) - show list
    skills.action(async () => {
        try {
            const config = loadConfig();
            const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config));
            const report = buildWorkspaceSkillStatus(workspaceDir, { config });
            defaultRuntime.log(formatSkillsList(report, {}));
        }
        catch (err) {
            defaultRuntime.error(String(err));
            defaultRuntime.exit(1);
        }
    });
}
