#!/usr/bin/env bash

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
SCRIPT_NAME="tasksentry"
SCRIPT_FILE="tasksentry.sh"
CONFIG_DIR="$HOME/.tasksentry"
CONFIG_FILE="config.json"
CONFIG_EXAMPLE="config.example.json"

DEFAULT_INSTALL_DIR="/usr/local/bin"
FALLBACK_INSTALL_DIR="$HOME/bin"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

UNINSTALL_MODE=false
QUIET_MODE=false
DEV_MODE=false

log_info() {
    [[ "$QUIET_MODE" == "true" ]] && return
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    [[ "$QUIET_MODE" == "true" ]] && return
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1" >&2
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1" >&2
}

show_help() {
    cat << EOF
TaskSentinel 安装脚本

用法:
    $0 [选项]

选项:
    -h, --help          显示此帮助信息
    -u, --uninstall     卸载 TaskSentinel
    -q, --quiet         静默模式，减少输出
    -d, --dev           开发模式，安装开发依赖
    --install-dir DIR   指定安装目录 (默认: $DEFAULT_INSTALL_DIR)

示例:
    $0                            # 默认安装
    $0 --install-dir ~/bin        # 安装到用户目录
    $0 --uninstall                # 卸载
    $0 --dev                      # 开发环境安装
EOF
}

