#!/usr/bin/env python3
"""
终极方案：用 Playwright 模拟真实用户在 DeepSeek 网页 UI 上操作，
点击登录按钮、填写邮箱密码、提交，获取 session token。
纯 UI 交互，不触发 API 级别的 WAF 检测。
"""
import asyncio
import json
import sys
from playwright.async_api import async_playwright

ACCOUNTS_FILE = "/root/accounts.json"
OUTPUT = "/tmp/ds_sessions.json"


async def login_via_ui(page, email: str, password: str) -> dict:
    """通过真实 UI 交互登录 DeepSeek"""
    try:
        # 1. 访问首页
        await page.goto("https://chat.deepseek.com/", wait_until="networkidle", timeout=60000)
        await asyncio.sleep(2)

        # 2. 点击登录按钮
        # DeepSeek 首页有 "登录" 按钮
        login_btn = page.locator('text=登录').first
        if await login_btn.count() == 0:
            login_btn = page.locator('button:has-text("登录")').first
        if await login_btn.count() == 0:
            login_btn = page.locator('a:has-text("登录")').first
        if await login_btn.count() == 0:
            # 尝试英文
            login_btn = page.locator('text=Log in').first
        if await login_btn.count() == 0:
            login_btn = page.locator('text=Sign in').first
        
        if await login_btn.count() > 0:
            print("  [UI] 点击登录按钮...")
            await login_btn.click()
            await asyncio.sleep(2)
        else:
            print("  [UI] 未找到登录按钮，尝试直接访问登录页...")
            await page.goto("https://chat.deepseek.com/sign_in", wait_until="networkidle", timeout=30000)
            await asyncio.sleep(2)

        # 3. 填写邮箱
        print("  [UI] 填写邮箱...")
        email_input = page.locator('input[type="email"], input[placeholder*="邮箱"], input[placeholder*="email"], input[placeholder*="Email"]').first
        if await email_input.count() == 0:
            email_input = page.locator('input').first
        await email_input.fill(email)
        await asyncio.sleep(0.5)

        # 4. 填写密码
        print("  [UI] 填写密码...")
        pwd_input = page.locator('input[type="password"]').first
        await pwd_input.fill(password)
        await asyncio.sleep(0.5)

        # 5. 点击提交按钮
        print("  [UI] 提交登录...")
        submit_btn = page.locator('button[type="submit"]').first
        if await submit_btn.count() == 0:
            submit_btn = page.locator('button:has-text("登录"), button:has-text("Log in"), button:has-text("Sign in")').first
        if await submit_btn.count() == 0:
            submit_btn = page.locator('button').first
        await submit_btn.click()

        # 6. 等待登录完成
        await asyncio.sleep(5)
        await page.wait_for_load_state("networkidle", timeout=30000)

        # 7. 提取 token
        print("  [UI] 提取 session token...")
        token = await page.evaluate("""
            () => {
                // 尝试从 localStorage 提取
                for (let i = 0; i < localStorage.length; i++) {
                    const key = localStorage.key(i);
                    const val = localStorage.getItem(key);
                    if (val && val.length > 100 && (key.includes('token') || key.includes('user') || key.includes('session'))) {
                        try { const p = JSON.parse(val); if (p.token) return p.token; } catch(e) {}
                        return val;
                    }
                }
                // 尝试从 cookie 提取
                const cookies = document.cookie.split(';');
                for (const c of cookies) {
                    const [k, v] = c.trim().split('=');
                    if (k && v && v.length > 50) return v;
                }
                return null;
            }
        """)

        print(f"  [UI] token={token[:50] if token else 'null'}...")
        return {"method": "ui", "token": token, "url": page.url}

    except Exception as e:
        print(f"  [UI] 异常: {e}")
        return {"method": "ui", "error": str(e)}


async def main():
    with open(ACCOUNTS_FILE) as f:
        accounts = json.load(f)

    results = []
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            args=["--no-sandbox", "--disable-gpu", "--disable-dev-shm-usage",
                  "--disable-setuid-sandbox", "--no-first-run", "--no-zygote",
                  "--single-process"],
        )
        context = await browser.new_context(
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
            viewport={"width": 1920, "height": 1080},
            locale="zh-CN",
        )
        page = await context.new_page()

        for acc in accounts:
            email = acc["email"]
            password = acc["password"]
            print(f"\n[LOGIN] {email}")
            r = await login_via_ui(page, email, password)
            results.append({"email": email, **r})

        await browser.close()

    with open(OUTPUT, "w") as f:
        json.dump(results, f, indent=2, ensure_ascii=False)
    print(f"\n[OK] Saved to {OUTPUT}")


if __name__ == "__main__":
    asyncio.run(main())