"""
Verification API Endpoints
Handles email and phone verification for users
"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from pydantic import BaseModel, EmailStr
from typing import Optional

from ..database import get_db
from ..models import User
from ..services import verification_service
from .auth import get_current_user, get_current_user_optional

router = APIRouter(prefix="/verification", tags=["verification"])


# Request/Response schemas
class SendEmailCodeRequest(BaseModel):
    email: EmailStr
    language: str = "en"


class SendPhoneCodeRequest(BaseModel):
    phone: str
    language: str = "en"


class VerifyCodeRequest(BaseModel):
    code: str
    email: Optional[str] = None
    phone: Optional[str] = None


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


class VerificationStatusResponse(BaseModel):
    email_verified: bool
    phone_verified: bool
    email: Optional[str] = None
    phone: Optional[str] = None


# Email Verification Endpoints
@router.post("/email/send", response_model=VerificationResponse)
async def send_email_code(
    request: SendEmailCodeRequest,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user_optional)
):
    """Send email verification code"""
    user_id = current_user.id if current_user else None

    # If user is logged in, only allow sending to their email
    if current_user and current_user.email != request.email:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="You can only verify your own email address"
        )

    success, message = await verification_service.send_email_verification(
        db=db,
        email=request.email,
        user_id=user_id,
        language=request.language
    )

    if not success:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=message)

    return VerificationResponse(success=True, message=message)


@router.post("/email/verify", response_model=VerificationResponse)
async def verify_email_code(
    request: VerifyCodeRequest,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user_optional)
):
    """Verify email code"""
    email = request.email
    if current_user:
        email = current_user.email

    if not email:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Email is required"
        )

    success, message = verification_service.verify_code(
        db=db,
        code=request.code,
        code_type="email",
        email=email
    )

    if not success:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=message)

    # If user is logged in, mark their email as verified
    if current_user:
        verification_service.mark_email_verified(db, current_user)

    return VerificationResponse(success=True, message=message)


# Phone Verification Endpoints
@router.post("/phone/send", response_model=VerificationResponse)
async def send_phone_code(
    request: SendPhoneCodeRequest,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)  # Requires login
):
    """Send phone verification code (requires login)"""
    success, message = await verification_service.send_sms_verification(
        db=db,
        phone=request.phone,
        user_id=current_user.id,
        language=request.language
    )

    if not success:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=message)

    return VerificationResponse(success=True, message=message)


@router.post("/phone/verify", response_model=VerificationResponse)
async def verify_phone_code(
    request: VerifyCodeRequest,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)  # Requires login
):
    """Verify phone code (requires login)"""
    if not request.phone:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Phone number is required"
        )

    # Normalize phone number
    phone = request.phone.strip().replace(" ", "").replace("-", "")
    if not phone.startswith("+"):
        if phone.startswith("9") and len(phone) == 8:
            phone = "+976" + phone

    success, message = verification_service.verify_code(
        db=db,
        code=request.code,
        code_type="phone",
        phone=phone
    )

    if not success:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=message)

    # Mark phone as verified
    verification_service.mark_phone_verified(db, current_user, phone)

    return VerificationResponse(success=True, message=message)


# Status Endpoint
@router.get("/status", response_model=VerificationStatusResponse)
async def get_verification_status(
    current_user: User = Depends(get_current_user),
):
    """Get current user's verification status"""
    return VerificationStatusResponse(
        email_verified=current_user.email_verified or False,
        phone_verified=current_user.phone_verified or False,
        email=current_user.email,
        phone=current_user.phone
    )


# Pre-registration email verification (for signup flow)
@router.post("/email/send-preregister", response_model=VerificationResponse)
async def send_preregister_email_code(
    request: SendEmailCodeRequest,
    db: Session = Depends(get_db)
):
    """Send email verification code for new registration (no login required)"""
    # Check if email is already registered
    existing = db.query(User).filter(User.email == request.email).first()
    if existing:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="This email is already registered"
        )

    success, message = await verification_service.send_email_verification(
        db=db,
        email=request.email,
        user_id=None,
        language=request.language
    )

    if not success:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=message)

    return VerificationResponse(success=True, message=message)


@router.post("/email/verify-preregister", response_model=VerificationResponse)
async def verify_preregister_email_code(
    request: VerifyCodeRequest,
    db: Session = Depends(get_db)
):
    """Verify email code for new registration (no login required)"""
    if not request.email:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Email is required"
        )

    success, message = verification_service.verify_code(
        db=db,
        code=request.code,
        code_type="email",
        email=request.email
    )

    if not success:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=message)

    return VerificationResponse(success=True, message=message)
