import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { existsSync, readFileSync } from "fs";
import { join } from "path";
import { homedir } from "os";
import { execFileSync } from "child_process";
import { writeFileSecure, ensureSecureDir } from "./secure-fs.js";
import { WhatsAppCommandsConfigSchema, parseConfigSafe } from "./schemas.js";
import { executeActionSafe } from "./sms-action-runner.js";
import {
  syncContext,
  getFrameDigestData,
  generateMobileDigest,
  loadSyncOptions
} from "./whatsapp-sync.js";
import { sendNotification } from "./sms-notify.js";
const MAX_REGEX_INPUT_LENGTH = 200;
const DANGEROUS_PATTERNS = [
  /(\+|\*|\?)\s*(\+|\*|\?)/,
  // Nested quantifiers like .+* or .*+
  /\(\?[^)]*\)\s*[+*]/,
  // Quantified groups with + or *
  /\[[^\]]*\]\s*[+*]\s*[+*]/,
  // Character classes with nested quantifiers
  /(\.\*|\.\+)\s*(\.\*|\.\+)/,
  // Overlapping .* or .+
  /\(\[[^\]]+\]\+\)\+/,
  // Nested + with character class
  /\(.*\+\).*\+/
  // Nested + quantifiers
];
function isPatternSafe(pattern) {
  for (const dangerous of DANGEROUS_PATTERNS) {
    if (dangerous.test(pattern)) {
      console.warn(
        `[whatsapp-commands] Potentially dangerous regex pattern blocked: ${pattern}`
      );
      return false;
    }
  }
  const quantifierCount = (pattern.match(/[+*?]/g) || []).length;
  const groupCount = (pattern.match(/\(/g) || []).length;
  if (quantifierCount > 5 || groupCount > 3) {
    console.warn(
      `[whatsapp-commands] Complex regex pattern blocked: ${pattern} (${quantifierCount} quantifiers, ${groupCount} groups)`
    );
    return false;
  }
  return true;
}
function safeRegexTest(pattern, input) {
  if (!isPatternSafe(pattern)) {
    return false;
  }
  const safeInput = input.slice(0, MAX_REGEX_INPUT_LENGTH);
  try {
    const regex = new RegExp(pattern);
    return regex.test(safeInput);
  } catch {
    console.warn(`[whatsapp-commands] Invalid regex pattern: ${pattern}`);
    return false;
  }
}
const CONFIG_PATH = join(homedir(), ".stackmemory", "whatsapp-commands.json");
const REMOTE_SESSIONS_PATH = join(
  homedir(),
  ".stackmemory",
  "remote-sessions.json"
);
function loadRemoteSessions() {
  try {
    if (existsSync(REMOTE_SESSIONS_PATH)) {
      return JSON.parse(readFileSync(REMOTE_SESSIONS_PATH, "utf8"));
    }
  } catch {
  }
  return { sessions: [] };
}
function saveRemoteSessions(store) {
  try {
    ensureSecureDir(join(homedir(), ".stackmemory"));
    writeFileSecure(REMOTE_SESSIONS_PATH, JSON.stringify(store, null, 2));
  } catch {
  }
}
function addRemoteSession(session) {
  const store = loadRemoteSessions();
  store.sessions = [session, ...store.sessions.slice(0, 19)];
  saveRemoteSessions(store);
}
function getRemoteSessions() {
  return loadRemoteSessions().sessions;
}
function getActiveRemoteSessions() {
  return loadRemoteSessions().sessions.filter((s) => s.status === "active");
}
const DEFAULT_COMMANDS = [
  {
    name: "help",
    description: "List available commands",
    enabled: true
  },
  {
    name: "status",
    description: "Get current task/frame status",
    enabled: true
  },
  {
    name: "sessions",
    description: "List active remote sessions with URLs",
    enabled: true
  },
  {
    name: "remote",
    description: "Launch remote Claude session (requires task prompt)",
    enabled: true,
    requiresArg: true
  },
  // Disabled by default - can be enabled in config if needed
  {
    name: "context",
    description: "Get latest context digest",
    enabled: false
  },
  {
    name: "sync",
    description: "Push current context to WhatsApp",
    enabled: false
  },
  {
    name: "tasks",
    description: "List active tasks",
    enabled: false
  }
];
const DEFAULT_CONFIG = {
  enabled: true,
  commands: DEFAULT_COMMANDS
};
function loadCommandsConfig() {
  try {
    if (existsSync(CONFIG_PATH)) {
      const data = JSON.parse(readFileSync(CONFIG_PATH, "utf8"));
      return parseConfigSafe(
        WhatsAppCommandsConfigSchema,
        { ...DEFAULT_CONFIG, ...data },
        DEFAULT_CONFIG,
        "whatsapp-commands"
      );
    }
  } catch {
  }
  return { ...DEFAULT_CONFIG };
}
function saveCommandsConfig(config) {
  try {
    ensureSecureDir(join(homedir(), ".stackmemory"));
    writeFileSecure(CONFIG_PATH, JSON.stringify(config, null, 2));
  } catch {
  }
}
function isCommand(message) {
  const trimmed = message.trim().toLowerCase();
  const config = loadCommandsConfig();
  if (!config.enabled) return false;
  const words = trimmed.split(/\s+/);
  const firstWord = words[0];
  return config.commands.some(
    (cmd) => cmd.enabled && cmd.name.toLowerCase() === firstWord
  );
}
function parseCommand(message) {
  const trimmed = message.trim();
  const words = trimmed.split(/\s+/);
  if (words.length === 0) return null;
  const name = words[0].toLowerCase();
  const arg = words.slice(1).join(" ").trim() || void 0;
  return { name, arg };
}
function generateHelpText(config) {
  const lines = ["Available commands:"];
  config.commands.filter((cmd) => cmd.enabled).forEach((cmd) => {
    const argHint = cmd.requiresArg ? " <arg>" : "";
    lines.push(`  ${cmd.name}${argHint} - ${cmd.description}`);
  });
  lines.push("");
  lines.push("Reply with command name to execute");
  return lines.join("\n");
}
async function handleContextCommand() {
  const data = await getFrameDigestData();
  if (!data) {
    return "No context available. Start a task first.";
  }
  const options = loadSyncOptions();
  return generateMobileDigest(data, options);
}
async function handleSyncCommand() {
  const result = await syncContext();
  if (result.success) {
    return `Context synced (${result.digestLength} chars)`;
  } else {
    return `Sync failed: ${result.error}`;
  }
}
async function handleStatusCommand() {
  try {
    const data = await getFrameDigestData();
    if (!data) {
      return "No active session. Start with: claude-sm";
    }
    const lines = [];
    lines.push(`Frame: ${data.name || data.frameId}`);
    lines.push(`Status: ${data.status}`);
    lines.push(`Files: ${data.filesModified?.length || 0} modified`);
    lines.push(`Tools: ${data.toolCallCount || 0} calls`);
    if (data.errors?.length > 0) {
      const unresolved = data.errors.filter((e) => !e.resolved).length;
      if (unresolved > 0) lines.push(`Errors: ${unresolved} unresolved`);
    }
    lines.push(`Duration: ${Math.round(data.durationSeconds / 60)}min`);
    return lines.join("\n");
  } catch {
    return "Status unavailable";
  }
}
async function handleTasksCommand() {
  try {
    const data = await getFrameDigestData();
    if (!data) {
      return "No active tasks";
    }
    const lines = [];
    if (data.decisions?.length > 0) {
      lines.push("Recent decisions:");
      data.decisions.slice(0, 3).forEach((d, i) => {
        lines.push(
          `${i + 1}. ${d.substring(0, 50)}${d.length > 50 ? "..." : ""}`
        );
      });
    }
    if (data.risks?.length > 0) {
      lines.push("");
      lines.push("Risks:");
      data.risks.slice(0, 2).forEach((r) => {
        lines.push(`- ${r.substring(0, 50)}${r.length > 50 ? "..." : ""}`);
      });
    }
    if (lines.length === 0) {
      return "No active tasks or decisions";
    }
    return lines.join("\n");
  } catch {
    return "Tasks unavailable";
  }
}
async function handleRemoteCommand(prompt) {
  try {
    const sanitizedPrompt = prompt.replace(/[`$\\]/g, "").replace(/["']/g, "'").substring(0, 500);
    if (!sanitizedPrompt.trim()) {
      return "Please provide a task prompt. Usage: remote <your task>";
    }
    console.log(
      `[whatsapp-commands] Launching remote session: ${sanitizedPrompt.substring(0, 50)}...`
    );
    const output = execFileSync("claude", ["--remote", sanitizedPrompt], {
      encoding: "utf8",
      timeout: 3e4,
      stdio: ["pipe", "pipe", "pipe"]
    });
    const urlMatch = output.match(
      /https:\/\/claude\.ai\/code\/session_[a-zA-Z0-9]+/
    );
    if (urlMatch) {
      const sessionUrl = urlMatch[0];
      const sessionId = sessionUrl.split("/").pop() || "unknown";
      addRemoteSession({
        id: sessionId,
        url: sessionUrl,
        prompt: sanitizedPrompt,
        createdAt: (/* @__PURE__ */ new Date()).toISOString(),
        status: "active"
      });
      return `Remote session launched!

${sessionUrl}

Task: ${sanitizedPrompt.substring(0, 100)}`;
    }
    return `Session launched:
${output.substring(0, 300)}`;
  } catch (err) {
    const error = err instanceof Error ? err.message : String(err);
    console.error(`[whatsapp-commands] Remote launch failed: ${error}`);
    return `Failed to launch remote session: ${error.substring(0, 100)}`;
  }
}
function handleSessionsCommand() {
  const sessions = getActiveRemoteSessions();
  if (sessions.length === 0) {
    return "No active remote sessions";
  }
  const lines = ["Active remote sessions:"];
  sessions.slice(0, 5).forEach((s, i) => {
    const age = Math.round(
      (Date.now() - new Date(s.createdAt).getTime()) / 6e4
    );
    const ageStr = age < 60 ? `${age}m ago` : `${Math.round(age / 60)}h ago`;
    lines.push(`${i + 1}. ${s.prompt.substring(0, 40)}... (${ageStr})`);
    lines.push(`   ${s.url}`);
  });
  return lines.join("\n");
}
async function processCommand(from, message) {
  const config = loadCommandsConfig();
  if (!config.enabled) {
    return { handled: false };
  }
  const parsed = parseCommand(message);
  if (!parsed) {
    return { handled: false };
  }
  const command = config.commands.find(
    (cmd) => cmd.enabled && cmd.name.toLowerCase() === parsed.name
  );
  if (!command) {
    return { handled: false };
  }
  if (command.name === "help") {
    const helpText = generateHelpText(config);
    return { handled: true, response: helpText };
  }
  if (command.name === "context") {
    const contextText = await handleContextCommand();
    return { handled: true, response: contextText };
  }
  if (command.name === "sync") {
    const syncText = await handleSyncCommand();
    return { handled: true, response: syncText };
  }
  if (command.name === "status") {
    const statusText = await handleStatusCommand();
    return { handled: true, response: statusText };
  }
  if (command.name === "tasks") {
    const tasksText = await handleTasksCommand();
    return { handled: true, response: tasksText };
  }
  if (command.name === "remote") {
    if (!parsed.arg) {
      return {
        handled: true,
        response: "Usage: remote <task prompt>\nExample: remote Fix the login bug",
        error: "Missing prompt"
      };
    }
    const remoteText = await handleRemoteCommand(parsed.arg);
    return { handled: true, response: remoteText };
  }
  if (command.name === "sessions") {
    const sessionsText = handleSessionsCommand();
    return { handled: true, response: sessionsText };
  }
  if (command.requiresArg && !parsed.arg) {
    return {
      handled: true,
      response: `${command.name} requires an argument. Usage: ${command.name} <arg>`,
      error: "Missing argument"
    };
  }
  if (command.argPattern && parsed.arg) {
    if (!safeRegexTest(command.argPattern, parsed.arg)) {
      return {
        handled: true,
        response: `Invalid argument format for ${command.name}`,
        error: "Invalid argument format"
      };
    }
  }
  let action = command.action;
  if (action && parsed.arg) {
    if (command.name === "approve") {
      action = `gh pr review ${parsed.arg} --approve`;
    } else if (command.name === "merge") {
      action = `gh pr merge ${parsed.arg} --squash`;
    }
  }
  if (action) {
    console.log(`[whatsapp-commands] Executing: ${action}`);
    const result = await executeActionSafe(action, message);
    if (result.success) {
      const output = result.output?.slice(0, 200) || "Done";
      return {
        handled: true,
        response: `${command.name}: ${output}`,
        action
      };
    } else {
      return {
        handled: true,
        response: `${command.name} failed: ${result.error?.slice(0, 100)}`,
        error: result.error,
        action
      };
    }
  }
  return {
    handled: true,
    response: `Command ${command.name} acknowledged`
  };
}
async function sendCommandResponse(response) {
  const result = await sendNotification({
    type: "custom",
    title: "Command Result",
    message: response
  });
  return { success: result.success, error: result.error };
}
function enableCommands() {
  const config = loadCommandsConfig();
  config.enabled = true;
  saveCommandsConfig(config);
}
function disableCommands() {
  const config = loadCommandsConfig();
  config.enabled = false;
  saveCommandsConfig(config);
}
function isCommandsEnabled() {
  const config = loadCommandsConfig();
  return config.enabled;
}
function addCommand(command) {
  const config = loadCommandsConfig();
  const existingIndex = config.commands.findIndex(
    (c) => c.name.toLowerCase() === command.name.toLowerCase()
  );
  if (existingIndex >= 0) {
    config.commands[existingIndex] = command;
  } else {
    config.commands.push(command);
  }
  saveCommandsConfig(config);
}
function removeCommand(name) {
  const config = loadCommandsConfig();
  const initialLength = config.commands.length;
  config.commands = config.commands.filter(
    (c) => c.name.toLowerCase() !== name.toLowerCase()
  );
  if (config.commands.length < initialLength) {
    saveCommandsConfig(config);
    return true;
  }
  return false;
}
function getAvailableCommands() {
  const config = loadCommandsConfig();
  return config.commands.filter((c) => c.enabled);
}
export {
  addCommand,
  disableCommands,
  enableCommands,
  getActiveRemoteSessions,
  getAvailableCommands,
  getRemoteSessions,
  isCommand,
  isCommandsEnabled,
  loadCommandsConfig,
  processCommand,
  removeCommand,
  saveCommandsConfig,
  sendCommandResponse
};
//# sourceMappingURL=whatsapp-commands.js.map
