#!/bin/bash

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
DATA_CENTER_DIR="$PROJECT_ROOT/data_center"

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

REMOTE_HOST="124.174.37.152"
REMOTE_USER="root"
REMOTE_PASS='Lsinfo_123$#.hs'
REMOTE_BACKUP_DIR="/lsinfo/ai/hellotax_ai/data_center/backup"
REMOTE_DATA_DIR="/lsinfo/ai/hellotax_ai/data_center/data"
REMOTE_DB_URL="postgresql://hellotax:yhUCSwHadU2H2LrngASzDNHQ0e4FFTOY@localhost:5435/hellotax"
REMOTE_DB_USER="hellotax"
REMOTE_DB_PASS="yhUCSwHadU2H2LrngASzDNHQ0e4FFTOY"
REMOTE_DB_HOST="localhost"
REMOTE_DB_PORT="5435"
REMOTE_DB_NAME="hellotax"

FROM_STEP=1
ARCHIVE=""

while [[ $# -gt 0 ]]; do
    case "$1" in
        --from-step) FROM_STEP="$2"; shift 2 ;;
        --archive)   ARCHIVE="$2";   shift 2 ;;
        *) echo -e "${RED}未知参数: $1${NC}"; exit 1 ;;
    esac
done

ssh_exec() {
    sshpass -p "$REMOTE_PASS" ssh -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" "$@"
}

rsync_upload() {
    SSHPASS="$REMOTE_PASS" rsync -az --progress \
        -e "sshpass -e ssh -o StrictHostKeyChecking=no" \
        "$1" "$REMOTE_USER@$REMOTE_HOST:$2"
}

step_done() { echo -e "${GREEN}[步骤$1完成]${NC}"; }
step_fail() {
    local step=$1; shift
    echo -e "${RED}[步骤${step}失败]${NC} 重试：$0 --from-step $step --archive \"$ARCHIVE\" $*"
    exit 1
}

# 检查依赖
if ! command -v sshpass &>/dev/null; then
    echo -e "${RED}错误：未找到 sshpass，请先安装：brew install sshpass${NC}"
    exit 1
fi
if ! command -v pg_dump &>/dev/null; then
    echo -e "${RED}错误：未找到 pg_dump${NC}"
    exit 1
fi

# ── 步骤 1：本地备份打包 ──────────────────────────────────────────────────────
if [ "$FROM_STEP" -le 1 ]; then
    echo -e "\n${YELLOW}[1/6] 本地导出数据库并打包...${NC}"

    ENV_FILE="$DATA_CENTER_DIR/backend/.env.development"
    [ ! -f "$ENV_FILE" ] && ENV_FILE="$DATA_CENTER_DIR/backend/.env"
    [ ! -f "$ENV_FILE" ] && echo -e "${RED}错误：未找到 backend/.env.development 或 backend/.env${NC}" && exit 1

    DATABASE_URL=$(grep -E "^DATABASE_URL=" "$ENV_FILE" | cut -d'=' -f2-)
    DB_USER=$(echo "$DATABASE_URL" | sed -E 's|postgresql://([^:]+):.*|\1|')
    DB_PASS=$(echo "$DATABASE_URL" | sed -E 's|postgresql://[^:]+:([^@]+)@.*|\1|')
    DB_HOST=$(echo "$DATABASE_URL" | sed -E 's|.*@([^:/]+)[:/].*|\1|')
    DB_PORT=$(echo "$DATABASE_URL" | sed -E 's|.*:([0-9]+)/.*|\1|')
    DB_NAME=$(echo "$DATABASE_URL" | sed -E 's|.*/([^?]+).*|\1|')

    TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
    BACKUP_DIR="$DATA_CENTER_DIR/backups/tmp_$TIMESTAMP"
    mkdir -p "$BACKUP_DIR"

    export PGPASSWORD="$DB_PASS"
    docker exec -e PGPASSWORD="$DB_PASS" data_center_postgres \
        pg_dump -h localhost -U "$DB_USER" --schema=data_center "$DB_NAME" > "$BACKUP_DIR/db.sql" || step_fail 1
    unset PGPASSWORD

    ARCHIVE="$DATA_CENTER_DIR/backups/backup_${TIMESTAMP}.tar.gz"
    tar_args=(-czf "$ARCHIVE" -C "$BACKUP_DIR" db.sql)
    if [ -d "$DATA_CENTER_DIR/data" ]; then
        tar_args+=(-C "$DATA_CENTER_DIR" data)
    else
        echo -e "${YELLOW}警告：data/ 目录不存在，仅打包数据库${NC}"
    fi
    tar "${tar_args[@]}" || step_fail 1

    rm -rf "$BACKUP_DIR"

    LOCAL_MD5=$(md5 -q "$ARCHIVE" 2>/dev/null || md5sum "$ARCHIVE" | cut -d' ' -f1)
    echo "  MD5: $LOCAL_MD5"
    step_done 1
    echo "  压缩包：$ARCHIVE"
