from typing import Optional

from fastapi import APIRouter, Depends, Query, Request
from fastapi.responses import JSONResponse

from model.access_token_model import AccessTokenModel
from model.user_model import (
    UserForgotPasswordPayload,
    UserGoogleLoginPayload,
    UserLoginPayload,
    UserModel,
    UserUpdatePasswordPayload,
    UserUpdateProfilePayload,
)
from utils.auth_helper import require_user, requires_permission
from utils.settings import ACCESS_TOKEN_TTL_HOURS
from utils.turnstile_helper import verify_turnstile

router = APIRouter(prefix="/user", tags=["User API"])


def _client_ip(request: Request) -> str:
    return request.client.host if request.client else ""


def _user_response_data(user: dict) -> dict:
    snapshot = UserModel.sync_user_tier(str(user.get("_id")))
    return {
        "id": str(user.get("_id")),
        "email": user.get("email"),
        "firstName": user.get("firstName", ""),
        "lastName": user.get("lastName", ""),
        "phone": user.get("phone", ""),
        "address": user.get("address", ""),
        "avatarUrl": user.get("avatarUrl", ""),
        "balance": user.get("balance", 0),
        "debtBalance": user.get("debtBalance", 0),
        "role": "user",
        "hasPassword": bool(user.get("password")),
        "createdAt": user.get("createdAt", ""),
        "tierCurrent": snapshot["tierCurrent"],
    }


def _issue_user_login_response(user: dict, request: Request, message: str = "Đăng nhập thành công"):
    issued = AccessTokenModel.issue_token(
        actor_id=str(user["_id"]),
        actor_role="user",
        ttl_hours=ACCESS_TOKEN_TTL_HOURS,
        created_by_ip=_client_ip(request),
        user_agent=request.headers.get("user-agent", ""),
    )

    return {
        "success": True,
        "data": {
            "accessToken": issued["rawToken"],
            "tokenType": "Bearer",
            "expiresIn": ACCESS_TOKEN_TTL_HOURS * 3600,
            "user": _user_response_data(user),
        },
        "message": message,
    }


@router.post("/auth/google", dependencies=[Depends(verify_turnstile)])
async def user_google_login(payload: UserGoogleLoginPayload, request: Request):
    try:
        user = UserModel.handle_google_login(payload)
        return _issue_user_login_response(user, request, "Đăng nhập Google thành công")
    except Exception as e:
        return {"success": False, "message": str(e)}


@router.post("/auth/login", dependencies=[Depends(verify_turnstile)])
async def user_login(payload: UserLoginPayload, request: Request):
    user = UserModel.verify_login(payload.email, payload.password)

    if user:
        return _issue_user_login_response(user, request)

    return {"success": False, "message": "Email hoặc mật khẩu không chính xác!"}


@router.post("/forgot-password", dependencies=[Depends(verify_turnstile)])
async def forgot_password(payload: UserForgotPasswordPayload):
    success, message = UserModel.reset_password(payload.email)
    return {"success": success, "message": message}


@router.get("/me")
def get_user_me(current_user=Depends(require_user())):
    user = UserModel.get_user_by_id(current_user["id"])
    if not user:
        return JSONResponse(
            status_code=404,
            content={"success": False, "message": "Không tìm thấy User"},
        )

    return {
        "success": True,
        "data": _user_response_data(user),
    }


@router.put("/me")
async def update_user_me(
    payload: UserUpdateProfilePayload,
    current_user=Depends(require_user()),
):
    user = UserModel.update_profile_by_id(
        user_id=current_user["id"],
        first_name=payload.firstName,
        last_name=payload.lastName,
        phone=payload.phone,
        address=payload.address,
        avatar_url=payload.avatarUrl,
    )

    if not user:
        return JSONResponse(
            status_code=404,
            content={"success": False, "message": "Không tìm thấy User"},
        )

    return {
        "success": True,
        "data": _user_response_data(user),
        "message": "Cập nhật thành công",
    }


@router.get("/search", dependencies=[Depends(requires_permission("staff_management"))])
def search_users(
    keyword: str = Query("", description="Từ khóa tìm kiếm user"),
    page: int = Query(1, ge=1),
    pageSize: int = Query(10, ge=1, le=100),
    dateFrom: Optional[str] = Query(None, description="YYYY-MM-DD"),
    dateTo: Optional[str] = Query(None, description="YYYY-MM-DD"),
    sortBy: str = Query("balance", pattern="^(balance|spent|debt)$"),
    sortOrder: str = Query("desc", pattern="^(asc|desc)$"),
):
    result = UserModel.search_users(
        keyword=keyword,
        page=page,
        page_size=pageSize,
        date_from=dateFrom,
        date_to=dateTo,
        sort_by=sortBy,
        sort_order=sortOrder,
    )

    return {
        "success": True,
        "data": result["items"],
        "total": result["total"],
        "page": result["page"],
        "pageSize": result["pageSize"],
        "totalPages": result["totalPages"],
    }


@router.put("/update-password", dependencies=[Depends(verify_turnstile)])
async def update_password(
    payload: UserUpdatePasswordPayload,
    current_user=Depends(require_user()),
):
    success, message = UserModel.update_password_by_id(
        current_user["id"],
        payload.oldPassword or "",
        payload.newPassword,
    )
    return {"success": success, "message": message}
