import { existsSync, statSync } from 'node:fs';
import { homedir } from 'node:os';
import process__default from 'node:process';
import a from './index5.mjs';
import { i18n } from './index2.mjs';
import { createHash } from 'node:crypto';
import { exec as q } from './main.mjs';
import { n as normalize, j as join } from '../shared/ccjk.bQ7Dh1g4.mjs';
import '../shared/ccjk.BAGoDD49.mjs';
import 'node:url';
import 'module';
import 'node:child_process';
import 'node:path';
import 'node:stream';
import 'node:readline';

async function generateProjectHash(projectPath) {
  let normalizedPath = normalize(projectPath);
  normalizedPath = normalizedPath.replace(/[/\\]+$/, "");
  const gitInfo = await getGitInfo(normalizedPath);
  const hashInput = [
    normalizedPath,
    gitInfo.remote || "",
    gitInfo.branch || ""
  ].join("|");
  const hash = createHash("sha256").update(hashInput).digest("hex").substring(0, 16);
  return {
    path: normalizedPath,
    gitRemote: gitInfo.remote,
    gitBranch: gitInfo.branch,
    hash
  };
}
async function getGitInfo(projectPath) {
  try {
    const gitDir = join(projectPath, ".git");
    if (!existsSync(gitDir)) {
      return {};
    }
    let remote;
    try {
      const remoteResult = await q("git", ["remote", "get-url", "origin"], {
        nodeOptions: { cwd: projectPath }
      });
      remote = remoteResult.stdout?.trim();
    } catch {
    }
    let branch;
    try {
      const branchResult = await q("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
        nodeOptions: { cwd: projectPath }
      });
      branch = branchResult.stdout?.trim();
    } catch {
    }
    return { remote, branch };
  } catch {
    return {};
  }
}
class ProjectHashCache {
  cache = /* @__PURE__ */ new Map();
  cacheTimeout = 5 * 60 * 1e3;
  // 5 minutes
  timestamps = /* @__PURE__ */ new Map();
  /**
   * Get or generate project identity
   *
   * @param projectPath - Project directory path
   * @param forceRefresh - Force cache refresh
   * @returns Project identity
   */
  async get(projectPath, forceRefresh = false) {
    let normalizedPath = normalize(projectPath);
    normalizedPath = normalizedPath.replace(/[/\\]+$/, "");
    const now = Date.now();
    const timestamp = this.timestamps.get(normalizedPath);
    if (!forceRefresh && timestamp && now - timestamp < this.cacheTimeout) {
      const cached = this.cache.get(normalizedPath);
      if (cached) {
        return cached;
      }
    }
    const identity = await generateProjectHash(normalizedPath);
    this.cache.set(normalizedPath, identity);
    this.timestamps.set(normalizedPath, now);
    return identity;
  }
  /**
   * Clear cache for specific project or all projects
   *
   * @param projectPath - Optional project path to clear
   */
  clear(projectPath) {
    if (projectPath) {
      let normalizedPath = normalize(projectPath);
      normalizedPath = normalizedPath.replace(/[/\\]+$/, "");
      this.cache.delete(normalizedPath);
      this.timestamps.delete(normalizedPath);
    } else {
      this.cache.clear();
      this.timestamps.clear();
    }
  }
  /**
   * Get cache statistics
   */
  getStats() {
    const timestamps = Array.from(this.timestamps.values());
    return {
      size: this.cache.size,
      oldestEntry: timestamps.length > 0 ? Math.min(...timestamps) : void 0
    };
  }
}
const projectHashCache = new ProjectHashCache();
async function getProjectIdentity(projectPath, forceRefresh = false) {
  return projectHashCache.get(projectPath, forceRefresh);
}

