import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync } from 'node:fs';
import { mkdir } from 'node:fs/promises';
import { homedir } from 'node:os';
import { j as join, b as basename } from '../shared/ccjk.bQ7Dh1g4.mjs';
import { i18n } from './index2.mjs';
import 'node:process';
import 'node:url';

const DEFAULT_COMPACT_CONFIG = {
  warningThreshold: 0.7,
  // 70% 时警告
  compactThreshold: 0.85,
  // 85% 时建议清理
  messageThreshold: 100,
  // 100 条消息
  planningMessageThreshold: 50,
  // Plan 阶段 50 条消息
  defaultMaxTokens: 2e5
  // 200k tokens (Claude 3.5 Sonnet)
};
class CompactAdvisor {
  config;
  constructor(config = {}) {
    this.config = { ...DEFAULT_COMPACT_CONFIG, ...config };
  }
  /**
   * 检测是否需要建议 compact
   */
  shouldSuggestCompact(context) {
    const maxTokens = context.maxTokens || this.config.defaultMaxTokens;
    const usagePercent = context.currentTokens / maxTokens;
    if (usagePercent >= this.config.compactThreshold) {
      return {
        shouldCompact: true,
        reason: "token_threshold",
        message: this.getTokenThresholdMessage(usagePercent, context.currentTokens, maxTokens),
        usagePercent,
        estimatedSavings: Math.floor(context.currentTokens * 0.6),
        // 预计节省 60%
        suggestedActions: this.getSuggestedActions("token_threshold")
      };
    }
    if (context.messageCount >= this.config.messageThreshold) {
      return {
        shouldCompact: true,
        reason: "message_threshold",
        message: this.getMessageThresholdMessage(context.messageCount),
        usagePercent,
        estimatedSavings: Math.floor(context.currentTokens * 0.5),
        suggestedActions: this.getSuggestedActions("message_threshold")
      };
    }
    if (usagePercent >= this.config.warningThreshold) {
      return {
        shouldCompact: false,
        message: this.getWarningMessage(usagePercent, context.currentTokens, maxTokens),
        usagePercent,
        suggestedActions: []
      };
    }
    return {
      shouldCompact: false,
      message: this.getHealthyMessage(usagePercent),
      usagePercent,
      suggestedActions: []
    };
  }
  /**
   * 检测 Plan 阶段完成
   */
  detectPlanCompletion(planContent) {
    const completionPatterns = [
      /##\s*(实施计划|Implementation Plan|执行计划)/i,
      /##\s*(任务(清单|列表)|Task List|Tasks)/i,
      /##\s*(验收标准|Acceptance Criteria)/i,
      /✅\s*(规划完成|Plan Complete|Planning Complete)/i,
      /---[\t\v\f\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*\n\s*💡\s*(下一步|Next Step)/i
    ];
    return completionPatterns.some((pattern) => pattern.test(planContent));
  }
  /**
   * 生成 Plan 完成后的建议
   */
  generatePlanCompleteSuggestion(plan, context) {
    const maxTokens = context.maxTokens || this.config.defaultMaxTokens;
    const usagePercent = context.currentTokens / maxTokens;
    const planningMessages = context.planningMessageCount || 0;
    const shouldCompact = planningMessages >= this.config.planningMessageThreshold || usagePercent >= 0.3;
    return {
      shouldCompact,
      reason: "plan_complete",
      message: this.getPlanCompleteMessage(plan, context, usagePercent),
      usagePercent,
      estimatedSavings: Math.floor(context.currentTokens * 0.7),
      // Plan 阶段可节省 70%
      suggestedActions: this.getSuggestedActions("plan_complete")
    };
  }
  /**
   * 生成建议输出（用于显示给用户）
   */
  generateSuggestionOutput(suggestion, planPath) {
    const lines = [];
    const isZh = i18n.language === "zh-CN";
    lines.push("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
    if (suggestion.reason === "plan_complete") {
      lines.push(isZh ? "\u2705 \u89C4\u5212\u5B8C\u6210\uFF01" : "\u2705 Planning Complete!");
    } else if (suggestion.shouldCompact) {
      lines.push(isZh ? "\u26A0\uFE0F \u4E0A\u4E0B\u6587\u4F7F\u7528\u7387\u8F83\u9AD8" : "\u26A0\uFE0F High Context Usage");
    } else {
      lines.push(isZh ? "\u{1F4CA} \u4E0A\u4E0B\u6587\u72B6\u6001" : "\u{1F4CA} Context Status");
    }
    lines.push("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
    lines.push("");
    if (planPath) {
      lines.push(isZh ? `\u{1F4C4} Plan \u5DF2\u4FDD\u5B58: ${planPath}` : `\u{1F4C4} Plan saved: ${planPath}`);
      lines.push("");
    }
    lines.push(isZh ? "\u{1F4CA} \u5F53\u524D\u4E0A\u4E0B\u6587\u72B6\u6001:" : "\u{1F4CA} Current context status:");
    lines.push(`   \u2022 Token ${isZh ? "\u4F7F\u7528" : "usage"}: ${(suggestion.usagePercent * 100).toFixed(1)}%`);
    if (suggestion.estimatedSavings) {
      lines.push(`   \u2022 ${isZh ? "\u9884\u8BA1\u53EF\u8282\u7701" : "Estimated savings"}: ~${this.formatTokens(suggestion.estimatedSavings)} tokens`);
    }
    lines.push("");
    lines.push(suggestion.message);
    lines.push("");
    if (suggestion.shouldCompact && suggestion.suggestedActions.length > 0) {
      lines.push(isZh ? "\u{1F4A1} \u5EFA\u8BAE\u64CD\u4F5C:" : "\u{1F4A1} Suggested actions:");
      lines.push("");
      for (let i = 0; i < suggestion.suggestedActions.length; i++) {
        lines.push(`   [${i + 1}] ${suggestion.suggestedActions[i]}`);
      }
      lines.push("");
    }
    lines.push("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
    return lines.join("\n");
  }
  // ==========================================================================
  // Private Helpers
  // ==========================================================================
  getTokenThresholdMessage(usagePercent, current, max) {
    const isZh = i18n.language === "zh-CN";
    const percent = (usagePercent * 100).toFixed(1);
    if (isZh) {
      return `\u4E0A\u4E0B\u6587\u4F7F\u7528\u7387\u5DF2\u8FBE ${percent}%\uFF08${this.formatTokens(current)} / ${this.formatTokens(max)}\uFF09\uFF0C\u5EFA\u8BAE\u6E05\u7406\u4EE5\u907F\u514D\u6027\u80FD\u4E0B\u964D\u3002`;
    }
    return `Context usage at ${percent}% (${this.formatTokens(current)} / ${this.formatTokens(max)}). Consider clearing to maintain performance.`;
  }
  getMessageThresholdMessage(count) {
    const isZh = i18n.language === "zh-CN";
    if (isZh) {
      return `\u5F53\u524D\u4F1A\u8BDD\u5DF2\u6709 ${count} \u6761\u6D88\u606F\uFF0C\u5EFA\u8BAE\u6E05\u7406\u4EE5\u4FDD\u6301\u54CD\u5E94\u8D28\u91CF\u3002`;
    }
    return `Current session has ${count} messages. Consider clearing to maintain response quality.`;
  }
  getWarningMessage(usagePercent, _current, _max) {
    const isZh = i18n.language === "zh-CN";
    const percent = (usagePercent * 100).toFixed(1);
    if (isZh) {
      return `\u26A0\uFE0F \u4E0A\u4E0B\u6587\u4F7F\u7528\u7387 ${percent}%\uFF0C\u63A5\u8FD1\u9608\u503C\u3002\u7EE7\u7EED\u5DE5\u4F5C\u65F6\u8BF7\u6CE8\u610F\u3002`;
    }
    return `\u26A0\uFE0F Context usage at ${percent}%, approaching threshold. Monitor as you continue.`;
  }
  getHealthyMessage(usagePercent) {
    const isZh = i18n.language === "zh-CN";
    const percent = (usagePercent * 100).toFixed(1);
    if (isZh) {
      return `\u2705 \u4E0A\u4E0B\u6587\u72B6\u6001\u826F\u597D\uFF08${percent}%\uFF09\uFF0C\u65E0\u9700\u6E05\u7406\u3002`;
    }
    return `\u2705 Context is healthy (${percent}%), no action needed.`;
  }
  getPlanCompleteMessage(plan, _context, _usagePercent) {
    const isZh = i18n.language === "zh-CN";
    if (isZh) {
      return `Claude Code \u65B0\u529F\u80FD\u652F\u6301\u5728\u63A5\u53D7\u8BA1\u5212\u540E\u81EA\u52A8\u6E05\u7A7A\u4E0A\u4E0B\u6587\uFF0C
\u8FD9\u80FD\u8BA9 Claude \u66F4\u4E13\u6CE8\u4E8E\u6267\u884C\uFF0C\u63D0\u5347\u4EFB\u52A1\u5B8C\u6210\u8D28\u91CF\u3002

Plan "${plan.name}" \u5DF2\u4FDD\u5B58\uFF0C\u60A8\u53EF\u4EE5\u9009\u62E9\uFF1A

\u{1F9F9} \u6E05\u7A7A\u4E0A\u4E0B\u6587\u5E76\u6267\u884C\uFF08\u63A8\u8350\uFF09
   - \u81EA\u52A8\u6E05\u7406\u89C4\u5212\u9636\u6BB5\u7684\u8BA8\u8BBA
   - \u4FDD\u7559 Plan \u6587\u6863\u4F5C\u4E3A\u6267\u884C\u4F9D\u636E
   - \u83B7\u5F97\u5E72\u51C0\u7684\u4E0A\u4E0B\u6587\u7A97\u53E3

\u{1F4CE} \u4FDD\u7559\u4E0A\u4E0B\u6587\u5E76\u6267\u884C
   - \u4FDD\u7559\u6240\u6709\u5386\u53F2\u5BF9\u8BDD
   - \u9002\u5408\u9700\u8981\u53C2\u8003\u8BA8\u8BBA\u7EC6\u8282\u7684\u60C5\u51B5`;
    }
    return `Claude Code now supports automatically clearing context after accepting a plan.
This helps Claude stay focused and improves task completion quality.

Plan "${plan.name}" has been saved. You can choose:

\u{1F9F9} Clear context and execute (Recommended)
   - Automatically clear planning discussions
   - Keep Plan document as execution reference
   - Get a fresh context window

\u{1F4CE} Keep context and execute
   - Preserve all conversation history
   - Suitable when you need to reference discussion details`;
  }
  getSuggestedActions(reason) {
    const isZh = i18n.language === "zh-CN";
    switch (reason) {
      case "plan_complete":
        return isZh ? [
          "\u{1F9F9} \u6E05\u7A7A\u4E0A\u4E0B\u6587\u5E76\u6267\u884C (\u63A8\u8350) - \u4F7F\u7528 Claude Code Plan Mode \u7684\u6E05\u7A7A\u9009\u9879",
          "\u{1F4CE} \u4FDD\u7559\u4E0A\u4E0B\u6587\u5E76\u6267\u884C - \u7EE7\u7EED\u5F53\u524D\u4F1A\u8BDD",
          "\u{1F4BE} \u4EC5\u4FDD\u5B58 Plan - \u7A0D\u540E\u6267\u884C"
        ] : [
          "\u{1F9F9} Clear context and execute (Recommended) - Use Claude Code Plan Mode clear option",
          "\u{1F4CE} Keep context and execute - Continue current session",
          "\u{1F4BE} Save Plan only - Execute later"
        ];
      case "token_threshold":
      case "message_threshold":
        return isZh ? [
          "\u6267\u884C /compact \u538B\u7F29\u4E0A\u4E0B\u6587",
          "\u5F00\u59CB\u65B0\u4F1A\u8BDD",
          "\u4FDD\u5B58\u5F53\u524D\u8FDB\u5EA6\u540E\u6E05\u7406"
        ] : [
          "Run /compact to compress context",
          "Start a new session",
          "Save progress and clear"
        ];
      default:
        return [];
    }
  }
  formatTokens(tokens) {
    if (tokens >= 1e6) {
      return `${(tokens / 1e6).toFixed(1)}M`;
    }
    if (tokens >= 1e3) {
      return `${(tokens / 1e3).toFixed(1)}k`;
    }
    return tokens.toString();
  }
}
let instance$1 = null;
function getCompactAdvisor(config) {
  if (!instance$1) {
    instance$1 = new CompactAdvisor(config);
  }
  return instance$1;
}

class PlanPersistenceManager {
  baseDir;
  projectPlanDir;
  constructor(projectPath) {
    this.baseDir = join(homedir(), ".ccjk", "plans");
    const cwd = projectPath || process.cwd();
    this.projectPlanDir = join(cwd, ".ccjk", "plan", "current");
    this.ensureDirectories();
  }
  ensureDirectories() {
    for (const dir of [this.baseDir, this.projectPlanDir]) {
      if (!existsSync(dir)) {
        mkdirSync(dir, { recursive: true });
      }
    }
  }
  /**
   * 生成 Plan ID
   */
  generateId() {
    return `plan-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`;
  }
  /**
   * 生成安全的文件名
   */
  sanitizeFileName(name) {
    return name.replace(/[<>:"/\\|?*]/g, "-").replace(/\s+/g, "-").replace(/-+/g, "-").substring(0, 50);
  }
  /**
   * 保存 Plan 文档
   */
  savePlan(plan, options = {}) {
    const now = /* @__PURE__ */ new Date();
    const id = this.generateId();
    const document = {
      ...plan,
      id,
      createdAt: now,
      updatedAt: now
    };
    const timestamp = now.toISOString().slice(0, 10).replace(/-/g, "");
    const safeName = this.sanitizeFileName(plan.name);
    const fileName = `${safeName}-${timestamp}.md`;
    const projectFilePath = join(this.projectPlanDir, fileName);
    this.writePlanFile(projectFilePath, document, options.overwrite);
    const globalFilePath = join(this.baseDir, fileName);
    this.writePlanFile(globalFilePath, document, true);
    return document;
  }
  /**
   * 写入 Plan 文件
   */
  writePlanFile(filePath, plan, overwrite = false) {
    if (existsSync(filePath) && !overwrite) {
      const ext = ".md";
      const base = filePath.slice(0, -ext.length);
      let counter = 1;
      let newPath = `${base}-v${counter}${ext}`;
      while (existsSync(newPath)) {
        counter++;
        newPath = `${base}-v${counter}${ext}`;
      }
      filePath = newPath;
    }
    const content = this.buildPlanMarkdown(plan);
    writeFileSync(filePath, content, "utf-8");
  }
  /**
   * 构建 Plan Markdown 内容
   */
  buildPlanMarkdown(plan) {
    const lines = [];
    lines.push("---");
    lines.push(`id: ${plan.id}`);
    lines.push(`name: ${plan.name}`);
    lines.push(`created: ${plan.createdAt.toISOString()}`);
    lines.push(`updated: ${plan.updatedAt.toISOString()}`);
    if (plan.sessionId) {
      lines.push(`session: ${plan.sessionId}`);
    }
    if (plan.sourceSkill) {
      lines.push(`skill: ${plan.sourceSkill}`);
    }
    if (plan.metadata.tokenEstimate) {
      lines.push(`tokens: ${plan.metadata.tokenEstimate}`);
    }
    lines.push("---");
    lines.push("");
    lines.push(plan.content);
    if (plan.metadata.tasks && plan.metadata.tasks.length > 0) {
      lines.push("");
      lines.push("## \u4EFB\u52A1\u6E05\u5355");
      lines.push("");
      for (const task of plan.metadata.tasks) {
        const checkbox = task.completed ? "[x]" : "[ ]";
        const priority = task.priority ? ` (${task.priority})` : "";
        lines.push(`- ${checkbox} ${task.title}${priority}`);
        if (task.description) {
          lines.push(`  - ${task.description}`);
        }
      }
    }
    if (plan.metadata.keyDecisions && plan.metadata.keyDecisions.length > 0) {
      lines.push("");
      lines.push("## \u5173\u952E\u51B3\u7B56");
      lines.push("");
      for (const decision of plan.metadata.keyDecisions) {
        lines.push(`- ${decision}`);
      }
    }
    return lines.join("\n");
  }
  /**
   * 读取 Plan 文档
   */
  readPlan(fileName) {
    let filePath = join(this.projectPlanDir, fileName);
    if (!existsSync(filePath)) {
      filePath = join(this.baseDir, fileName);
    }
    if (!existsSync(filePath)) {
      return null;
    }
    return this.parsePlanFile(filePath);
  }
  /**
   * 解析 Plan 文件
   */
  parsePlanFile(filePath) {
    try {
      const content = readFileSync(filePath, "utf-8");
      const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
      if (!frontmatterMatch) {
        return {
          id: basename(filePath, ".md"),
          name: basename(filePath, ".md"),
          content,
          createdAt: /* @__PURE__ */ new Date(),
          updatedAt: /* @__PURE__ */ new Date(),
          metadata: {}
        };
      }
      const frontmatter = frontmatterMatch[1];
      const body = frontmatterMatch[2];
      const meta = {};
      for (const line of frontmatter.split("\n")) {
        const match = line.match(/^(\w+):\s*(.*)$/);
        if (match) {
          meta[match[1]] = match[2];
        }
      }
      return {
        id: meta.id || basename(filePath, ".md"),
        name: meta.name || basename(filePath, ".md"),
        content: body.trim(),
        sessionId: meta.session,
        sourceSkill: meta.skill,
        createdAt: meta.created ? new Date(meta.created) : /* @__PURE__ */ new Date(),
        updatedAt: meta.updated ? new Date(meta.updated) : /* @__PURE__ */ new Date(),
        metadata: {
          tokenEstimate: meta.tokens ? Number.parseInt(meta.tokens, 10) : void 0
        }
      };
    } catch {
      return null;
    }
  }
  /**
   * 列出所有 Plan 文档
   */
  listPlans(location = "project") {
    const plans = [];
    if (location === "project" || location === "all") {
      if (existsSync(this.projectPlanDir)) {
        const files = readdirSync(this.projectPlanDir).filter((f) => f.endsWith(".md"));
        plans.push(...files.map((f) => join(this.projectPlanDir, f)));
      }
    }
    if (location === "global" || location === "all") {
      if (existsSync(this.baseDir)) {
        const files = readdirSync(this.baseDir).filter((f) => f.endsWith(".md"));
        plans.push(...files.map((f) => join(this.baseDir, f)));
      }
    }
    return plans;
  }
  /**
   * 获取最新的 Plan 文档
   */
  getLatestPlan() {
    const plans = this.listPlans("project");
    if (plans.length === 0) {
      return null;
    }
    const sorted = plans.map((p) => {
      const doc = this.parsePlanFile(p);
      return doc ? { path: p, doc } : null;
    }).filter((p) => p !== null).sort((a, b) => b.doc.updatedAt.getTime() - a.doc.updatedAt.getTime());
    return sorted[0]?.doc || null;
  }
  /**
   * 获取项目 Plan 目录路径
   */
  getProjectPlanDir() {
    return this.projectPlanDir;
  }
}
let instance = null;
function getPlanPersistenceManager(projectPath) {
  if (!instance) {
    instance = new PlanPersistenceManager(projectPath);
  }
  return instance;
}

const PLAN_DIRECTORIES = [
  ".ccjk/plan/current",
  ".ccjk/plan/archive"
];
const GLOBAL_PLAN_DIR = join(homedir(), ".ccjk", "plans");
async function initializeContextFeatures() {
  try {
    if (!existsSync(GLOBAL_PLAN_DIR)) {
      await mkdir(GLOBAL_PLAN_DIR, { recursive: true });
    }
    const cwd = process.cwd();
    for (const dir of PLAN_DIRECTORIES) {
      const fullPath = join(cwd, dir);
      if (!existsSync(fullPath)) {
        await mkdir(fullPath, { recursive: true });
      }
    }
    getCompactAdvisor();
    getPlanPersistenceManager();
  } catch {
  }
}

export { initializeContextFeatures };