check_dependencies() {
    local missing_deps=()
    local deps_info=(
        "bash:4.0:Bash shell"
        "jq:1.6:JSON processor"
        "curl:7.40:HTTP client"
        "openssl:1.1.1:SSL/TLS toolkit"
    )
    
    if [[ "$DEV_MODE" == "true" ]]; then
        deps_info+=("bats:1.9.0:Bash testing framework")
        deps_info+=("shellcheck:0.7.0:Shell script analyzer")
    fi

    log_info "检查系统依赖..."

    for dep_info in "${deps_info[@]}"; do
        IFS=':' read -r cmd min_version desc <<< "$dep_info"
        
        if ! command -v "$cmd" &> /dev/null; then
            missing_deps+=("$cmd")
            log_error "缺少依赖: $desc ($cmd)"
        else
            local version
            case "$cmd" in
                "bash")
                    version=$("$cmd" --version 2>/dev/null | head -n1 | grep -oE '[0-9]+\.[0-9]+' | head -n1)
                    ;;
                "jq")
                    version=$("$cmd" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+')
                    ;;
                "curl")
                    version=$("$cmd" --version 2>/dev/null | head -n1 | grep -oE '[0-9]+\.[0-9]+' | head -n1)
                    ;;
                "openssl")
                    version=$("$cmd" version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)
                    ;;
                "bats")
                    version=$("$cmd" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
                    ;;
                "shellcheck")
                    version=$("$cmd" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
                    ;;
            esac
            
            if [[ -n "$version" ]]; then
                log_success "$desc ($cmd) - 版本: $version"
            else
                log_warning "$desc ($cmd) - 无法获取版本信息"
            fi
        fi
    done

    if [[ ${#missing_deps[@]} -gt 0 ]]; then
        log_error "发现 ${#missing_deps[@]} 个缺失的依赖"
        echo
        log_info "安装建议:"
        
        if command -v apt-get &> /dev/null; then
            echo "  sudo apt-get update && sudo apt-get install ${missing_deps[*]}"
        elif command -v yum &> /dev/null; then
            echo "  sudo yum install ${missing_deps[*]}"
        elif command -v brew &> /dev/null; then
            echo "  brew install ${missing_deps[*]}"
        elif command -v pacman &> /dev/null; then
            echo "  sudo pacman -S ${missing_deps[*]}"
        else
            echo "  请根据您的包管理器安装: ${missing_deps[*]}"
        fi
        
        echo
        read -p "是否继续安装？缺失的依赖可能导致功能异常 (y/N): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            log_info "安装已取消"
            exit 1
        fi
    fi
}

create_user_directory() {
    log_info "创建配置目录: $CONFIG_DIR"
    
    if [[ -d "$CONFIG_DIR" ]]; then
        log_info "配置目录已存在"
    else
        if mkdir -p "$CONFIG_DIR"; then
            log_success "配置目录创建成功"
        else
            log_error "无法创建配置目录: $CONFIG_DIR"
            return 1
        fi
    fi

    chmod 700 "$CONFIG_DIR"
    log_info "设置配置目录权限: 700"
}

install_script() {
    local install_dir="$1"
    local source_script="$PROJECT_ROOT/scripts/$SCRIPT_FILE"
    local target_script="$install_dir/$SCRIPT_NAME"
    local source_adapter="$PROJECT_ROOT/scripts/claude-hook-adapter.sh"
    local target_adapter="$install_dir/claude-hook-adapter"

    if [[ ! -f "$source_script" ]]; then
        log_error "源脚本不存在: $source_script"
        return 1
    fi

    if [[ ! -f "$source_adapter" ]]; then
        log_error "Claude Hook适配器脚本不存在: $source_adapter"
        return 1
    fi

    log_info "安装脚本到: $target_script"

    if [[ ! -d "$install_dir" ]]; then
        log_info "创建安装目录: $install_dir"
        if ! mkdir -p "$install_dir"; then
            log_error "无法创建安装目录: $install_dir"
            return 1
        fi
    fi

    # 备份主脚本
    if [[ -f "$target_script" ]]; then
        log_warning "目标文件已存在，将备份原文件"
        local backup_file="${target_script}.backup.$(date +%Y%m%d_%H%M%S)"
        if cp "$target_script" "$backup_file"; then
            log_info "备份文件: $backup_file"
        else
            log_warning "无法创建备份文件"
        fi
    fi

    # 安装主脚本
    if cp "$source_script" "$target_script"; then
        chmod +x "$target_script"
        log_success "主脚本安装成功"
    else
        log_error "主脚本安装失败"
        return 1
    fi

    # 备份适配器脚本
    if [[ -f "$target_adapter" ]]; then
        local adapter_backup="${target_adapter}.backup.$(date +%Y%m%d_%H%M%S)"
        if cp "$target_adapter" "$adapter_backup"; then
            log_info "备份适配器脚本: $adapter_backup"
        fi
    fi

    # 安装适配器脚本
    log_info "安装Claude Hook适配器到: $target_adapter"
    if cp "$source_adapter" "$target_adapter"; then
        chmod +x "$target_adapter"
        log_success "Claude Hook适配器安装成功"
        return 0
    else
        log_error "Claude Hook适配器安装失败"
        return 1
    fi
}

copy_config_file() {
    local source_config="$PROJECT_ROOT/config/$CONFIG_EXAMPLE"
    local target_config="$CONFIG_DIR/$CONFIG_FILE"

    if [[ ! -f "$source_config" ]]; then
        log_error "配置模板不存在: $source_config"
        return 1
    fi

    if [[ -f "$target_config" ]]; then
        log_warning "配置文件已存在: $target_config"
        read -p "是否覆盖现有配置文件？(y/N): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            log_info "保留现有配置文件"
            return 0
        fi
        
        local backup_file="${target_config}.backup.$(date +%Y%m%d_%H%M%S)"
        if cp "$target_config" "$backup_file"; then
            log_info "备份现有配置: $backup_file"
        fi
    fi

    log_info "复制配置文件模板"
    if cp "$source_config" "$target_config"; then
        chmod 600 "$target_config"
        log_success "配置文件创建成功: $target_config"
        log_info "请编辑配置文件以添加您的 webhook URL 和密钥"
        return 0
    else
        log_error "配置文件复制失败"
        return 1
    fi
}

check_permissions() {
    local install_dir="$1"
    
    if [[ "$install_dir" == "/usr/local/bin" ]] || [[ "$install_dir" == "/usr/bin" ]]; then
        if [[ $EUID -ne 0 ]] && ! sudo -n true 2>/dev/null; then
            log_warning "安装到系统目录需要管理员权限"
            log_info "将尝试使用 sudo，或者您可以选择安装到用户目录"
            
            read -p "继续使用 sudo 安装到 $install_dir？(y/N): " -n 1 -r
            echo
            if [[ ! $REPLY =~ ^[Yy]$ ]]; then
                return 1
            fi
        fi
    fi
    return 0
}

install_with_sudo() {
    local install_dir="$1"
    local source_script="$PROJECT_ROOT/scripts/$SCRIPT_FILE"
    local target_script="$install_dir/$SCRIPT_NAME"
    local source_adapter="$PROJECT_ROOT/scripts/claude-hook-adapter.sh"
    local target_adapter="$install_dir/claude-hook-adapter"

    log_info "使用 sudo 安装脚本"
    
    # 安装主脚本
    if sudo cp "$source_script" "$target_script" && sudo chmod +x "$target_script"; then
        log_success "主脚本安装成功（使用 sudo）"
    else
        log_error "主脚本 sudo 安装失败"
        return 1
    fi

    # 安装适配器脚本
    if sudo cp "$source_adapter" "$target_adapter" && sudo chmod +x "$target_adapter"; then
        log_success "Claude Hook适配器安装成功（使用 sudo）"
        return 0
    else
        log_error "适配器脚本 sudo 安装失败"
        return 1
    fi
}

interactive_install() {
    echo
    log_info "TaskSentinel 安装向导"
    echo "=================="
    echo
    
    echo "选择安装位置:"
    echo "1) $DEFAULT_INSTALL_DIR (系统全局，需要 sudo)"
    echo "2) $FALLBACK_INSTALL_DIR (用户目录)"
    echo "3) 自定义路径"
    echo
    
    while true; do
        read -p "请选择 [1-3]: " -n 1 -r
        echo
        case $REPLY in
            1)
                INSTALL_DIR="$DEFAULT_INSTALL_DIR"
                break
                ;;
            2)
                INSTALL_DIR="$FALLBACK_INSTALL_DIR"
                break
                ;;
            3)
                read -p "请输入安装路径: " INSTALL_DIR
                if [[ -n "$INSTALL_DIR" ]]; then
                    break
                else
                    log_error "路径不能为空"
                fi
                ;;
            *)
                echo "请输入 1, 2 或 3"
                ;;
        esac
    done
    
    echo
    log_info "安装配置:"
    echo "  安装目录: $INSTALL_DIR"
    echo "  配置目录: $CONFIG_DIR"
    echo "  脚本名称: $SCRIPT_NAME"
    echo
    
    read -p "确认安装？(Y/n): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Nn]$ ]]; then
        log_info "安装已取消"
        exit 0
    fi
}