fi

[ -z "$ARCHIVE" ] && echo -e "${RED}错误：--from-step >= 2 时需要指定 --archive <path>${NC}" && exit 1
[ ! -f "$ARCHIVE" ] && echo -e "${RED}错误：压缩包不存在：$ARCHIVE${NC}" && exit 1

ARCHIVE_NAME=$(basename "$ARCHIVE")
TIMESTAMP=$(echo "$ARCHIVE_NAME" | sed -E 's/backup_(.+)\.tar\.gz/\1/')
REMOTE_TMP="$REMOTE_BACKUP_DIR/tmp_$TIMESTAMP"

# ── 步骤 2：上传 ──────────────────────────────────────────────────────────────
if [ "$FROM_STEP" -le 2 ]; then
    echo -e "\n${YELLOW}[2/6] 上传压缩包到远程服务器（rsync 断点续传）...${NC}"
    ssh_exec "mkdir -p $REMOTE_BACKUP_DIR" || step_fail 2
    rsync_upload "$ARCHIVE" "$REMOTE_BACKUP_DIR/" || step_fail 2

    LOCAL_MD5=$(md5 -q "$ARCHIVE" 2>/dev/null || md5sum "$ARCHIVE" | cut -d' ' -f1)
    REMOTE_MD5=$(ssh_exec "md5sum $REMOTE_BACKUP_DIR/$ARCHIVE_NAME | cut -d' ' -f1") || step_fail 2
    if [ "$LOCAL_MD5" != "$REMOTE_MD5" ]; then
        echo -e "${RED}错误：MD5 校验失败（本地: $LOCAL_MD5，远程: $REMOTE_MD5）${NC}"
        step_fail 2
    fi
    echo "  MD5 校验通过：$LOCAL_MD5"
    step_done 2
fi

# ── 步骤 3：远程解压 ──────────────────────────────────────────────────────────
if [ "$FROM_STEP" -le 3 ]; then
    echo -e "\n${YELLOW}[3/6] 远程解压压缩包...${NC}"
    ssh_exec "mkdir -p $REMOTE_TMP && tar -xzf $REMOTE_BACKUP_DIR/$ARCHIVE_NAME -C $REMOTE_TMP" || step_fail 3
    step_done 3
fi

# ── 步骤 4：远程恢复 data/ 目录 ───────────────────────────────────────────────
if [ "$FROM_STEP" -le 4 ]; then
    echo -e "\n${YELLOW}[4/6] 远程恢复 data/ 目录...${NC}"
    ssh_exec "
        if [ -d $REMOTE_TMP/data ]; then
            rm -rf $REMOTE_DATA_DIR
            mv $REMOTE_TMP/data $REMOTE_DATA_DIR
            echo 'data/ 目录已恢复'
        else
            echo '压缩包中无 data/ 目录，跳过'
        fi
    " || step_fail 4
    step_done 4
fi

# ── 步骤 5：远程导入数据库 ────────────────────────────────────────────────────
if [ "$FROM_STEP" -le 5 ]; then
    echo -e "\n${YELLOW}[5/6] 远程导入数据库...${NC}"
    ssh_exec "
        export PGPASSWORD='$REMOTE_DB_PASS'
        echo '清空 public schema...'
        psql -h $REMOTE_DB_HOST -p $REMOTE_DB_PORT -U $REMOTE_DB_USER $REMOTE_DB_NAME -c \
            'DROP SCHEMA IF EXISTS public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO $REMOTE_DB_USER;'

        echo '导入 db.sql...'
        psql -h $REMOTE_DB_HOST -p $REMOTE_DB_PORT -U $REMOTE_DB_USER $REMOTE_DB_NAME -f $REMOTE_TMP/db.sql

        echo '迁移数据到 data_center schema...'
        psql -h $REMOTE_DB_HOST -p $REMOTE_DB_PORT -U $REMOTE_DB_USER $REMOTE_DB_NAME <<'SQL'
