"""
账号管理 API（多账号）

说明：
- 这是“多账号第一步”的管理入口：创建/禁用/更新密钥
- 交易/配置/统计接口通过 X-Account-Id 头来选择账号（默认 1）
"""

from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel, Field
from typing import Optional, List, Dict, Any
import logging

from database.models import Account, UserAccountMembership
from api.auth_deps import get_current_user, get_admin_user, require_account_access, require_account_owner

from api.supervisor_account import (
    ensure_account_program,
    run_supervisorctl,
    parse_supervisor_status,
    program_name_for_account,
    tail_supervisor,
    tail_supervisord_log,
    tail_trading_log_files,
)

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


class AccountCreate(BaseModel):
    name: str = Field(..., min_length=1, max_length=100)
    api_key: Optional[str] = ""
    api_secret: Optional[str] = ""
    use_testnet: bool = False
    status: str = Field("active", pattern="^(active|disabled)$")


class AccountUpdate(BaseModel):
    name: Optional[str] = Field(None, min_length=1, max_length=100)
    status: Optional[str] = Field(None, pattern="^(active|disabled)$")
    use_testnet: Optional[bool] = None


class AccountCredentialsUpdate(BaseModel):
    api_key: Optional[str] = None
    api_secret: Optional[str] = None
    use_testnet: Optional[bool] = None


