"""
子系统后端示例 - 集成SSO认证
"""
import sys
import os
  # 手动配置路径（兼容性）
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..'))
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../../..'))
from fastapi import FastAPI, Depends, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import RedirectResponse, JSONResponse
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from pydantic import BaseModel
from typing import Optional, Dict, Any
import httpx
import os
from urllib.parse import urlencode
import secrets
from dotenv import load_dotenv
from src.core.config import config_handler

# 加载环境变量
#load_dotenv()

app = FastAPI(title="子系统示例", version="1.0.0")

# CORS配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3001"],  # 子系统前端地址
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# SSO配置
SSO_BASE_URL = config_handler.get("sub_system_app","SSO_BASE_URL", "http://localhost:8000")
CLIENT_ID = config_handler.get("sub_system_app","CLIENT_ID", "your-client-id")
CLIENT_SECRET = config_handler.get("sub_system_app","CLIENT_SECRET", "your-client-secret")
REDIRECT_URI = config_handler.get("sub_system_app","REDIRECT_URI", "http://localhost:8001/auth/callback")

print(f"🔧 SSO配置:")
print(f"   SSO_BASE_URL: {SSO_BASE_URL}")
print(f"   CLIENT_ID: {CLIENT_ID}")
print(f"   CLIENT_SECRET: {CLIENT_SECRET[:20]}...")
print(f"   REDIRECT_URI: {REDIRECT_URI}")

security = HTTPBearer()

class UserInfo(BaseModel):
    """用户信息模型"""
    id: str
    username: str
    email: str
    phone: Optional[str] = None
    avatar_url: Optional[str] = None
    is_active: bool

class TokenResponse(BaseModel):
    """令牌响应模型"""
    access_token: str
    refresh_token: Optional[str] = None
    token_type: str
    expires_in: int
    scope: Optional[str] = None

# 内存存储（生产环境应使用数据库或Redis）
user_sessions: Dict[str, UserInfo] = {}
access_tokens: Dict[str, str] = {}  # token -> user_id

async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)) -> UserInfo:
    """获取当前用户"""
    token = credentials.credentials
    
    # 检查本地token缓存
    user_id = access_tokens.get(token)
    if user_id and user_id in user_sessions:
        return user_sessions[user_id]
    
    # 向SSO服务验证token
    async with httpx.AsyncClient() as client:
        try:
            response = await client.get(
                f"{SSO_BASE_URL}/oauth/userinfo",
                headers={"Authorization": f"Bearer {token}"}
            )
            
            if response.status_code == 200:
                data = response.json()
                if data.get("code") == 0:
                    user_data = data["data"]
                    user_info = UserInfo(**user_data)
                    
                    # 缓存用户信息
                    user_sessions[user_info.id] = user_info
                    access_tokens[token] = user_info.id
                    
                    return user_info
            
            raise HTTPException(status_code=401, detail="无效的访问令牌")
            
        except httpx.RequestError:
            raise HTTPException(status_code=503, detail="SSO服务不可用")

@app.get("/")
async def root():
    """根路径"""
    return {"message": "子系统示例", "version": "1.0.0"}

@app.get("/auth/login")
async def login(request: Request):
    """发起SSO登录"""
    # 生成state参数防止CSRF攻击
    state = secrets.token_urlsafe(32)
    
    # 构建授权URL
    params = {
        "response_type": "code",
        "client_id": CLIENT_ID,
        "redirect_uri": REDIRECT_URI,
        "scope": "profile email",
        "state": state
    }
    
    auth_url = f"{SSO_BASE_URL}/oauth/authorize?{urlencode(params)}"
    
    return RedirectResponse(url=auth_url)