INSERT INTO data_center.data_sources SELECT * FROM public.data_sources ON CONFLICT DO NOTHING;
INSERT INTO data_center.tax_documents (
  id, source_url, category_id, doc_number, title, issuing_authority,
  issue_date, effective_date, content_html, content_markdown, file_path,
  attachments, processing_status, content_hash, last_check_time, is_imported,
  knowledge_doc_id, created_at, updated_at, fetch_strategy, supersedes,
  \"references\", content_text, source_id, doc_type, region_code, qa_question,
  qa_answer, interpretation_form, inline_images, inline_videos, doc_status
)
SELECT
  id, source_url, category_id, doc_number, title, issuing_authority,
  issue_date, effective_date, content_html, content_markdown, file_path,
  attachments, processing_status, content_hash, last_check_time, is_imported,
  knowledge_doc_id, created_at, updated_at, fetch_strategy, supersedes,
  \"references\", content_text, source_id, doc_type, region_code, qa_question,
  qa_answer, interpretation_form, inline_images, inline_videos, doc_status
FROM public.tax_documents ON CONFLICT DO NOTHING;
INSERT INTO data_center.data_processing_tasks SELECT * FROM public.data_processing_tasks ON CONFLICT DO NOTHING;
INSERT INTO data_center.processing_logs SELECT * FROM public.processing_logs ON CONFLICT DO NOTHING;
INSERT INTO data_center.tax_documents_versions SELECT * FROM public.tax_document_versions ON CONFLICT DO NOTHING;
SELECT setval('data_center.tax_documents_id_seq', COALESCE((SELECT MAX(id) FROM data_center.tax_documents), 1));
SELECT setval('data_center.data_processing_tasks_id_seq', COALESCE((SELECT MAX(id) FROM data_center.data_processing_tasks), 1));
SQL

        echo '修复文件路径前缀...'
        psql -h $REMOTE_DB_HOST -p $REMOTE_DB_PORT -U $REMOTE_DB_USER $REMOTE_DB_NAME <<SQL
UPDATE public.tax_documents
SET
  file_path = regexp_replace(file_path, '^.*/data_center/data/', '$REMOTE_DATA_DIR/'),
  inline_images = (
    SELECT json_agg(jsonb_set(e::jsonb, '{path}',
      to_jsonb(regexp_replace(e->>'path', '^.*/data_center/data/', '$REMOTE_DATA_DIR/'))))
    FROM json_array_elements(inline_images) e
  ),
  inline_videos = (
    SELECT json_agg(jsonb_set(e::jsonb, '{path}',
      to_jsonb(regexp_replace(e->>'path', '^.*/data_center/data/', '$REMOTE_DATA_DIR/'))))
    FROM json_array_elements(inline_videos) e
  )
WHERE file_path LIKE '%/data_center/data/%'
   OR inline_images::text LIKE '%/data_center/data/%'
   OR inline_videos::text LIKE '%/data_center/data/%';

UPDATE data_center.tax_documents d
SET file_path = p.file_path, inline_images = p.inline_images, inline_videos = p.inline_videos
FROM public.tax_documents p
WHERE d.id = p.id
  AND (p.file_path IS NOT NULL OR p.inline_images IS NOT NULL OR p.inline_videos IS NOT NULL);
SQL
        unset PGPASSWORD
    " || step_fail 5
    step_done 5
fi

# ── 步骤 6：清理远程临时目录 ──────────────────────────────────────────────────
if [ "$FROM_STEP" -le 6 ]; then
    echo -e "\n${YELLOW}[6/6] 清理远程临时目录...${NC}"
    ssh_exec "rm -rf $REMOTE_TMP" || step_fail 6
    step_done 6
fi

echo -e "\n${GREEN}=========================================="
echo "部署完成！"
echo "==========================================${NC}"
echo "本地备份：$ARCHIVE"
echo "远程备份：$REMOTE_BACKUP_DIR/$ARCHIVE_NAME"
echo "远程数据：$REMOTE_DATA_DIR"
