#!/usr/bin/env python3
"""
通过宝塔 API 自动部署 AI 面试系统
"""
import requests
import time
import hashlib
import os
import base64
import json

# 禁用 SSL 警告
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# 宝塔配置
BT_PANEL = "http://47.107.172.23:8888"
BT_API_KEY = "PKdfnaInQL0P5ghB8SvwbrGcIpXWaEvq"

# 部署配置
DEPLOY_PATH = "/www/wwwroot/ai-interview"
DOMAIN = "interview.test.ai.ireborn.com.cn"


def bt_api(action, data=None, files=None):
    """调用宝塔 API"""
    if data is None:
        data = {}
    
    request_time = int(time.time())
    request_token = hashlib.md5(
        f"{request_time}{hashlib.md5(BT_API_KEY.encode()).hexdigest()}".encode()
    ).hexdigest()
    
    data['request_time'] = request_time
    data['request_token'] = request_token
    
    url = f"{BT_PANEL}/{action}"
    
    try:
        if files:
            response = requests.post(url, data=data, files=files, timeout=300, verify=False)
        else:
            response = requests.post(url, data=data, timeout=60, verify=False)
        return response.json()
    except requests.exceptions.JSONDecodeError:
        return {"status": True, "msg": response.text}
    except Exception as e:
        return {"status": False, "msg": str(e)}


def create_directory(path):
    """创建目录"""
    print(f"📁 创建目录: {path}")
    result = bt_api("files?action=CreateDir", {"path": path})
    if result.get("status") or "已存在" in str(result.get("msg", "")):
        print("   ✅ 目录已就绪")
        return True
    print(f"   ⚠️ {result}")
    return True  # 继续执行


def upload_file(local_path, remote_dir):
    """上传文件到服务器"""
    filename = os.path.basename(local_path)
    print(f"📤 上传文件: {filename}")
    
    with open(local_path, 'rb') as f:
        files = {'f_path': (filename, f)}
        data = {'f_path': remote_dir, 'f_name': filename}
        result = bt_api("files?action=upload", data, files)
    
    if result.get("status") or result.get("msg") == "上传成功":
        print(f"   ✅ 上传成功")
        return True
    print(f"   ❌ 上传失败: {result}")
    return False


def exec_shell(command):
    """执行 Shell 命令"""
    print(f"🔧 执行命令: {command[:80]}...")
    result = bt_api("files?action=ExecShell", {"command": command})
    return result


def create_website(domain):
    """创建网站"""
    print(f"🌐 创建网站: {domain}")
    data = {
        "webname": json.dumps({"domain": domain, "domainlist": [], "count": 0}),
        "path": f"/www/wwwroot/{domain}",
        "type_id": 0,
        "type": "PHP",
        "version": "00",
        "port": "80",
        "ps": "AI面试系统",
        "ftp": "false",
        "sql": "false"
    }
    result = bt_api("site?action=AddSite", data)
    if result.get("status") or result.get("siteStatus"):
        print("   ✅ 网站创建成功")
        return True
    if "已存在" in str(result.get("msg", "")):
        print("   ⚠️ 网站已存在")
        return True
    print(f"   结果: {result}")
    return True


def set_proxy(domain, target_url):
    """设置反向代理"""
    print(f"🔄 设置反向代理: {domain} -> {target_url}")
    
    # 获取站点 ID
    sites_result = bt_api("site?action=GetSitesSort")
    site_id = None
    if sites_result.get("data"):
        for site in sites_result["data"]:
            if site.get("name") == domain:
                site_id = site.get("id")
                break
    
    if not site_id:
        print("   ⚠️ 未找到站点 ID，尝试继续...")
        return True
    
    # 设置代理
    proxy_data = {
        "sitename": domain,
        "proxyname": "ai-interview",
        "proxydir": "/",
        "proxysite": target_url,
        "proxysend": "0",
        "cache": "0",
        "cacheTime": "1",
        "subfilter": "[]",
        "type": "1",
        "advanced": "0"
    }
    result = bt_api("site?action=CreateProxy", proxy_data)
    print(f"   结果: {result}")
    return True