@router.get("")
async def list_my_accounts(user: Dict[str, Any] = Depends(get_current_user)):
    """列出我有权访问的账号"""
    try:
        if user.get("role") == "admin":
            accounts = Account.list_all()
        else:
            accounts = UserAccountMembership.get_user_accounts(user["id"])
        
        # 补充一些运行时信息（可选），并处理敏感字段
        for acc in accounts:
            acc['has_api_key'] = bool(acc.get('api_key_enc'))
            acc['has_api_secret'] = bool(acc.get('api_secret_enc'))
            # 移除加密字段，不直接暴露给前端
            acc.pop('api_key_enc', None)
            acc.pop('api_secret_enc', None)
            
        return accounts
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("")
async def create_account(
    data: AccountCreate, 
    user: Dict[str, Any] = Depends(get_current_user)
):
    """创建新账号（仅管理员或允许的用户）"""
    # 暂时只允许 admin 创建
    if user.get("role") != "admin":
        raise HTTPException(status_code=403, detail="Only admin can create accounts")
        
    try:
        aid = Account.create(
            name=data.name,
            api_key=data.api_key,
            api_secret=data.api_secret,
            use_testnet=data.use_testnet,
            status=data.status
        )
        # 自动将创建者关联为 owner
        UserAccountMembership.add_membership(user["id"], aid, "owner")
        
        return {"id": aid, "message": "Account created successfully"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/{account_id}")
async def get_account_detail(
    account_id: int, 
    user: Dict[str, Any] = Depends(get_current_user)
):
    """获取账号详情"""
    require_account_access(account_id, user)
    try:
        acc = Account.get_by_id(account_id)
        if not acc:
            raise HTTPException(status_code=404, detail="Account not found")
        return acc
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/{account_id}")
async def update_account(
    account_id: int, 
    data: AccountUpdate, 
    user: Dict[str, Any] = Depends(get_current_user)
):
    """更新账号基本信息"""
    require_account_owner(account_id, user)
    try:
        updates = {}
        if data.name is not None:
            updates['name'] = data.name
        if data.status is not None:
            updates['status'] = data.status
        if data.use_testnet is not None:
            updates['testnet'] = 1 if data.use_testnet else 0
            
        if updates:
            Account.update(account_id, **updates)
            
        return {"message": "Account updated"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/{account_id}/credentials")
async def update_credentials(
    account_id: int,
    data: AccountCredentialsUpdate,
    user: Dict[str, Any] = Depends(get_current_user)
):
    """更新API密钥"""
    require_account_owner(account_id, user)
    try:
        updates = {}
        if data.api_key is not None:
            updates['api_key'] = data.api_key
        if data.api_secret is not None:
            updates['api_secret'] = data.api_secret
        if data.use_testnet is not None:
            updates['testnet'] = 1 if data.use_testnet else 0
            
        if updates:
            Account.update(account_id, **updates)
            
        return {"message": "Credentials updated"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


# --- Service Management ---

@router.get("/{account_id}/trading/status")
@router.get("/{account_id}/service/status", include_in_schema=False)  # 兼容旧路由
async def get_service_status(
    account_id: int, 
    user: Dict[str, Any] = Depends(get_current_user)
):
    """获取该账号关联的交易服务状态"""
    # 手动调用权限检查，因为 Depends(require_account_access) 无法直接获取路径参数 account_id
    require_account_access(account_id, user)
    
    try:
        program = program_name_for_account(account_id)
        # status <program>
        try:
            out = run_supervisorctl(["status", program])
            running, pid, state = parse_supervisor_status(out)
            return {
                "program": program,
                "running": running,
                "pid": pid,
                "state": state,
                "raw": out
            }
        except RuntimeError as e:
            # 可能进程不存在
            return {
                "program": program,
                "running": False,
                "pid": None,
                "state": "UNKNOWN",
                "raw": str(e),
                "error": "Process likely not configured or supervisor error"
            }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/{account_id}/trading/start")
@router.post("/{account_id}/service/start", include_in_schema=False)
async def start_service(
    account_id: int, 
    user: Dict[str, Any] = Depends(get_current_user)
):
    """启动交易服务（需该账号 owner 或管理员）"""
    require_account_owner(account_id, user)
    try:
        program = program_name_for_account(account_id)
        out = run_supervisorctl(["start", program])
        # Check status again
        status_out = run_supervisorctl(["status", program])
        running, pid, state = parse_supervisor_status(status_out)
        return {
            "message": "Service start command sent",
            "output": out,
            "status": {
                "running": running,
                "pid": pid,
                "state": state
            }
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/{account_id}/trading/stop")
@router.post("/{account_id}/service/stop", include_in_schema=False)
async def stop_service(
    account_id: int, 
    user: Dict[str, Any] = Depends(get_current_user)
):
    """停止交易服务（需该账号 owner 或管理员）"""
    require_account_owner(account_id, user)
    try:
        program = program_name_for_account(account_id)
        out = run_supervisorctl(["stop", program])
        # Check status again
        status_out = run_supervisorctl(["status", program])
        running, pid, state = parse_supervisor_status(status_out)
        return {
            "message": "Service stop command sent",
            "output": out,
            "status": {
                "running": running,
                "pid": pid,
                "state": state
            }
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/{account_id}/trading/restart")
@router.post("/{account_id}/service/restart", include_in_schema=False)
async def restart_service(
    account_id: int, 
    user: Dict[str, Any] = Depends(get_current_user)
):
    """重启交易服务（需该账号 owner 或管理员）"""
    require_account_owner(account_id, user)
    try:
        program = program_name_for_account(account_id)
        out = run_supervisorctl(["restart", program])
        # Check status again
        status_out = run_supervisorctl(["status", program])
        running, pid, state = parse_supervisor_status(status_out)
        return {
            "message": "Service restart command sent",
            "output": out,
            "status": {
                "running": running,
                "pid": pid,
                "state": state
            }
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/{account_id}/trading/ensure-program")
async def ensure_trading_program(account_id: int, user: Dict[str, Any] = Depends(get_current_user)):
    if int(account_id) <= 0:
        raise HTTPException(status_code=400, detail="account_id 必须 >= 1")
    require_account_owner(int(account_id), user)
    sup = ensure_account_program(int(account_id))
    if not sup.ok:
        raise HTTPException(status_code=500, detail=sup.error or "生成 supervisor 配置失败")
    return {
        "ok": True,
        "program": sup.program,
        "ini_path": sup.ini_path,
        "program_dir": sup.program_dir,
        "supervisor_conf": sup.supervisor_conf,
        "reread": sup.reread,
        "update": sup.update,
    }