@app.get("/auth/callback")
async def auth_callback(
    code: Optional[str] = None,
    state: Optional[str] = None,
    error: Optional[str] = None
):
    """处理SSO回调"""
    print(f"🔄 收到SSO回调: code={code[:20] if code else None}..., state={state}, error={error}")
    
    if error:
        print(f"❌ 授权失败: {error}")
        return JSONResponse(
            status_code=400,
            content={"error": error, "message": "授权失败"}
        )
    
    if not code:
        print("❌ 缺少授权码")
        return JSONResponse(
            status_code=400,
            content={"error": "missing_code", "message": "缺少授权码"}
        )
    
    # 用授权码换取访问令牌
    async with httpx.AsyncClient() as client:
        try:
            print(f"🎫 开始令牌交换...")
            print(f"   SSO令牌端点: {SSO_BASE_URL}/oauth/token")
            print(f"   Client ID: {CLIENT_ID}")
            print(f"   回调URI: {REDIRECT_URI}")
            
            token_data = {
                "grant_type": "authorization_code",
                "code": code,
                "redirect_uri": REDIRECT_URI,
                "client_id": CLIENT_ID,
                "client_secret": CLIENT_SECRET
            }
            
            print(f"   令牌请求数据: {dict(token_data)}")
            
            response = await client.post(
                f"{SSO_BASE_URL}/oauth/token",
                data=token_data
            )
            
            print(f"   令牌响应状态: {response.status_code}")
            print(f"   令牌响应内容: {response.text}")
            
            if response.status_code == 200:
                data = response.json()
                print(f"   解析的响应数据: {data}")
                
                # 检查响应格式
                if "access_token" in data:
                    # 直接的令牌响应格式
                    token_info = data
                    print(f"✅ 直接令牌格式: {token_info.get('access_token', '')[:20]}...")
                elif data.get("code") == 0 and "data" in data:
                    # 包装的响应格式
                    token_info = data["data"]
                    print(f"✅ 包装令牌格式: {token_info.get('access_token', '')[:20]}...")
                else:
                    print(f"❌ 未知的令牌响应格式: {data}")
                    return JSONResponse(
                        status_code=400,
                        content={"error": "invalid_token_response", "message": "无效的令牌响应格式"}
                    )
                
                # 获取用户信息
                print(f"👤 获取用户信息...")
                user_response = await client.get(
                    f"{SSO_BASE_URL}/oauth/userinfo",
                    headers={"Authorization": f"Bearer {token_info['access_token']}"}
                )
                
                print(f"   用户信息响应状态: {user_response.status_code}")
                print(f"   用户信息响应内容: {user_response.text}")
                
                if user_response.status_code == 200:
                    user_data = user_response.json()
                    print(f"   解析的用户数据: {user_data}")
                    
                    # 检查用户信息响应格式
                    if "sub" in user_data:
                        # 直接的用户信息格式
                        user_info_data = user_data
                        print(f"✅ 直接用户信息格式")
                    elif user_data.get("code") == 0 and "data" in user_data:
                        # 包装的用户信息格式
                        user_info_data = user_data["data"]
                        print(f"✅ 包装用户信息格式")
                    else:
                        print(f"❌ 未知的用户信息响应格式: {user_data}")
                        return JSONResponse(
                            status_code=400,
                            content={"error": "invalid_user_response", "message": "无效的用户信息响应格式"}
                        )
                    
                    # 构建用户信息对象
                    user_info = UserInfo(
                        id=user_info_data["sub"],
                        username=user_info_data.get("username", ""),
                        email=user_info_data.get("email", ""),
                        phone=user_info_data.get("phone"),
                        avatar_url=user_info_data.get("avatar_url"),
                        is_active=True
                    )
                    
                    # 缓存用户信息和token
                    user_sessions[user_info.id] = user_info
                    access_tokens[token_info["access_token"]] = user_info.id
                    
                    print(f"✅ 用户登录成功: {user_info.username}")
                    
                    # 登录成功，重定向到首页
                    print(f"✅ 用户登录成功: {user_info.username}")
                    
                    # 构建首页URL，携带token和用户信息
                    home_url = f"/home?token={token_info['access_token']}&user_id={user_info.id}&username={user_info.username}&email={user_info.email}"
                    
                    print(f"🏠 重定向到首页: {home_url[:80]}...")
                    return RedirectResponse(url=home_url)
                else:
                    print(f"❌ 获取用户信息失败: {user_response.status_code}")
                    return JSONResponse(
                        status_code=400,
                        content={"error": "user_info_failed", "message": "获取用户信息失败"}
                    )
            else:
                print(f"❌ 令牌交换失败: {response.status_code}")
                return JSONResponse(
                    status_code=400,
                    content={"error": "token_exchange_failed", "message": "令牌交换失败"}
                )
            
        except httpx.RequestError as e:
            print(f"❌ 网络请求错误: {e}")
            return JSONResponse(
                status_code=503,
                content={"error": "sso_unavailable", "message": "SSO服务不可用"}
            )
        except Exception as e:
            print(f"❌ 处理回调时发生错误: {e}")
            return JSONResponse(
                status_code=500,
                content={"error": "callback_error", "message": f"回调处理错误: {str(e)}"}
            )

