"""用户端代理路由"""
from fastapi import APIRouter, Depends, HTTPException, Query, Request
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession

from app.database import get_db
from app.core.deps import get_current_user
from app.models import User, AffiliateClick, AgentStatus
from app.schemas.agent import (
    AgentOverviewResponse,
    AgentSettlementResponse,
    AgentCustomerResponse,
    AgentApplyRequest,
    AgentTierResponse,
    AffiliateInfoResponse,
    AffiliateClickRequest,
)
from app.schemas.common import ApiResponse
from app.services import agent_service, system_setting_service
from app.services import membership_service

router = APIRouter()


@router.get("/me", response_model=ApiResponse)
async def get_agent_overview(
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    await agent_service.settle_due_rewards_for_user(db, current_user.id)
    agent = await agent_service.get_user_agent(db, current_user.id)
    agent_active = agent and agent.status.value in ("active", "observing")
    customer_count = await agent_service.get_customer_count(db, current_user.id) if agent_active else 0
    pending_profit = await agent_service.get_agent_pending_profit(db, current_user.id) if agent else 0

    membership = await membership_service.get_or_create_membership(db, current_user.id)
    code = await agent_service.generate_invite_code(db, current_user)
    business_settings = await system_setting_service.get_business_settings(db)
    invite_code_change_count = int(current_user.invite_code_change_count or 0)

    from app.schemas.agent import UserAgentResponse
    agent_data = UserAgentResponse.model_validate(agent) if agent else None

    result = AgentOverviewResponse(
        agent=agent_data,
        customer_count=customer_count,
        pending_profit=pending_profit,
        total_sales=agent.total_sales if agent else 0,
        total_profit=agent.total_profit if agent else 0,
        invite_code=code,
        invite_code_edit_enabled=business_settings.invite_code_edit_enabled,
        invite_code_change_count=invite_code_change_count,
        invite_code_change_limit=agent_service.invite_code_change_limit(current_user),
        invite_code_change_remaining=agent_service.invite_code_change_remaining(current_user),
        member_commission_rate=0,
    ).model_dump()
    result["available_points"] = membership.available_points
    result["total_points"] = membership.total_points
    return ApiResponse(data=result)


@router.get("/tiers", response_model=ApiResponse)
async def list_public_agent_tiers(db: AsyncSession = Depends(get_db)):
    from app.models import AgentTier

    res = await db.execute(
        select(AgentTier).where(AgentTier.enabled == True).order_by(AgentTier.sort_order, AgentTier.id)
    )
    return ApiResponse(data=[AgentTierResponse.model_validate(t) for t in res.scalars().all()])


@router.post("/apply", response_model=ApiResponse)
async def apply_agent(
    body: AgentApplyRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """直接提交代理申请"""
    from app.models import AgentTier

    # 验证档位
    tier_res = await db.execute(
        select(AgentTier).where(AgentTier.code == body.tier, AgentTier.enabled == True)
    )
    tier = tier_res.scalar_one_or_none()
    if not tier:
        raise HTTPException(400, f"代理档位 {body.tier} 不存在或已停用")

    # 检查会员等级
    membership = await membership_service.get_or_create_membership(db, current_user.id)
    if membership.member_level and membership.member_level.level < tier.min_member_level:
        raise HTTPException(403, f"当前会员等级不足以申请{tier.name}，需要 LV{tier.min_member_level} 及以上")

    # 创建或更新申请
    agent = await agent_service.get_or_create_user_agent(db, current_user.id)
    agent.status = AgentStatus.PENDING
    agent.apply_tier = body.tier
    agent.apply_reason = body.reason
    agent.apply_channels = body.channels
    await db.flush()
    await db.refresh(agent)

    from app.schemas.agent import UserAgentResponse
    return ApiResponse(data=UserAgentResponse.model_validate(agent).model_dump(), message="申请已提交")


@router.get("/customers", response_model=ApiResponse)
async def list_customers(
    offset: int = Query(0, ge=0),
    limit: int = Query(20, ge=1, le=100),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    agent = await agent_service.get_user_agent(db, current_user.id)
    if not agent or agent.status.value not in ("active", "observing"):
        raise HTTPException(403, "您还不是代理或代理身份未激活")

    rows = await agent_service.get_agent_customers(db, current_user.id, offset, limit)
    total = await agent_service.get_customer_count(db, current_user.id)

    from app.schemas.agent import UserBrief
    items = []
    for ac, user in rows:
        resp = AgentCustomerResponse(
            id=ac.id,
            agent_user_id=ac.agent_user_id,
            customer_user_id=ac.customer_user_id,
            bind_source=ac.bind_source,
            bound_at=ac.bound_at,
            first_order_id=ac.first_order_id,
            status=ac.status,
            customer=UserBrief.model_validate(user),
        )
        items.append(resp)

    return ApiResponse(data={"items": [i.model_dump() for i in items], "total": total})


@router.get("/settlements", response_model=ApiResponse)
async def list_settlements(
    offset: int = Query(0, ge=0),
    limit: int = Query(20, ge=1, le=100),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    await agent_service.settle_due_rewards_for_user(db, current_user.id)
    settlements = await agent_service.get_agent_settlements(db, current_user.id, offset, limit)
    return ApiResponse(data={
        "items": [AgentSettlementResponse.model_validate(s).model_dump() for s in settlements],
        "total": len(settlements),
    })


@router.get("/invite-code", response_model=ApiResponse)
async def get_invite_code(
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """兼容旧前端：推广码统一来自 users.invite_code。"""
    code = await agent_service.generate_invite_code(db, current_user)
    business_settings = await system_setting_service.get_business_settings(db)
    base_url = business_settings.promotion_base_url.rstrip("/")
    link = f"{base_url}/register?ref={code}"
    return ApiResponse(data={
        "invite_code": code,
        "invite_link": link,
        "register_link": link,
    })


# ── AFF / 推广链接 ──
@router.get("/aff-info", response_model=ApiResponse)
async def get_aff_info(
    code: str = Query(..., description="AFF代码或邀请码"),
    db: AsyncSession = Depends(get_db),
):
    """根据邀请码查询推广者信息"""
    agent_user = await agent_service.resolve_agent_from_code(db, code)
    if not agent_user:
        from app.models import UserAgent as UAModel
        res = await db.execute(select(UAModel).where(UAModel.invite_code == code))
        ua = res.scalar_one_or_none()
        if not ua:
            return ApiResponse(data=None, message="无效的推广码")
        res = await db.execute(select(User).where(User.id == ua.user_id))
        agent_user = res.scalar_one_or_none()

    tier_name = None
    from app.models import UserAgent as UAModel
    res = await db.execute(select(UAModel).where(UAModel.user_id == agent_user.id))
    ua = res.scalar_one_or_none()
    if ua and ua.agent_tier:
        tier_name = ua.agent_tier.name

    return ApiResponse(data=AffiliateInfoResponse(
        aff_code=code,
        agent_name=agent_user.nickname or agent_user.username,
        agent_tier=tier_name,
    ).model_dump())


@router.post("/aff-click", response_model=ApiResponse)
async def record_aff_click(
    body: AffiliateClickRequest,
    request: Request,
    db: AsyncSession = Depends(get_db),
):
    """记录AFF推广点击"""
    agent_id = None
    agent_user = await agent_service.resolve_agent_from_code(db, body.aff_code)
    if agent_user:
        agent_id = agent_user.id

    click = AffiliateClick(
        aff_code=body.aff_code,
        agent_id=agent_id,
        landing_url=body.landing_url or str(request.url),
        ip=request.client.host if request.client else None,
        user_agent=request.headers.get("user-agent"),
        referer=request.headers.get("referer"),
        utm_source=body.utm_source,
        utm_medium=body.utm_medium,
        utm_campaign=body.utm_campaign,
        utm_content=body.utm_content,
        utm_term=body.utm_term,
    )
    db.add(click)
    await db.flush()
    return ApiResponse(data={"ok": True})