def write_remote_file(path, content):
    """写入远程文件"""
    print(f"📝 写入文件: {path}")
    # 使用 base64 编码内容
    encoded = base64.b64encode(content.encode()).decode()
    result = bt_api("files?action=SaveFileBody", {
        "path": path,
        "data": content,
        "encoding": "utf-8"
    })
    if result.get("status"):
        print("   ✅ 文件写入成功")
        return True
    print(f"   结果: {result}")
    return True


def main():
    print("=" * 60)
    print("🚀 AI 语音面试系统 - 自动部署")
    print("=" * 60)
    print()
    
    # 1. 创建部署目录
    print("\n📦 步骤 1: 创建目录结构")
    create_directory(DEPLOY_PATH)
    create_directory(f"{DEPLOY_PATH}/frontend")
    create_directory(f"{DEPLOY_PATH}/backend")
    create_directory(f"{DEPLOY_PATH}/deploy")
    create_directory(f"{DEPLOY_PATH}/deploy/nginx")
    
    # 2. 写入配置文件
    print("\n📝 步骤 2: 写入配置文件")
    
    # .env 文件
    env_content = """COZE_PAT_TOKEN=pat_nd1wU47WyPS9GCIyJ1clnH8h1WOQXGrYELX8w73TnSZaYbFdYD4swIhzcETBUbfT
COZE_BOT_ID=7595113005181386792
COZE_WORKFLOW_A_ID=7597357422713798710
COZE_WORKFLOW_C_ID=7597376294612107318
FILE_SERVER_URL=https://files.test.ai.ireborn.com.cn
FILE_SERVER_TOKEN=ai_interview_2026_secret
"""
    write_remote_file(f"{DEPLOY_PATH}/deploy/.env", env_content)
    
    # 3. 上传部署包
    print("\n📤 步骤 3: 上传部署包")
    tar_path = "/Users/a111/Documents/AgentWD/projects/ai-interview-deploy.tar.gz"
    if os.path.exists(tar_path):
        upload_file(tar_path, "/www/wwwroot")
    else:
        print(f"   ⚠️ 部署包不存在: {tar_path}")
    
    # 4. 解压并部署
    print("\n🔧 步骤 4: 解压部署包")
    commands = [
        f"cd /www/wwwroot && tar -xzf ai-interview-deploy.tar.gz -C {DEPLOY_PATH}",
        f"cd {DEPLOY_PATH}/deploy && cp .env .env.bak 2>/dev/null || true",
    ]
    for cmd in commands:
        exec_shell(cmd)
        time.sleep(1)
    
    # 5. 启动 Docker
    print("\n🐳 步骤 5: 启动 Docker 容器")
    docker_commands = [
        f"cd {DEPLOY_PATH}/deploy && docker-compose down 2>/dev/null || true",
        f"cd {DEPLOY_PATH}/deploy && docker-compose up -d --build",
    ]
    for cmd in docker_commands:
        print(f"   执行: {cmd}")
        result = exec_shell(cmd)
        print(f"   结果: {result}")
        time.sleep(3)
    
    # 6. 创建网站和反向代理
    print("\n🌐 步骤 6: 配置网站")
    create_website(DOMAIN)
    time.sleep(2)
    set_proxy(DOMAIN, "http://127.0.0.1:3000")
    
    # 7. 检查状态
    print("\n🔍 步骤 7: 检查部署状态")
    result = exec_shell("docker ps --format 'table {{.Names}}\\t{{.Status}}\\t{{.Ports}}'")
    print(f"   容器状态: {result}")
    
    print()
    print("=" * 60)
    print("✅ 部署完成!")
    print("=" * 60)
    print()
    print(f"🌐 访问地址:")
    print(f"   用户端:    http://{DOMAIN}")
    print(f"   管理后台:  http://{DOMAIN}/admin")
    print()
    print("⚠️ 如需 HTTPS，请在宝塔面板中为该网站申请 SSL 证书")
    print("=" * 60)


if __name__ == "__main__":
    main()
