import { existsSync } from "fs";
import { isAbsolute, normalize, resolve, sep } from "path";
import { fileURLToPath } from "node:url";
import { execFile } from "child_process";
import { getDextoGlobalPath } from "@dexto/agent-management";
const CUSTOM_SOUND_EXTENSIONS = [".wav", ".mp3", ".ogg", ".oga", ".aiff", ".m4a"];
function getSoundFileKey(soundType) {
  switch (soundType) {
    case "startup":
      return "startupSoundFile";
    case "approval":
      return "approvalSoundFile";
    case "complete":
      return "completeSoundFile";
  }
}
function resolvePathWithinSoundsDir(soundPath) {
  if (soundPath.trim().length === 0) return null;
  const soundsDir = normalize(getDextoGlobalPath("sounds"));
  const resolved = isAbsolute(soundPath) ? normalize(soundPath) : resolve(soundsDir, soundPath);
  if (resolved === soundsDir || resolved.startsWith(soundsDir + sep)) {
    return resolved;
  }
  return null;
}
const PLATFORM_SOUNDS = {
  darwin: {
    // macOS system sounds
    approval: "/System/Library/Sounds/Blow.aiff",
    complete: "/System/Library/Sounds/Glass.aiff"
  },
  linux: {
    // Common Linux sound paths (freedesktop)
    approval: "/usr/share/sounds/freedesktop/stereo/message-new-instant.oga",
    complete: "/usr/share/sounds/freedesktop/stereo/complete.oga"
  },
  win32: {
    // Windows system sounds (handled differently via PowerShell)
    approval: "SystemAsterisk",
    complete: "SystemHand"
  }
};
const BUNDLED_STARTUP_SOUND_PATH = fileURLToPath(
  new URL("../../assets/sounds/startup.wav", import.meta.url)
);
function getDefaultSoundSpec(soundType) {
  if (soundType === "startup") {
    return BUNDLED_STARTUP_SOUND_PATH;
  }
  const platformSounds = PLATFORM_SOUNDS[process.platform];
  return platformSounds?.[soundType] ?? null;
}
function playSound(soundPath) {
  const execOrBell = (cmd, args, onError) => {
    execFile(cmd, args, { windowsHide: true }, (error) => {
      if (!error) return;
      if (onError) {
        onError();
        return;
      }
      playTerminalBell();
    });
  };
  switch (process.platform) {
    case "darwin": {
      execOrBell("afplay", [soundPath]);
      return;
    }
    case "linux": {
      const lowerSoundPath = soundPath.toLowerCase();
      const isOgg = lowerSoundPath.endsWith(".oga") || lowerSoundPath.endsWith(".ogg");
      if (isOgg) {
        execOrBell("paplay", [soundPath], () => {
          execOrBell("ogg123", ["-q", soundPath]);
        });
      } else {
        execOrBell("paplay", [soundPath], () => {
          execOrBell("aplay", ["-q", soundPath]);
        });
      }
      return;
    }
    case "win32": {
      if (["SystemAsterisk", "SystemHand", "SystemExclamation", "SystemQuestion"].includes(
        soundPath
      )) {
        const systemSoundName = soundPath.replace("System", "");
        execOrBell("powershell", [
          "-NoProfile",
          "-NonInteractive",
          "-Command",
          `[System.Media.SystemSounds]::${systemSoundName}.Play()`
        ]);
        return;
      }
      execOrBell("powershell", [
        "-NoProfile",
        "-NonInteractive",
        "-Command",
        "& { param([string]$p) (New-Object System.Media.SoundPlayer $p).PlaySync() }",
        soundPath
      ]);
      return;
    }
    default: {
      playTerminalBell();
      return;
    }
  }
}
function playSoundFile(soundPath) {
  playSound(soundPath);
}
function playTerminalBell() {
  process.stdout.write("\x07");
}
function resolveNotificationSoundSpec(soundType, config) {
  const configuredRelativePath = config?.[getSoundFileKey(soundType)];
  if (configuredRelativePath) {
    const resolved = resolvePathWithinSoundsDir(configuredRelativePath);
    if (resolved && existsSync(resolved)) {
      return resolved;
    }
  }
  const defaultSpec = getDefaultSoundSpec(soundType);
  if (!defaultSpec) return null;
  if (process.platform === "win32") {
    return defaultSpec;
  }
  return existsSync(defaultSpec) ? defaultSpec : null;
}
function playNotificationSound(soundType, config) {
  const soundSpec = resolveNotificationSoundSpec(soundType, config);
  if (!soundSpec) {
    playTerminalBell();
    return;
  }
  playSound(soundSpec);
}
class SoundNotificationService {
  config;
  constructor(config) {
    this.config = { ...config };
  }
  /**
   * Update configuration
   */
  setConfig(config) {
    this.config = { ...this.config, ...config };
  }
  /**
   * Get current configuration
   */
  getConfig() {
    return { ...this.config };
  }
  /**
   * Play CLI startup sound if enabled
   */
  playStartupSound() {
    if (this.config.enabled && this.config.onStartup) {
      playNotificationSound("startup", this.config);
    }
  }
  /**
   * Play approval required sound if enabled
   */
  playApprovalSound() {
    if (this.config.enabled && this.config.onApprovalRequired) {
      playNotificationSound("approval", this.config);
    }
  }
  /**
   * Play task complete sound if enabled
   */
  playCompleteSound() {
    if (this.config.enabled && this.config.onTaskComplete) {
      playNotificationSound("complete", this.config);
    }
  }
}
export {
  CUSTOM_SOUND_EXTENSIONS,
  SoundNotificationService,
  getDefaultSoundSpec,
  playNotificationSound,
  playSoundFile
};
