#!/bin/bash
# Momentry n8n Workflow 備份腳本
# 路徑: /Users/accusys/momentry_core_0.1/monitor/workflow/backup_n8n_workflows.sh
#
# 功能:
#   - 導出所有 workflows 為 n8n 原生 JSON 格式
#   - 按用戶分組備份
#   - 版本化存儲
#
# 使用方式:
#   ./backup_n8n_workflows.sh          # 備份所有 workflows
#   ./backup_n8n_workflows.sh daily     # 每日增量備份
#   ./backup_n8n_workflows.sh full      # 完整備份
#   ./backup_n8n_workflows.sh restore   # 列出可恢復版本

set -e

# ============================================
# 配置
# ============================================

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKUP_ROOT="/Users/accusys/momentry/backup/n8n_workflows"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_DIR="/Users/accusys/momentry/log/monitor"

# 載入密碼配置
MONITOR_DIR="$(dirname "$SCRIPT_DIR")"
if [ -f "$MONITOR_DIR/common/load_credentials.sh" ]; then
    source "$MONITOR_DIR/common/load_credentials.sh"
fi

# n8n 數據庫連接 (使用 n8n 用戶)
N8N_PG_USER="${N8N_PG_USER:-n8n}"
N8N_PG_PASSWORD="${N8N_PG_PASSWORD:-accusys}"
N8N_PG_HOST="${N8N_PG_HOST:-localhost}"
N8N_PG_DB="${N8N_PG_DB:-n8n}"

# 確保目錄存在
mkdir -p "$LOG_DIR"
mkdir -p "$BACKUP_ROOT"

# ============================================
# 顏色
# ============================================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

# ============================================
# 日誌函數
# ============================================
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_DIR/workflow_backup.log"
}

log_success() {
    echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] ✅ $1${NC}" | tee -a "$LOG_DIR/workflow_backup.log"
}

log_error() {
    echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ❌ $1${NC}" | tee -a "$LOG_DIR/workflow_backup.log"
}

log_warn() {
    echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] ⚠️  $1${NC}" | tee -a "$LOG_DIR/workflow_backup.log"
}

