from fastapi import APIRouter, HTTPException, Request, Depends
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from typing import Optional
import logging

from jingrow.utils.auth import login, logout, get_user_info, set_context, get_jingrow_cloud_url, get_jingrow_cloud_api_headers
from jingrow.config import Config
from jingrow.utils.jingrow_api import get_user_pagetype_permissions_from_jingrow

logger = logging.getLogger(__name__)
router = APIRouter()

class LoginRequest(BaseModel):
    username: str
    password: str

class SignupRequest(BaseModel):
    username: str
    password: str
    email: Optional[str] = None
    phone_number: Optional[str] = None

class SignupResponse(BaseModel):
    success: bool
    message: str
    user: Optional[dict] = None
    session_cookie: Optional[str] = None

class LoginResponse(BaseModel):
    success: bool
    message: str
    user: Optional[dict] = None
    session_cookie: Optional[str] = None

class LogoutResponse(BaseModel):
    success: bool
    message: str

class UserInfoResponse(BaseModel):
    success: bool
    user_info: Optional[dict] = None
    message: Optional[str] = None


class UserPermissionsResponse(BaseModel):
    success: bool
    user: Optional[str] = None
    roles: Optional[list[str]] = None
    permissions: Optional[dict] = None
    error: Optional[str] = None

COOKIE_CONFIG = {
    "httponly": True,
    "samesite": "lax",
    "secure": False,
    "path": "/",
    "max_age": 7 * 24 * 60 * 60
}

COOKIES_TO_CLEAR = ["sid", "user_id", "user_image", "full_name", "system_user"]

def get_session_cookie(request: Request) -> Optional[str]:
    """从请求中获取session cookie并设置context（FastAPI依赖注入）"""
    session_cookie = request.cookies.get('sid')
    if session_cookie:
        set_context({"session_cookie": session_cookie})
    return session_cookie

def handle_auth_result(result: dict, error_status_code: int = 400):
    """统一处理认证结果，成功返回数据，失败抛出异常"""
    if not result.get("success"):
        raise HTTPException(
            status_code=error_status_code,
            detail=result.get("message", "操作失败")
        )
    return result

def create_response_with_cookie(data: dict, session_cookie: Optional[str] = None) -> JSONResponse:
    """创建响应并设置cookie"""
    response = JSONResponse(content=data)
    if session_cookie:
        response.set_cookie(key="sid", value=session_cookie, **COOKIE_CONFIG)
    return response

def create_response_clear_cookies(data: dict) -> JSONResponse:
    """创建响应并清除所有相关cookie"""
    response = JSONResponse(content=data)
    for cookie_name in COOKIES_TO_CLEAR:
        cookie_kwargs = {
            "path": COOKIE_CONFIG.get("path", "/"),
            "samesite": COOKIE_CONFIG.get("samesite", "lax"),
            "httponly": COOKIE_CONFIG.get("httponly", True)
        }
        if COOKIE_CONFIG.get("secure"):
            cookie_kwargs["secure"] = True
        response.delete_cookie(key=cookie_name, **cookie_kwargs)
    return response

@router.post("/jingrow/login", response_model=LoginResponse)
async def login_route(login_data: LoginRequest):
    """登录路由"""
    try:
        result = login(login_data.username, login_data.password)
        handle_auth_result(result, error_status_code=401)
        
        session_cookie = result.get("session_cookie")
        user_info_result = get_user_info(session_cookie)
        user_info = user_info_result.get("user_info") if user_info_result.get("success") else None
        
        return create_response_with_cookie({
            "success": True,
            "message": result.get("message", "Logged In"),
            "user": user_info
        }, session_cookie)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"登录异常: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"登录异常: {str(e)}")

@router.post("/jingrow/logout", response_model=LogoutResponse)
async def logout_route(session_cookie: Optional[str] = Depends(get_session_cookie)):
    """登出路由"""
    try:
        result = logout(session_cookie)
        handle_auth_result(result, error_status_code=400)
        return create_response_clear_cookies({
            "success": True,
            "message": result.get("message", "登出成功")
        })
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"登出异常: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"登出异常: {str(e)}")

