#!/bin/bash
set -euo pipefail

resolve_script_dir() {
  local target="$1"
  if [ -L "$target" ]; then
    local link
    link="$(readlink "$target")"
    if [[ "$link" != /* ]]; then
      target="$(cd "$(dirname "$target")" && pwd)/$link"
    else
      target="$link"
    fi
  fi
  cd "$(dirname "$target")" && pwd
}

SCRIPT_DIR="$(resolve_script_dir "$0")"
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
VERSION="$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$ROOT/package.json" 2>/dev/null | head -1 | sed 's/.*: *"\(.*\)"/\1/')"
VERSION="${VERSION:-0.1.0}"
BIN_DIR="$HOME/.local/bin"
CONFIG_DIR="$HOME/.config/ivox"
SOCK="$CONFIG_DIR/ivox.sock"

ivox_python() {
  if [[ -n "${IVOX_PYTHON:-}" ]]; then
    echo "$IVOX_PYTHON"
  elif [[ -f "$CONFIG_DIR/py/.venv/bin/python" ]]; then
    echo "$CONFIG_DIR/py/.venv/bin/python"
  else
    echo "python3"
  fi
}
PLIST="$HOME/Library/LaunchAgents/com.user.ivox.plist"
BINARY_PATH="$BIN_DIR/ivoxd"

cmd_setup() {
  # 0. 平台检查
  if [[ "$(uname -m)" != "arm64" ]]; then
    echo "[✗] iVox 当前仅支持 Apple Silicon (M 系列芯片)"
    echo "    Intel Mac 的 MLX 支持尚在开发中"
    exit 1
  fi

  echo "== iVox Setup =="
  mkdir -p "$CONFIG_DIR" "$BIN_DIR" "$HOME/Library/LaunchAgents"

  # 1. Python 环境
  echo "--- Python 环境 ---"
  rm -rf "$CONFIG_DIR/py"
  cp -R "$ROOT/py" "$CONFIG_DIR/py"

  local venv_python="$CONFIG_DIR/py/.venv/bin/python"
  if [[ ! -f "$venv_python" ]]; then
    echo "创建虚拟环境..."
    "${IVOX_PYTHON:-python3}" -m venv "$CONFIG_DIR/py/.venv" || {
      echo "[✗] 创建 Python venv 失败，请确认 python3 已安装"
      exit 1
    }
    echo "安装依赖 (mlx-audio, librosa, soundfile)..."
    "$venv_python" -m pip install --quiet mlx-audio==0.4.3 librosa==0.11.0 soundfile==0.13.1 || {
      echo "[✗] pip install 失败，请检查网络连接"
      exit 1
    }
    echo "✓ Python 环境就绪"
  else
    echo "✓ Python 环境已存在"
  fi

  # 2. 音色
  echo "--- 音色 ---"
  mkdir -p "$CONFIG_DIR/voices"
  local voice_count=0
  for wav in "$ROOT"/voices/*.wav; do
    if [[ -f "$wav" ]]; then
      local name
      name="$(basename "$wav")"
      if [[ ! -f "$CONFIG_DIR/voices/$name" ]]; then
        cp "$wav" "$CONFIG_DIR/voices/" && ((voice_count++))
      else
        ((voice_count++))
      fi
    fi
  done
  echo "✓ ${voice_count} 个音色"

  # 3. 配置
  echo "--- 配置 ---"
  if [[ ! -f "$CONFIG_DIR/config.json" ]]; then
    if PYTHONPATH="$CONFIG_DIR/py" "$venv_python" -m ivox_tts.migrate 2>/dev/null; then
      echo "✓ 从旧版本迁移配置"
    else
      cp "$ROOT/configs/config.example.json" "$CONFIG_DIR/config.json"
      echo "✓ 新配置已生成"
    fi
  else
    echo "✓ 配置已存在"
  fi

  # 4. Hooks
  echo "--- Code CLI Hooks ---"
  cp "$ROOT/configs/hook-speak.sh" "$CONFIG_DIR/hook-speak.sh"
  cp "$ROOT/configs/hook-speak.js" "$CONFIG_DIR/hook-speak.js"
  cp "$ROOT/configs/ivox.ts" "$CONFIG_DIR/ivox.ts"
  chmod +x "$CONFIG_DIR/hook-speak.sh" 2>/dev/null || true
  PYTHONPATH="$CONFIG_DIR/py" "$venv_python" -m ivox_tts.install_hooks

  # 5. 模型
  echo "--- 模型 ---"
  local model_dir="$CONFIG_DIR/models/Qwen3-TTS-12Hz-0.6B-Base-4bit"
  if [[ ! -d "$model_dir" ]]; then
    echo "从 ModelScope 下载模型 (~1.2GB)..."
    echo "网络良好情况下约需 2-5 分钟"
    "$venv_python" -m pip install --quiet modelscope
    "$venv_python" -c "
from modelscope import snapshot_download
print('正在下载，请耐心等待...')
snapshot_download(
    'mlx-community/Qwen3-TTS-12Hz-0.6B-Base-4bit',
    local_dir='$model_dir',
)
" || {
      echo "[✗] 模型下载失败，请检查网络连接"
      echo "    手动下载: git clone https://www.modelscope.cn/mlx-community/Qwen3-TTS-12Hz-0.6B-Base-4bit.git $model_dir"
      exit 1
    }
    # 校验关键文件
    if [[ ! -f "$model_dir/config.json" || ! -f "$model_dir/model.safetensors" ]]; then
      echo "[✗] 模型文件不完整，请重新运行 setup"
      exit 1
    fi
    echo "✓ 模型就绪"
  else
    if [[ ! -f "$model_dir/config.json" || ! -f "$model_dir/model.safetensors" ]]; then
      echo "[!] 已存在的模型文件不完整，删除后请重新运行 ivox setup"
      rm -rf "$model_dir"
      exit 1
    fi
    echo "✓ 模型已存在"
  fi

  # 6. 启动
  echo "--- 启动服务 ---"
  sed "s|BINARY_PATH_PLACEHOLDER|$BINARY_PATH|g" "$ROOT/configs/com.user.ivox.plist" > "$PLIST"
  launchctl bootout "gui/$(id -u)/com.user.ivox" 2>/dev/null || true
  launchctl bootstrap "gui/$(id -u)" "$PLIST" || {
    echo "[✗] 注册 LaunchAgent 失败"
    echo "    手动启动: $BINARY_PATH"
    exit 1
  }
  launchctl kickstart -k "gui/$(id -u)/com.user.ivox" 2>/dev/null || true

  echo
  echo "=================="
  echo "iVox setup 完成!"
  echo "  测试播报: ivox speak 你好"
  echo "  查看状态: ivox status"
  echo "  查看日志: ivox logs"
}

cmd_status() {
  echo "iVox $VERSION"
  if pgrep ivoxd >/dev/null 2>&1; then
    echo "  进程: $(pgrep ivoxd) ✓"
  else
    echo "  进程: 未运行 ✗"
  fi
  [[ -S "$SOCK" ]] && echo "  Socket: ✓" || echo "  Socket: ✗"
}

cmd_restart() {
  launchctl bootstrap "gui/$(id -u)" "$PLIST" 2>/dev/null || true
  launchctl kickstart -k "gui/$(id -u)/com.user.ivox" >/dev/null 2>&1 || true
  echo "ivox: restarted"
}

cmd_uninstall() {
  echo "将删除以下内容："
  echo "  ~/.config/ivox/        配置文件、模型、Python 环境"
  echo "  ~/Library/LaunchAgents/com.user.ivox.plist"
  echo "  ~/.local/bin/ivoxd"
  echo
  echo "Hooks 配置会保留（~/.claude/, ~/.codex/, ~/.pi/），可手动清理。"
  echo
  read -p "确认卸载? [y/N] " confirm
  if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
    echo "已取消"
    return
  fi

  cmd_stop
  launchctl bootout "gui/$(id -u)/com.user.ivox" 2>/dev/null || true
  rm -rf "$CONFIG_DIR"
  rm -f "$PLIST"
  rm -f "$BIN_DIR/ivoxd"
  echo "iVox 已卸载"
}

cmd_update() {
  echo "ivox: updating... (当前版本: $VERSION)"

  local updated=false

  if [[ "$ROOT" == "$(npm root -g 2>/dev/null)"/* ]]; then
    # npm 全局安装
    echo "  → npm update -g @xdfnet/ivox"
    npm update -g @xdfnet/ivox || {
      echo "[✗] npm update 失败，请检查网络或执行: npm i -g @xdfnet/ivox@latest"
      return 1
    }
    updated=true
  elif [[ -d "$ROOT/.git" ]]; then
    # Git 开发模式
    echo "  → git pull"
    git pull || { echo "[✗] git pull 失败"; return 1; }
    echo "  → make deploy"
    make deploy || { echo "[✗] build 失败"; return 1; }
    updated=true
  else
    echo "[!] 未知安装方式，跳过二进制更新"
  fi

  # 同步部署文件（Python 代码 + Hooks + 配置模版）
  if [[ -d "$ROOT/py/ivox_tts" ]]; then
    rm -rf "$CONFIG_DIR/py/ivox_tts"
    cp -R "$ROOT/py/ivox_tts" "$CONFIG_DIR/py/ivox_tts"
    echo "  → Python 代码已同步"
  fi
  if [[ -f "$ROOT/configs/hook-speak.sh" ]]; then
    cp "$ROOT/configs/hook-speak.sh" "$CONFIG_DIR/hook-speak.sh"
    cp "$ROOT/configs/hook-speak.js" "$CONFIG_DIR/hook-speak.js"
    cp "$ROOT/configs/ivox.ts" "$CONFIG_DIR/ivox.ts"
    chmod +x "$CONFIG_DIR/hook-speak.sh" 2>/dev/null || true
    echo "  → Hooks 已同步"
  fi

  # 升级依赖（兼容版本，不是锁死）
  if [[ -f "$CONFIG_DIR/py/.venv/bin/python" ]]; then
    echo "  → pip install --upgrade"
    "$CONFIG_DIR/py/.venv/bin/python" -m pip install --quiet --upgrade mlx-audio librosa soundfile
  fi

  cmd_restart

  if $updated; then
    local new_version
    new_version="$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$ROOT/package.json" 2>/dev/null | head -1 | sed 's/.*: *"\(.*\)"/\1/')"
    echo "ivox: update complete → v${new_version:-$VERSION}"
  else
    echo "ivox: update complete"
  fi
}

cmd_stop() {
  launchctl bootout "gui/$(id -u)/com.user.ivox" 2>/dev/null || true
  pkill -f ivoxd 2>/dev/null || true
  echo "ivox: stopped"
}

cmd_logs() {
  tail -n "${1:-120}" "$CONFIG_DIR/ivox.log" 2>/dev/null || true
}

cmd_speak() {
  local source=""
  if [[ "${1:-}" == "-s" || "${1:-}" == "--source" ]]; then
    source="${2:-}"
    shift 2
  fi
  local payload="$*"
  if [[ -n "$source" && "$payload" != \{source:* ]]; then
    payload="{source:${source}}${payload}"
  fi
  if [[ "${IVOX_CLI_PRINT_PAYLOAD:-}" == "1" ]]; then
    printf "%s" "$payload"
    return 0
  fi
  printf "%s" "$payload" | nc -U -w5 "$SOCK" 2>/dev/null || echo "ivox: socket 不可用，请先运行 ivox setup 或 ivox restart" >&2
}

cmd_voice_list() {
  PYTHONPATH="$CONFIG_DIR/py" "$(ivox_python)" -m ivox_tts.worker voices --config "$CONFIG_DIR/config.json"
}

cmd_voice_clone_volcengine() {
  PYTHONPATH="$CONFIG_DIR/py" "$(ivox_python)" -m ivox_tts.clone_volcengine \
    --config "$CONFIG_DIR/config.json" "$@"
}

case "${1:-}" in
  setup) cmd_setup ;;
  update) cmd_update ;;
  uninstall) cmd_uninstall ;;
  status) cmd_status ;;
  restart) cmd_restart ;;
  stop) cmd_stop ;;
  logs) shift; cmd_logs "${1:-120}" ;;
  speak) shift; cmd_speak "$@" ;;
  voice)
    shift
    case "${1:-}" in
      list) cmd_voice_list ;;
      clone)
        shift
        if [[ "${1:-}" != "volcengine" ]]; then
          echo "usage: ivox voice clone volcengine --voice-type ID --resource-id ID --name NAME --text TEXT" >&2
          exit 1
        fi
        shift
        cmd_voice_clone_volcengine "$@"
        ;;
      *) echo "usage: ivox voice list | ivox voice clone volcengine ..." >&2; exit 1 ;;
    esac
    ;;
  version|-v|--version) echo "iVox $VERSION" ;;
  ""|status) cmd_status ;;
  *)
    cmd_speak "$@"
    ;;
esac