# ============================================
# 導出單個 Workflow (n8n 原生格式)
# ============================================
export_workflow() {
    local wf_id=$1
    local output_file=$2
    
    # 查詢 workflow 數據 (包含所有 n8n 需要的欄位)
    PGPASSWORD="$N8N_PG_PASSWORD" psql -U "$N8N_PG_USER" -h "$N8N_PG_HOST" -d "$N8N_PG_DB" -t -A -c "
        SELECT json_build_object(
            'id', id,
            'name', name,
            'active', active,
            'nodes', nodes,
            'connections', connections,
            'settings', COALESCE(settings, '{}'),
            'staticData', COALESCE(\"staticData\", 'null'),
            'pinData', COALESCE(\"pinData\", 'null'),
            'versionId', \"versionId\",
            'triggerCount', \"triggerCount\",
            'createdAt', \"createdAt\",
            'updatedAt', \"updatedAt\",
            'isArchived', \"isArchived\",
            'versionCounter', \"versionCounter\",
            'description', COALESCE(description, ''),
            'meta', COALESCE(meta, '{}')
        )
        FROM workflow_entity
        WHERE id = '$wf_id';
    " > "$output_file" 2>&1
    
    # 移除錯誤輸出
    if grep -q "ERROR:" "$output_file" 2>/dev/null; then
        sed -i '/ERROR:/d' "$output_file"
    fi
    
    if [ -s "$output_file" ]; then
        return 0
    else
        return 1
    fi
}

# ============================================
# 按用戶導出 Workflows
# ============================================
export_workflows_by_user() {
    local user_id=$1
    local user_email=$2
    local output_dir=$3
    
    log "導出用戶 $user_email 的 workflows..."
    
    mkdir -p "$output_dir"
    
    local count=0
    
    # 獲取該用戶的 workflows
    workflows=$(PGPASSWORD="$N8N_PG_PASSWORD" psql -U "$N8N_PG_USER" -h "$N8N_PG_HOST" -d "$N8N_PG_DB" -t -A -c "
        SELECT DISTINCT w.id, w.name
        FROM workflow_entity w
        LEFT JOIN shared_workflow sw ON w.id = sw.\"workflowId\"
        LEFT JOIN project p ON sw.\"projectId\" = p.id
        WHERE p.\"creatorId\" = '$user_id'
           OR w.id IN (
               SELECT \"workflowId\" FROM shared_workflow 
               WHERE \"projectId\" IN (
                   SELECT id FROM project WHERE \"creatorId\" = '$user_id'
               )
           )
        ORDER BY w.name;
    " 2>/dev/null)
    
    while IFS='|' read -r wf_id wf_name; do
        if [ -n "$wf_id" ]; then
            # 清理文件名
            local safe_name=$(echo "$wf_name" | sed 's/[^a-zA-Z0-9_-]/_/g')
            local output_file="$output_dir/${safe_name}.json"
            
            if export_workflow "$wf_id" "$output_file"; then
                log "  ✅ $wf_name"
                ((count++))
            else
                log_error "  ❌ $wf_name (ID: $wf_id)"
            fi
        fi
    done <<< "$workflows"
    
    echo "$count"
}

# ============================================
# 導出所有 Workflows (n8n 批量格式)
# ============================================
export_all_workflows() {
    local output_file="$1"
    
    log "導出所有 workflows..."
    
    # 導出 workflows
    PGPASSWORD="$N8N_PG_PASSWORD" psql -U "$N8N_PG_USER" -h "$N8N_PG_HOST" -d "$N8N_PG_DB" -t -A -c "
        SELECT json_agg(
            json_build_object(
                'id', id,
                'name', name,
                'active', active,
                'nodes', nodes,
                'connections', connections,
                'settings', COALESCE(settings, '{}'),
                'staticData', COALESCE(\"staticData\", 'null'),
                'pinData', COALESCE(\"pinData\", 'null'),
                'versionId', \"versionId\",
                'triggerCount', \"triggerCount\",
                'createdAt', \"createdAt\",
                'updatedAt', \"updatedAt\",
                'isArchived', \"isArchived\",
                'versionCounter', \"versionCounter\",
                'description', COALESCE(description, ''),
                'meta', COALESCE(meta, '{}')
            )
        )
        FROM workflow_entity;
    " > "$output_file" 2>&1
    
    # 移除 psql 錯誤輸出
    if grep -q "ERROR:" "$output_file" 2>/dev/null; then
        sed -i '/ERROR:/d' "$output_file"
    fi
    
    if [ $? -eq 0 ] && [ -s "$output_file" ]; then
        log_success "導出完成: $output_file"
        return 0
    else
        log_error "導出失敗"
        return 1
    fi
}

# ============================================
# 完整備份 (所有 workflows + 用戶)
# ============================================
backup_full() {
    log "=========================================="
    log "開始完整 n8n Workflow 備份"
    log "=========================================="
    
    local backup_dir="$BACKUP_ROOT/full/$TIMESTAMP"
    mkdir -p "$backup_dir"
    
    # 1. 導出所有 workflows 為單一檔案
    export_all_workflows "$backup_dir/all_workflows.json"
    
    # 2. 導出執行歷史統計
    log ""
    log "導出執行統計..."
    PGPASSWORD="$N8N_PG_PASSWORD" psql -U "$N8N_PG_USER" -h "$N8N_PG_HOST" -d "$N8N_PG_DB" -t -A -c "
        SELECT json_agg(
            json_build_object(
                'workflow_id', w.id,
                'workflow_name', w.name,
                'total_executions', e.total_executions,
                'successful_executions', e.successful_executions,
                'failed_executions', e.failed_executions,
                'last_execution', e.last_execution
            )
        )
        FROM (
            SELECT 
                \"workflowId\" as wid,
                COUNT(*) as total_executions,
                COUNT(CASE WHEN status = 'success' THEN 1 END) as successful_executions,
                COUNT(CASE WHEN status = 'error' THEN 1 END) as failed_executions,
                MAX(\"startedAt\") as last_execution
            FROM execution_entity
            GROUP BY \"workflowId\"
        ) e
        JOIN workflow_entity w ON e.wid = w.id;
    " > "$backup_dir/execution_stats.json" 2>&1
    
    # 移除錯誤輸出
    if grep -q "ERROR:" "$backup_dir/execution_stats.json" 2>/dev/null; then
        sed -i '/ERROR:/d' "$backup_dir/execution_stats.json"
    fi
    
    # 3. 生成備份清單
    local workflow_count=$(cat "$backup_dir/all_workflows.json" 2>/dev/null | jq '. | length' 2>/dev/null || echo "0")
    cat > "$backup_dir/manifest.json" << EOF
{
    "backup_time": "$(date -Iseconds)",
    "timestamp": "$TIMESTAMP",
    "workflow_count": $workflow_count,
    "version": "1.0"
}
EOF
    
    # 5. 計算 SHA256
    sha256sum "$backup_dir/all_workflows.json" > "$backup_dir/all_workflows.json.sha256"
    
    log ""
    log_success "備份完成!"
    log "備份目錄: $backup_dir"
    log "Workflow 總數: $workflow_count"
}

# ============================================
# 增量備份 (每日)
# ============================================
backup_daily() {
    local backup_dir="$BACKUP_ROOT/daily/$(date +%Y%m%d)"
    
    log "=========================================="
    log "開始每日 n8n Workflow 增量備份"
    log "=========================================="
    
    mkdir -p "$backup_dir"
    
    # 導出所有 workflows
    export_all_workflows "$backup_dir/workflows.json"
    
    # SHA256 校驗
    sha256sum "$backup_dir/workflows.json" > "$backup_dir/workflows.json.sha256"
    
    log_success "每日備份完成: $backup_dir/workflows.json"
}

# ============================================
# 列出可恢復版本
# ============================================
list_backups() {
    log ""
    log "=========================================="
    log "可用備份版本"
    log "=========================================="
    log ""
    
    echo "📁 完整備份:"
    for dir in "$BACKUP_ROOT"/full/*/; do
        if [ -d "$dir" ]; then
            local name=$(basename "$dir")
            local count=$(cat "$dir/all_workflows.json" 2>/dev/null | jq '. | length' 2>/dev/null || echo "?")
            echo "  $name ($count workflows)"
        fi
    done
    
    echo ""
    echo "📁 每日備份:"
    for dir in "$BACKUP_ROOT"/daily/*/; do
        if [ -d "$dir" ]; then
            local name=$(basename "$dir")
            local size=$(du -sh "$dir" | cut -f1)
            echo "  $name ($size)"
        fi
    done
}

# ============================================
# 恢復 Workflow
# ============================================
restore_workflow() {
    local backup_file=$1
    local wf_name=$2
    
    if [ ! -f "$backup_file" ]; then
        log_error "備份文件不存在: $backup_file"
        return 1
    fi
    
    log "從 $backup_file 恢復 workflow..."
    
    # 這需要 n8n API 或直接 SQL 插入
    # 這裡只是示範結構
    log_warn "請使用 n8n UI 或 API 進行恢復"
    log "備份文件格式:"
    jq 'keys' "$backup_file" 2>/dev/null
}

# ============================================
# 主程序
# ============================================
main() {
    case "${1:-full}" in
        full)
            backup_full
            ;;
        daily)
            backup_daily
            ;;
        list)
            list_backups
            ;;
        restore)
            restore_workflow "$2" "$3"
            ;;
        *)
            echo "用法: $0 [full|daily|list|restore]"
            echo ""
            echo "命令:"
            echo "  full     - 完整備份 (所有 workflows + 用戶分組)"
            echo "  daily    - 每日增量備份"
            echo "  list     - 列出可用備份"
            echo "  restore  - 恢復 workflow"
            exit 1
            ;;
    esac
}

main "$@"