@app.get("/home")
async def home_page(
    token: str = None,
    user_id: str = None,
    username: str = None,
    email: str = None
):
    """子系统首页"""
    try:
        print(f"🏠 访问首页: user={username}")
        
        # 构建首页HTML
        home_html = f"""
        <!DOCTYPE html>
        <html lang="zh-CN">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>子系统首页</title>
            <style>
                * {{
                    margin: 0;
                    padding: 0;
                    box-sizing: border-box;
                }}
                
                body {{
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
                    background: #f5f5f5;
                    min-height: 100vh;
                }}
                
                .header {{
                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                    color: white;
                    padding: 20px 0;
                    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
                }}
                
                .header-content {{
                    max-width: 1200px;
                    margin: 0 auto;
                    padding: 0 20px;
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                }}
                
                .logo {{
                    font-size: 24px;
                    font-weight: bold;
                }}
                
                .user-info {{
                    display: flex;
                    align-items: center;
                    gap: 20px;
                }}
                
                .user-avatar {{
                    width: 40px;
                    height: 40px;
                    background: rgba(255, 255, 255, 0.2);
                    border-radius: 50%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    font-size: 18px;
                }}
                
                .user-details {{
                    display: flex;
                    flex-direction: column;
                }}
                
                .username {{
                    font-weight: 500;
                    font-size: 16px;
                }}
                
                .email {{
                    font-size: 14px;
                    opacity: 0.8;
                }}
                
                .logout-btn {{
                    background: rgba(255, 255, 255, 0.2);
                    border: 1px solid rgba(255, 255, 255, 0.3);
                    color: white;
                    padding: 8px 16px;
                    border-radius: 6px;
                    cursor: pointer;
                    font-size: 14px;
                    transition: all 0.3s;
                }}
                
                .logout-btn:hover {{
                    background: rgba(255, 255, 255, 0.3);
                }}
                
                .main-content {{
                    max-width: 1200px;
                    margin: 40px auto;
                    padding: 0 20px;
                }}
                
                .welcome-section {{
                    background: white;
                    border-radius: 15px;
                    padding: 40px;
                    margin-bottom: 30px;
                    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
                    text-align: center;
                }}
                
                .welcome-title {{
                    font-size: 32px;
                    color: #333;
                    margin-bottom: 10px;
                }}
                
                .welcome-subtitle {{
                    font-size: 18px;
                    color: #666;
                    margin-bottom: 30px;
                }}
                
                .features-grid {{
                    display: grid;
                    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
                    gap: 20px;
                    margin-bottom: 30px;
                }}
                
                .feature-card {{
                    background: white;
                    border-radius: 12px;
                    padding: 30px;
                    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
                    transition: transform 0.3s, box-shadow 0.3s;
                }}
                
                .feature-card:hover {{
                    transform: translateY(-5px);
                    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
                }}
                
                .feature-icon {{
                    font-size: 48px;
                    margin-bottom: 20px;
                }}
                
                .feature-title {{
                    font-size: 20px;
                    font-weight: 600;
                    color: #333;
                    margin-bottom: 10px;
                }}
                
                .feature-description {{
                    color: #666;
                    line-height: 1.6;
                    margin-bottom: 20px;
                }}
                
                .feature-btn {{
                    background: #007bff;
                    color: white;
                    padding: 10px 20px;
                    border: none;
                    border-radius: 6px;
                    cursor: pointer;
                    font-size: 14px;
                    font-weight: 500;
                    transition: background 0.3s;
                    text-decoration: none;
                    display: inline-block;
                }}
                
                .feature-btn:hover {{
                    background: #0056b3;
                }}
                
                .api-section {{
                    background: white;
                    border-radius: 12px;
                    padding: 30px;
                    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
                }}
                
                .api-title {{
                    font-size: 24px;
                    color: #333;
                    margin-bottom: 20px;
                }}
                
                .api-result {{
                    background: #f8f9fa;
                    border: 1px solid #e9ecef;
                    border-radius: 8px;
                    padding: 20px;
                    font-family: 'Courier New', monospace;
                    font-size: 14px;
                    max-height: 300px;
                    overflow-y: auto;
                    white-space: pre-wrap;
                    margin-bottom: 20px;
                }}
                
                .api-buttons {{
                    display: flex;
                    gap: 10px;
                    flex-wrap: wrap;
                }}
                
                .status-indicator {{
                    display: inline-block;
                    width: 8px;
                    height: 8px;
                    border-radius: 50%;
                    margin-right: 8px;
                }}
                
                .status-online {{
                    background: #28a745;
                }}
                
                .status-offline {{
                    background: #dc3545;
                }}
                
                @media (max-width: 768px) {{
                    .header-content {{
                        flex-direction: column;
                        gap: 20px;
                    }}
                    
                    .user-info {{
                        flex-direction: column;
                        text-align: center;
                    }}
                    
                    .features-grid {{
                        grid-template-columns: 1fr;
                    }}
                    
                    .api-buttons {{
                        flex-direction: column;
                    }}
                }}
            </style>
        </head>
        <body>
            <!-- 头部导航 -->
            <header class="header">
                <div class="header-content">
                    <div class="logo">
                        🏢 子系统示例
                    </div>
                    <div class="user-info">
                        <div class="user-avatar">
                            {username[0].upper() if username else '?'}
                        </div>
                        <div class="user-details">
                            <div class="username">{username or '未知用户'}</div>
                            <div class="email">{email or '未知邮箱'}</div>
                        </div>
                        <button class="logout-btn" onclick="logout()">
                            🚪 退出登录
                        </button>
                    </div>
                </div>
            </header>
            
            <!-- 主要内容 -->
            <main class="main-content">
                <!-- 欢迎区域 -->
                <section class="welcome-section">
                    <h1 class="welcome-title">欢迎回来，{username or '用户'}！</h1>
                    <p class="welcome-subtitle">您已通过SSO成功登录到子系统</p>
                    <div style="display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 20px;">
                        <span class="status-indicator status-online"></span>
                        <span>系统状态：正常运行</span>
                    </div>
                </section>
                
                <!-- 功能卡片 -->
                <div class="features-grid">
                    <div class="feature-card">
                        <div class="feature-icon">👤</div>
                        <h3 class="feature-title">个人资料</h3>
                        <p class="feature-description">查看和管理您的个人信息，包括基本资料和账户设置。</p>
                        <button class="feature-btn" onclick="testAPI('/api/user/profile', '个人资料')">
                            查看资料
                        </button>
                    </div>
                    
                    <div class="feature-card">
                        <div class="feature-icon">📦</div>
                        <h3 class="feature-title">产品管理</h3>
                        <p class="feature-description">浏览和管理系统中的所有产品信息。</p>
                        <button class="feature-btn" onclick="testAPI('/api/products', '产品列表')">
                            查看产品
                        </button>
                    </div>
                    
                    <div class="feature-card">
                        <div class="feature-icon">📋</div>
                        <h3 class="feature-title">订单管理</h3>
                        <p class="feature-description">查看您的订单历史和当前订单状态。</p>
                        <button class="feature-btn" onclick="testAPI('/api/orders', '订单列表')">
                            查看订单
                        </button>
                    </div>
                </div>
                
                <!-- API测试区域 -->
                <section class="api-section">
                    <h2 class="api-title">📡 API测试区域</h2>
                    <div class="api-result" id="apiResult">
点击上方按钮测试API功能...
                    </div>
                    <div class="api-buttons">
                        <button class="feature-btn" onclick="clearResult()">清空结果</button>
                        <button class="feature-btn" onclick="showToken()">显示Token</button>
                        <button class="feature-btn" onclick="testAllAPIs()">测试所有API</button>
                    </div>
                </section>
            </main>
            
            <script>
                // 存储用户信息和token
                const userInfo = {{
                    id: '{user_id or ''}',
                    username: '{username or ''}',
                    email: '{email or ''}',
                    token: '{token or ''}'
                }};
                
                // 将信息存储到localStorage
                if (userInfo.token) {{
                    localStorage.setItem('access_token', userInfo.token);
                    localStorage.setItem('user_info', JSON.stringify(userInfo));
                }}
                
                // API测试函数
                async function testAPI(endpoint, name) {{
                    const resultDiv = document.getElementById('apiResult');
                    resultDiv.textContent = `正在请求 ${{name}}...`;
                    
                    try {{
                        const response = await fetch(endpoint, {{
                            headers: {{
                                'Authorization': `Bearer ${{userInfo.token}}`
                            }}
                        }});
                        
                        const data = await response.json();
                        
                        resultDiv.textContent = `${{name}} API 响应:\\n\\n${{JSON.stringify(data, null, 2)}}`;
                    }} catch (error) {{
                        resultDiv.textContent = `${{name}} API 请求失败:\\n\\n${{error.message}}`;
                    }}
                }}
                
                // 测试所有API
                async function testAllAPIs() {{
                    const apis = [
                        {{endpoint: '/api/user/profile', name: '个人资料'}},
                        {{endpoint: '/api/products', name: '产品列表'}},
                        {{endpoint: '/api/orders', name: '订单列表'}}
                    ];
                    
                    const resultDiv = document.getElementById('apiResult');
                    resultDiv.textContent = '正在测试所有API...\\n\\n';
                    
                    for (const api of apis) {{
                        try {{
                            const response = await fetch(api.endpoint, {{
                                headers: {{
                                    'Authorization': `Bearer ${{userInfo.token}}`
                                }}
                            }});
                            
                            const data = await response.json();
                            resultDiv.textContent += `✅ ${{api.name}}: 成功\\n`;
                        }} catch (error) {{
                            resultDiv.textContent += `❌ ${{api.name}}: 失败 - ${{error.message}}\\n`;
                        }}
                    }}
                }}
                
                // 显示Token
                function showToken() {{
                    const resultDiv = document.getElementById('apiResult');
                    resultDiv.textContent = `访问令牌:\\n\\n${{userInfo.token}}\\n\\n令牌信息已复制到剪贴板（如果支持）`;
                    
                    // 尝试复制到剪贴板
                    if (navigator.clipboard) {{
                        navigator.clipboard.writeText(userInfo.token);
                    }}
                }}
                
                // 清空结果
                function clearResult() {{
                    document.getElementById('apiResult').textContent = '点击上方按钮测试API功能...';
                }}
                
                // 退出登录
                async function logout() {{
                    if (confirm('确定要退出登录吗？')) {{
                        try {{
                            // 调用退出API
                            await fetch('/auth/logout', {{
                                method: 'GET',
                                headers: {{
                                    'Authorization': `Bearer ${{userInfo.token}}`
                                }}
                            }});
                        }} catch (error) {{
                            console.log('退出API调用失败:', error);
                        }} finally {{
                            // 清除本地存储
                            localStorage.removeItem('access_token');
                            localStorage.removeItem('user_info');
                            
                            // 重定向到登录页面
                            window.location.href = '/auth/login';
                        }}
                    }}
                }}
                
                // 页面加载完成后的初始化
                document.addEventListener('DOMContentLoaded', function() {{
                    console.log('首页加载完成');
                    console.log('用户信息:', userInfo);
                    
                    // 如果没有token，重定向到登录页面
                    if (!userInfo.token) {{
                        alert('未检测到有效的登录信息，请重新登录');
                        window.location.href = '/auth/login';
                    }}
                }});
            </script>
        </body>
        </html>
        """
        
        from fastapi.responses import HTMLResponse
        return HTMLResponse(content=home_html)
        
    except Exception as e:
        print(f"❌ 首页错误: {e}")
        return {"error": "server_error", "message": "首页加载失败"}