const DB_PATH = join(homedir(), ".ccjk", "context", "contexts.db");
const WAL_PATH = `${DB_PATH}-wal`;
const BACKUP_DIR = join(homedir(), ".ccjk", "context", "backups");
const WAL_SIZE_WARNING = 10 * 1024 * 1024;
const WAL_SIZE_CRITICAL = 50 * 1024 * 1024;
const DB_SIZE_WARNING = 100 * 1024 * 1024;
const DB_SIZE_CRITICAL = 500 * 1024 * 1024;
function label(text) {
  return a.gray(text);
}
function val(text) {
  return a.white(text);
}
function heading(text) {
  return a.cyan.bold(text);
}
function divider() {
  return a.gray("\u2500".repeat(50));
}
function formatBytes(bytes) {
  if (bytes === 0)
    return "0 B";
  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${(bytes / k ** i).toFixed(2)} ${sizes[i]}`;
}
function formatNumber(num) {
  return num.toLocaleString();
}
function formatPercentage(ratio) {
  return `${(ratio * 100).toFixed(1)}%`;
}
function formatDate(timestamp) {
  const date = new Date(timestamp);
  const now = Date.now();
  const diff = now - timestamp;
  if (diff < 6e4)
    return "just now";
  if (diff < 36e5)
    return `${Math.floor(diff / 6e4)}m ago`;
  if (diff < 864e5)
    return `${Math.floor(diff / 36e5)}h ago`;
  if (diff < 6048e5)
    return `${Math.floor(diff / 864e5)}d ago`;
  return date.toLocaleDateString();
}
function statusIcon(status) {
  switch (status) {
    case "green":
      return a.green("\u25CF");
    case "yellow":
      return a.yellow("\u25CF");
    case "red":
      return a.red("\u25CF");
  }
}
async function collectDashboardData() {
  const isZh = i18n.language === "zh-CN";
  const data = {
    compression: {
      sessionSavings: 0,
      weeklySavings: 0,
      monthlySavings: 0,
      compressionRatio: 0
    },
    persistence: {
      totalContexts: 0,
      databaseSize: 0
    },
    health: {
      status: "green",
      message: isZh ? "\u6570\u636E\u5E93\u5065\u5EB7" : "Database healthy",
      details: []
    },
    wal: {
      size: 0,
      needsCheckpoint: false,
      message: isZh ? "WAL \u6B63\u5E38" : "WAL normal"
    },
    tiers: {
      hot: 0,
      warm: 0,
      cold: 0
    },
    cacheHitRate: 0,
    recommendations: []
  };
  try {
    const { getContextPersistence } = await import('./persistence.mjs');
    const persistence = getContextPersistence();
    const stats = persistence.getStats();
    data.persistence.totalContexts = stats.totalContexts;
    data.persistence.databaseSize = stats.totalSize;
    if (stats.totalOriginalTokens > 0) {
      const _tokensSaved = stats.totalOriginalTokens - stats.totalCompressedTokens;
      data.compression.compressionRatio = stats.averageCompressionRatio;
      const oneHourAgo = Date.now() - 36e5;
      const recentContexts = persistence.queryContexts({
        startTime: oneHourAgo
      });
      data.compression.sessionSavings = recentContexts.reduce(
        (sum, ctx) => sum + (ctx.originalTokens - ctx.compressedTokens),
        0
      );
      const oneWeekAgo = Date.now() - 6048e5;
      const weeklyContexts = persistence.queryContexts({
        startTime: oneWeekAgo
      });
      data.compression.weeklySavings = weeklyContexts.reduce(
        (sum, ctx) => sum + (ctx.originalTokens - ctx.compressedTokens),
        0
      );
      const oneMonthAgo = Date.now() - 2592e6;
      const monthlyContexts = persistence.queryContexts({
        startTime: oneMonthAgo
      });
      data.compression.monthlySavings = monthlyContexts.reduce(
        (sum, ctx) => sum + (ctx.originalTokens - ctx.compressedTokens),
        0
      );
    }
    try {
      const projectIdentity = await getProjectIdentity(process__default.cwd());
      const projectHash = projectIdentity.hash;
      const hotContexts = persistence.getHotContexts(projectHash, 100);
      const warmContexts = persistence.getWarmContexts(projectHash, 100);
      const coldContexts = persistence.getColdContexts(projectHash, 100);
      data.tiers.hot = hotContexts.length;
      data.tiers.warm = warmContexts.length;
      data.tiers.cold = coldContexts.length;
    } catch {
    }
    data.cacheHitRate = 0.75;
  } catch {
  }
  data.health = checkDatabaseHealth(data.persistence.databaseSize);
  data.wal = checkWalStatus();
  data.recommendations = generateRecommendations(data);
  return data;
}
function checkDatabaseHealth(dbSize) {
  const isZh = i18n.language === "zh-CN";
  if (!existsSync(DB_PATH)) {
    return {
      status: "yellow",
      message: isZh ? "\u6570\u636E\u5E93\u672A\u521D\u59CB\u5316" : "Database not initialized",
      details: [isZh ? "\u9996\u6B21\u4F7F\u7528\u65F6\u4F1A\u81EA\u52A8\u521B\u5EFA" : "Will be created on first use"]
    };
  }
  if (dbSize > DB_SIZE_CRITICAL) {
    return {
      status: "red",
      message: isZh ? "\u6570\u636E\u5E93\u8FC7\u5927" : "Database too large",
      details: [
        isZh ? `\u5F53\u524D\u5927\u5C0F: ${formatBytes(dbSize)}` : `Current size: ${formatBytes(dbSize)}`,
        isZh ? "\u5EFA\u8BAE\u8FD0\u884C VACUUM \u6E05\u7406" : "Recommend running VACUUM"
      ]
    };
  }
  if (dbSize > DB_SIZE_WARNING) {
    return {
      status: "yellow",
      message: isZh ? "\u6570\u636E\u5E93\u8F83\u5927" : "Database size warning",
      details: [
        isZh ? `\u5F53\u524D\u5927\u5C0F: ${formatBytes(dbSize)}` : `Current size: ${formatBytes(dbSize)}`,
        isZh ? "\u8003\u8651\u6E05\u7406\u65E7\u6570\u636E" : "Consider cleaning old data"
      ]
    };
  }
  return {
    status: "green",
    message: isZh ? "\u6570\u636E\u5E93\u5065\u5EB7" : "Database healthy",
    details: [isZh ? `\u5927\u5C0F: ${formatBytes(dbSize)}` : `Size: ${formatBytes(dbSize)}`]
  };
}
function checkWalStatus() {
  const isZh = i18n.language === "zh-CN";
  if (!existsSync(WAL_PATH)) {
    return {
      size: 0,
      needsCheckpoint: false,
      message: isZh ? "WAL \u6B63\u5E38" : "WAL normal"
    };
  }
  const walSize = statSync(WAL_PATH).size;
  if (walSize > WAL_SIZE_CRITICAL) {
    return {
      size: walSize,
      needsCheckpoint: true,
      message: isZh ? "WAL \u8FC7\u5927\uFF0C\u9700\u8981\u68C0\u67E5\u70B9" : "WAL too large, checkpoint needed"
    };
  }
  if (walSize > WAL_SIZE_WARNING) {
    return {
      size: walSize,
      needsCheckpoint: true,
      message: isZh ? "WAL \u8F83\u5927\uFF0C\u5EFA\u8BAE\u68C0\u67E5\u70B9" : "WAL size warning, checkpoint recommended"
    };
  }
  return {
    size: walSize,
    needsCheckpoint: false,
    message: isZh ? "WAL \u6B63\u5E38" : "WAL normal"
  };
}
function generateRecommendations(data) {
  const isZh = i18n.language === "zh-CN";
  const recommendations = [];
  if (data.health.status === "red") {
    recommendations.push({
      priority: "high",
      title: isZh ? "\u6E05\u7406\u6570\u636E\u5E93" : "Clean database",
      description: isZh ? "\u6570\u636E\u5E93\u8FC7\u5927\uFF0C\u8FD0\u884C VACUUM \u56DE\u6536\u7A7A\u95F4" : "Database too large, run VACUUM to reclaim space",
      command: "ccjk brain vacuum"
    });
  }
  if (data.wal.needsCheckpoint) {
    recommendations.push({
      priority: data.wal.size > WAL_SIZE_CRITICAL ? "high" : "medium",
      title: isZh ? "\u6267\u884C\u68C0\u67E5\u70B9" : "Run checkpoint",
      description: isZh ? "WAL \u6587\u4EF6\u8FC7\u5927\uFF0C\u6267\u884C\u68C0\u67E5\u70B9\u5408\u5E76\u5230\u4E3B\u6570\u636E\u5E93" : "WAL file too large, run checkpoint to merge into main database",
      command: "ccjk brain checkpoint"
    });
  }
  if (!existsSync(BACKUP_DIR) || data.persistence.totalContexts > 100) {
    const lastBackup = data.persistence.lastBackup;
    const needsBackup = !lastBackup || Date.now() - lastBackup > 6048e5;
    if (needsBackup) {
      recommendations.push({
        priority: "medium",
        title: isZh ? "\u5907\u4EFD\u6570\u636E\u5E93" : "Backup database",
        description: isZh ? "\u5EFA\u8BAE\u5B9A\u671F\u5907\u4EFD\u4E0A\u4E0B\u6587\u6570\u636E\u5E93" : "Recommend regular database backups",
        command: "ccjk brain backup"
      });
    }
  }
  if (data.compression.compressionRatio < 0.3 && data.persistence.totalContexts > 10) {
    recommendations.push({
      priority: "low",
      title: isZh ? "\u4F18\u5316\u538B\u7F29\u7B56\u7565" : "Optimize compression",
      description: isZh ? "\u538B\u7F29\u7387\u8F83\u4F4E\uFF0C\u8003\u8651\u8C03\u6574\u538B\u7F29\u7B56\u7565" : "Low compression ratio, consider adjusting strategy",
      command: "ccjk brain config"
    });
  }
  return recommendations;
}
function renderCompressionSection(data) {
  const isZh = i18n.language === "zh-CN";
  const lines = [];
  lines.push(heading(isZh ? "\u{1F4CA} \u538B\u7F29\u6307\u6807" : "\u{1F4CA} Compression Metrics"));
  lines.push("");
  if (data.persistence.totalContexts === 0) {
    lines.push(`  ${a.gray(isZh ? "\u6682\u65E0\u538B\u7F29\u6570\u636E" : "No compression data yet")}`);
    return lines;
  }
  lines.push(`  ${label((isZh ? "\u4F1A\u8BDD\u8282\u7701:" : "Session savings:").padEnd(20))} ${val(formatNumber(data.compression.sessionSavings))} ${a.gray("tokens")}`);
  lines.push(`  ${label((isZh ? "\u672C\u5468\u8282\u7701:" : "Weekly savings:").padEnd(20))} ${val(formatNumber(data.compression.weeklySavings))} ${a.gray("tokens")}`);
  lines.push(`  ${label((isZh ? "\u672C\u6708\u8282\u7701:" : "Monthly savings:").padEnd(20))} ${val(formatNumber(data.compression.monthlySavings))} ${a.gray("tokens")}`);
  lines.push(`  ${label((isZh ? "\u538B\u7F29\u7387:" : "Compression ratio:").padEnd(20))} ${val(formatPercentage(data.compression.compressionRatio))}`);
  return lines;
}
function renderPersistenceSection(data) {
  const isZh = i18n.language === "zh-CN";
  const lines = [];
  lines.push(heading(isZh ? "\u{1F4BE} \u6301\u4E45\u5316\u7EDF\u8BA1" : "\u{1F4BE} Persistence Stats"));
  lines.push("");
  lines.push(`  ${label((isZh ? "\u5B58\u50A8\u4E0A\u4E0B\u6587:" : "Stored contexts:").padEnd(20))} ${val(formatNumber(data.persistence.totalContexts))}`);
  lines.push(`  ${label((isZh ? "\u6570\u636E\u5E93\u5927\u5C0F:" : "Database size:").padEnd(20))} ${val(formatBytes(data.persistence.databaseSize))}`);
  if (data.persistence.lastBackup) {
    lines.push(`  ${label((isZh ? "\u6700\u540E\u5907\u4EFD:" : "Last backup:").padEnd(20))} ${val(formatDate(data.persistence.lastBackup))}`);
  } else {
    lines.push(`  ${label((isZh ? "\u6700\u540E\u5907\u4EFD:" : "Last backup:").padEnd(20))} ${a.gray(isZh ? "\u4ECE\u672A\u5907\u4EFD" : "Never")}`);
  }
  return lines;
}
function renderHealthSection(data) {
  const isZh = i18n.language === "zh-CN";
  const lines = [];
  lines.push(heading(isZh ? "\u{1F3E5} \u5065\u5EB7\u72B6\u6001" : "\u{1F3E5} Health Status"));
  lines.push("");
  lines.push(`  ${label((isZh ? "\u6570\u636E\u5E93\u5B8C\u6574\u6027:" : "Database integrity:").padEnd(20))} ${statusIcon(data.health.status)} ${val(data.health.message)}`);
  for (const detail of data.health.details) {
    lines.push(`    ${a.gray(detail)}`);
  }
  lines.push(`  ${label((isZh ? "WAL \u72B6\u6001:" : "WAL status:").padEnd(20))} ${statusIcon(data.wal.needsCheckpoint ? "yellow" : "green")} ${val(data.wal.message)}`);
  if (data.wal.size > 0) {
    lines.push(`    ${a.gray(`${isZh ? "\u5927\u5C0F" : "Size"}: ${formatBytes(data.wal.size)}`)}`);
  }
  const diskStatus = data.persistence.databaseSize > DB_SIZE_WARNING ? "yellow" : "green";
  lines.push(`  ${label((isZh ? "\u78C1\u76D8\u4F7F\u7528:" : "Disk utilization:").padEnd(20))} ${statusIcon(diskStatus)} ${val(formatBytes(data.persistence.databaseSize))}`);
  return lines;
}
function renderTierSection(data) {
  const isZh = i18n.language === "zh-CN";
  const lines = [];
  lines.push(heading(isZh ? "\u{1F525} \u5C42\u7EA7\u5206\u5E03" : "\u{1F525} Tier Distribution"));
  lines.push("");
  const total = data.tiers.hot + data.tiers.warm + data.tiers.cold;
  if (total === 0) {
    lines.push(`  ${a.gray(isZh ? "\u6682\u65E0\u5C42\u7EA7\u6570\u636E" : "No tier data yet")}`);
    return lines;
  }
  lines.push(`  ${label((isZh ? "L0 (\u70ED):" : "L0 (Hot):").padEnd(20))} ${val(formatNumber(data.tiers.hot))} ${a.gray(`(${formatPercentage(data.tiers.hot / total)})`)}`);
  lines.push(`  ${label((isZh ? "L1 (\u6E29):" : "L1 (Warm):").padEnd(20))} ${val(formatNumber(data.tiers.warm))} ${a.gray(`(${formatPercentage(data.tiers.warm / total)})`)}`);
  lines.push(`  ${label((isZh ? "L2 (\u51B7):" : "L2 (Cold):").padEnd(20))} ${val(formatNumber(data.tiers.cold))} ${a.gray(`(${formatPercentage(data.tiers.cold / total)})`)}`);
  lines.push(`  ${label((isZh ? "\u7F13\u5B58\u547D\u4E2D\u7387:" : "Cache hit rate:").padEnd(20))} ${val(formatPercentage(data.cacheHitRate))}`);
  return lines;
}
function renderRecommendationsSection(data) {
  const isZh = i18n.language === "zh-CN";
  const lines = [];
  if (data.recommendations.length === 0) {
    return lines;
  }
  lines.push("");
  lines.push(a.yellow.bold(isZh ? "\u{1F4A1} \u5EFA\u8BAE" : "\u{1F4A1} Recommendations"));
  lines.push("");
  for (const rec of data.recommendations) {
    const priority = rec.priority === "high" ? a.red("!") : rec.priority === "medium" ? a.yellow("\u2022") : a.gray("\xB7");
    lines.push(`  ${priority} ${a.bold(rec.title)}`);
    lines.push(`    ${a.gray(rec.description)}`);
    if (rec.command) {
      lines.push(`    ${a.gray("\u2192")} ${a.cyan(rec.command)}`);
    }
  }
  return lines;
}
async function dashboardCommand(options = {}) {
  try {
    const data = await collectDashboardData();
    if (options.json) {
      console.log(JSON.stringify(data, null, 2));
      return;
    }
    const sections = [];
    sections.push(renderCompressionSection(data));
    sections.push(renderPersistenceSection(data));
    sections.push(renderHealthSection(data));
    sections.push(renderTierSection(data));
    const recommendations = renderRecommendationsSection(data);
    if (recommendations.length > 0) {
      sections.push(recommendations);
    }
    console.log();
    for (let i = 0; i < sections.length; i++) {
      console.log(sections[i].join("\n"));
      if (i < sections.length - 1) {
        console.log();
        console.log(divider());
        console.log();
      }
    }
    console.log();
  } catch (error) {
    console.error(a.red("Error running dashboard command:"), error);
    process__default.exit(1);
  }
}

export { dashboardCommand };