@router.post("/jingrow/signup", response_model=SignupResponse)
async def signup_route(signup_data: SignupRequest):
    """注册路由"""
    import requests
    
    try:
        url = f"{get_jingrow_cloud_url()}/api/action/jcloud.api.account.signup_with_username"
        data = {"username": signup_data.username, "password": signup_data.password}
        if signup_data.email:
            data["email"] = signup_data.email
        if signup_data.phone_number:
            data["phone_number"] = signup_data.phone_number
        
        response = requests.post(url, headers=get_jingrow_cloud_api_headers(), json=data, timeout=30)
        
        if response.status_code != 200:
            raise HTTPException(status_code=400, detail=f"注册请求失败 (HTTP {response.status_code})")
        
        try:
            result = response.json()
        except Exception as e:
            raise HTTPException(status_code=400, detail="注册失败：无法解析服务器响应")
        
        message_obj = result.get("message")
        if not isinstance(message_obj, dict):
            raise HTTPException(status_code=400, detail="注册失败：服务器响应格式错误")
        
        success_value = message_obj.get("success")
        success_message = message_obj.get("message", "注册成功")
        
        if success_value is False:
            raise HTTPException(status_code=400, detail=success_message)
        
        session_cookie = None
        user_info = None
        
        try:
            login_result = login(signup_data.username, signup_data.password)
            if login_result.get("success"):
                session_cookie = login_result.get("session_cookie")
                if session_cookie:
                    user_info_result = get_user_info(session_cookie)
                    if user_info_result.get("success"):
                        user_info = user_info_result.get("user_info")
            else:
                pass
        except Exception as e:
            pass
        
        response_data = {
            "success": True,
            "message": success_message,
            "user": user_info
        }
        
        if session_cookie:
            return create_response_with_cookie(response_data, session_cookie)
        else:
            return JSONResponse(content=response_data)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"注册异常: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"注册异常: {str(e)}")

@router.get("/jingrow/server-config")
async def get_server_config():
    return {
        "success": True,
        "jingrow_server_url": Config.jingrow_server_url
    }

@router.get("/jingrow/user-info", response_model=UserInfoResponse)
async def get_user_info_route(session_cookie: Optional[str] = Depends(get_session_cookie)):
    """获取用户信息路由"""
    try:
        result = get_user_info(session_cookie)
        handle_auth_result(result, error_status_code=401)
        return {
            "success": True,
            "user_info": result.get("user_info")
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取用户信息异常: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"获取用户信息异常: {str(e)}")


@router.get("/jingrow/user-permissions", response_model=UserPermissionsResponse)
async def get_user_permissions_route(session_cookie: Optional[str] = Depends(get_session_cookie)):
    """获取当前登录用户的 PageType 权限"""
    if not session_cookie:
        raise HTTPException(status_code=401, detail="未提供认证信息")

    try:
        result = get_user_pagetype_permissions_from_jingrow(session_cookie)
        if not result or not result.get("success"):
            error_msg = result.get("error") if isinstance(result, dict) else "获取权限失败"
            raise HTTPException(status_code=400, detail=error_msg)
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取用户权限异常: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"获取用户权限异常: {str(e)}")


# ============ 兼容 SaaS 版前端 API ============

@router.post("/api/action/login")
async def saas_login(request: Request):
    """兼容 SaaS 版前端登录"""
    from urllib.parse import unquote
    
    content_type = request.headers.get('content-type', '')
    
    if 'application/x-www-form-urlencoded' in content_type:
        body = await request.body()
        params = dict(pair.split('=', 1) for pair in body.decode().split('&') if '=' in pair)
        # URL 解码参数
        username = unquote(params.get('usr', params.get('username', '')))
        password = unquote(params.get('pwd', params.get('password', '')))
    else:
        data = await request.json()
        username = data.get('usr', data.get('username', ''))
        password = data.get('pwd', data.get('password', ''))
    
    if not username or not password:
        raise HTTPException(status_code=400, detail="用户名和密码不能为空")
    
    result = login(username, password)
    if not result.get("success"):
        raise HTTPException(status_code=401, detail=result.get("message", "登录失败"))
    
    session_cookie = result.get("session_cookie")
    
    response = JSONResponse(content={"message": result.get("message", "Logged In")})
    if session_cookie:
        response.set_cookie(key="sid", value=session_cookie, **COOKIE_CONFIG)
    response.set_cookie(key="user_id", value=username, path="/", samesite="lax")
    response.set_cookie(key="full_name", value=username, path="/", samesite="lax")
    response.set_cookie(key="system_user", value="yes", path="/", samesite="lax")
    
    return response


@router.api_route("/api/action/logout", methods=["GET", "POST"])
async def saas_logout(request: Request):
    """兼容 SaaS 版前端登出"""
    session_cookie = request.cookies.get('sid')
    logout(session_cookie)
    return create_response_clear_cookies({"message": "Logged Out"})