@app.get("/auth/logout")
async def logout(credentials: HTTPAuthorizationCredentials = Depends(security)):
    """用户登出"""
    token = credentials.credentials
    
    # 清除本地缓存
    user_id = access_tokens.pop(token, None)
    if user_id:
        user_sessions.pop(user_id, None)
    
    # 可选：通知SSO服务撤销token
    async with httpx.AsyncClient() as client:
        try:
            await client.post(
                f"{SSO_BASE_URL}/oauth/revoke",
                data={"token": token, "token_type_hint": "access_token"}
            )
        except:
            pass  # 忽略错误
    
    return {"message": "登出成功"}

@app.get("/api/user/profile")
async def get_user_profile(current_user: UserInfo = Depends(get_current_user)):
    """获取用户资料"""
    return {
        "code": 0,
        "message": "获取用户资料成功",
        "data": current_user.dict()
    }

@app.get("/api/products")
async def get_products(current_user: UserInfo = Depends(get_current_user)):
    """获取产品列表（示例业务接口）"""
    # 模拟产品数据
    products = [
        {"id": 1, "name": "产品A", "price": 100.0, "description": "这是产品A"},
        {"id": 2, "name": "产品B", "price": 200.0, "description": "这是产品B"},
        {"id": 3, "name": "产品C", "price": 300.0, "description": "这是产品C"},
    ]
    
    return {
        "code": 0,
        "message": "获取产品列表成功",
        "data": {
            "products": products,
            "total": len(products),
            "user": current_user.username
        }
    }

@app.get("/api/orders")
async def get_orders(current_user: UserInfo = Depends(get_current_user)):
    """获取订单列表（示例业务接口）"""
    # 模拟订单数据
    orders = [
        {
            "id": 1,
            "product_name": "产品A",
            "quantity": 2,
            "total_price": 200.0,
            "status": "已完成",
            "created_at": "2024-01-15 10:30:00"
        },
        {
            "id": 2,
            "product_name": "产品B",
            "quantity": 1,
            "total_price": 200.0,
            "status": "处理中",
            "created_at": "2024-01-15 14:20:00"
        }
    ]
    
    return {
        "code": 0,
        "message": "获取订单列表成功",
        "data": {
            "orders": orders,
            "total": len(orders),
            "user": current_user.username
        }
    }

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8100)