from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.deps import get_current_user
from app.database import get_db
from app.models.user import User
from app.schemas.common import ApiResponse
from app.schemas.user import (
    BindEmailRequest,
    BindPhoneRequest,
    PasswordChange,
    SendCodeRequest,
    SendSmsRequest,
    UserResponse,
    UserUpdate,
)
from app.services import auth_service
from app.services.auth_service import hash_password, verify_password

router = APIRouter()


@router.get("/me", response_model=ApiResponse)
async def get_me(current_user: User = Depends(get_current_user)):
    return ApiResponse(data=UserResponse.model_validate(current_user))


@router.patch("/me", response_model=ApiResponse)
async def update_me(
    data: UserUpdate,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    update_data = data.model_dump(exclude_unset=True)
    for key, value in update_data.items():
        setattr(current_user, key, value)
    await db.flush()
    await db.refresh(current_user)
    return ApiResponse(data=UserResponse.model_validate(current_user))


@router.put("/me/password", response_model=ApiResponse)
async def change_password(
    data: PasswordChange,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    if current_user.hashed_password:
        if not data.old_password:
            raise HTTPException(status_code=400, detail="请输入当前密码")
        if not verify_password(data.old_password, current_user.hashed_password):
            raise HTTPException(status_code=400, detail="当前密码不正确")

    current_user.hashed_password = hash_password(data.new_password)
    await db.flush()
    await db.refresh(current_user)
    return ApiResponse(data=UserResponse.model_validate(current_user))


@router.post("/me/send-bind-email-code", response_model=ApiResponse)
async def send_bind_email_code(
    data: SendCodeRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    cooldown = await auth_service.send_bind_email_code(db, current_user, data)
    return ApiResponse(data={"cooldown": cooldown})


@router.post("/me/send-bind-phone-code", response_model=ApiResponse)
async def send_bind_phone_code(
    data: SendSmsRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    cooldown = await auth_service.send_bind_sms_code(db, current_user, data)
    return ApiResponse(data={"cooldown": cooldown})


@router.post("/me/bind-email", response_model=ApiResponse)
async def bind_email(
    data: BindEmailRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    user = await auth_service.bind_email(db, current_user, data.email, data.code)
    return ApiResponse(data=UserResponse.model_validate(user))


@router.post("/me/bind-phone", response_model=ApiResponse)
async def bind_phone(
    data: BindPhoneRequest,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    user = await auth_service.bind_phone(db, current_user, data.phone, data.code)
    return ApiResponse(data=UserResponse.model_validate(user))