uninstall() {
    log_info "开始卸载 TaskSentinel"
    
    local install_locations=(
        "/usr/local/bin/$SCRIPT_NAME"
        "/usr/bin/$SCRIPT_NAME"
        "$HOME/bin/$SCRIPT_NAME"
        "$HOME/.local/bin/$SCRIPT_NAME"
    )
    
    local adapter_locations=(
        "/usr/local/bin/claude-hook-adapter"
        "/usr/bin/claude-hook-adapter"
        "$HOME/bin/claude-hook-adapter"
        "$HOME/.local/bin/claude-hook-adapter"
    )
    
    local found_installations=()
    local found_adapters=()
    
    for location in "${install_locations[@]}"; do
        if [[ -f "$location" ]]; then
            found_installations+=("$location")
        fi
    done
    
    for location in "${adapter_locations[@]}"; do
        if [[ -f "$location" ]]; then
            found_adapters+=("$location")
        fi
    done
    
    if [[ ${#found_installations[@]} -eq 0 && ${#found_adapters[@]} -eq 0 ]]; then
        log_warning "未找到已安装的 TaskSentinel 脚本"
    else
        echo "找到以下安装:"
        for installation in "${found_installations[@]}"; do
            echo "  - $installation (主脚本)"
        done
        for adapter in "${found_adapters[@]}"; do
            echo "  - $adapter (适配器)"
        done
        echo
        
        read -p "是否删除这些文件？(y/N): " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            # 删除主脚本
            for installation in "${found_installations[@]}"; do
                if [[ "$installation" == "/usr/local/bin/$SCRIPT_NAME" ]] || [[ "$installation" == "/usr/bin/$SCRIPT_NAME" ]]; then
                    if sudo rm -f "$installation"; then
                        log_success "已删除: $installation"
                    else
                        log_error "删除失败: $installation"
                    fi
                else
                    if rm -f "$installation"; then
                        log_success "已删除: $installation"
                    else
                        log_error "删除失败: $installation"
                    fi
                fi
            done
            
            # 删除适配器脚本
            for adapter in "${found_adapters[@]}"; do
                if [[ "$adapter" == "/usr/local/bin/claude-hook-adapter" ]] || [[ "$adapter" == "/usr/bin/claude-hook-adapter" ]]; then
                    if sudo rm -f "$adapter"; then
                        log_success "已删除: $adapter"
                    else
                        log_error "删除失败: $adapter"
                    fi
                else
                    if rm -f "$adapter"; then
                        log_success "已删除: $adapter"
                    else
                        log_error "删除失败: $adapter"
                    fi
                fi
            done
        fi
    fi
    
    if [[ -d "$CONFIG_DIR" ]]; then
        echo
        log_warning "配置目录存在: $CONFIG_DIR"
        read -p "是否删除配置目录和配置文件？(y/N): " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            if rm -rf "$CONFIG_DIR"; then
                log_success "配置目录已删除: $CONFIG_DIR"
            else
                log_error "删除配置目录失败: $CONFIG_DIR"
            fi
        else
            log_info "保留配置目录: $CONFIG_DIR"
        fi
    fi
    
    log_success "卸载完成"
}

validate_installation() {
    local install_dir="$1"
    local target_script="$install_dir/$SCRIPT_NAME"

    log_info "验证安装..."

    if [[ ! -f "$target_script" ]]; then
        log_error "脚本文件不存在: $target_script"
        return 1
    fi

    if [[ ! -x "$target_script" ]]; then
        log_error "脚本文件不可执行: $target_script"
        return 1
    fi

    if [[ ! -f "$CONFIG_DIR/$CONFIG_FILE" ]]; then
        log_error "配置文件不存在: $CONFIG_DIR/$CONFIG_FILE"
        return 1
    fi

    log_info "测试脚本执行..."
    if "$target_script" --help &> /dev/null; then
        log_success "安装验证成功"
        return 0
    else
        log_error "脚本执行测试失败"
        return 1
    fi
}

show_post_install_info() {
    local install_dir="$1"
    
    echo
    log_success "TaskSentinel 安装完成！"
    echo
    echo "安装信息:"
    echo "  主脚本: $install_dir/$SCRIPT_NAME"
    echo "  适配器: $install_dir/claude-hook-adapter"
    echo "  配置文件: $CONFIG_DIR/$CONFIG_FILE"
    echo
    echo "下一步:"
    echo "  1. 编辑配置文件: nano $CONFIG_DIR/$CONFIG_FILE"
    echo "  2. 配置您的 webhook URL 和密钥"
    echo "  3. 测试发送: $SCRIPT_NAME --message \"测试消息\""
    echo
    echo "Claude Code 集成:"
    echo "  1. 复制 Claude hooks 配置: cp $PROJECT_ROOT/config/claude-settings.example.json .claude/settings.json"
    echo "  2. 编辑 .claude/settings.json 中的钩子配置，使用以下命令:"
    echo "     \"command\": \"claude-hook-adapter\""
    echo "  3. 测试适配器:"
    echo "     echo '{\"hook_event_name\":\"Notification\",\"message\":\"测试\"}' | claude-hook-adapter"
    echo "  4. 支持的钩子类型: PreToolUse, PostToolUse, Notification, UserPromptSubmit, Stop, SubagentStop, PreCompact"
    echo
    echo "特色功能:"
    echo "  • 自动识别 Claude Code 钩子类型并智能处理"
    echo "  • 显示完整的钩子原始数据 (session_id, tool_name, tool_input 等)"
    echo "  • 根据不同工具类型优化消息显示"
    echo "  • 支持 Markdown 和文本格式通知"
    echo "  • 完全独立安装，无需保留项目目录"
    echo
    echo "使用帮助:"
    echo "  $SCRIPT_NAME --help"
    echo "  claude-hook-adapter --help"
    echo
    
    if [[ ":$PATH:" != *":$install_dir:"* ]]; then
        log_warning "安装目录不在 PATH 中: $install_dir"
        echo "请将以下行添加到您的 ~/.bashrc 或 ~/.zshrc:"
        echo "  export PATH=\"$install_dir:\$PATH\""
    fi
}

main() {
    local INSTALL_DIR="$DEFAULT_INSTALL_DIR"
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            -u|--uninstall)
                UNINSTALL_MODE=true
                shift
                ;;
            -q|--quiet)
                QUIET_MODE=true
                shift
                ;;
            -d|--dev)
                DEV_MODE=true
                shift
                ;;
            --install-dir)
                INSTALL_DIR="$2"
                shift 2
                ;;
            *)
                log_error "未知选项: $1"
                show_help
                exit 1
                ;;
        esac
    done

    if [[ "$UNINSTALL_MODE" == "true" ]]; then
        uninstall
        exit 0
    fi

    log_info "TaskSentinel 安装脚本启动"
    
    check_dependencies
    
    if [[ "$QUIET_MODE" != "true" ]]; then
        interactive_install
    fi
    
    create_user_directory
    copy_config_file
    
    local install_success=false
    
    if check_permissions "$INSTALL_DIR"; then
        if [[ "$INSTALL_DIR" == "/usr/local/bin" ]] || [[ "$INSTALL_DIR" == "/usr/bin" ]]; then
            if [[ $EUID -ne 0 ]]; then
                install_with_sudo "$INSTALL_DIR" && install_success=true
            else
                install_script "$INSTALL_DIR" && install_success=true
            fi
        else
            install_script "$INSTALL_DIR" && install_success=true
        fi
    else
        log_info "切换到用户目录安装: $FALLBACK_INSTALL_DIR"
        INSTALL_DIR="$FALLBACK_INSTALL_DIR"
        install_script "$INSTALL_DIR" && install_success=true
    fi
    
    if [[ "$install_success" == "true" ]]; then
        if validate_installation "$INSTALL_DIR"; then
            show_post_install_info "$INSTALL_DIR"
            exit 0
        else
            log_error "安装验证失败"
            exit 1
        fi
    else
        log_error "安装失败"
        exit 1
    fi
}

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi