"""
Forgot password function - standalone, no database required.
"""

import secrets
from datetime import datetime, timedelta, timezone
from typing import Dict, Any

from apexsaas.email import send_reset_email
from apexsaas.exceptions import ApexValidationError, ApexEmailError


async def forgot_password(
    email: str,
    sendgrid_api_key: str,
    from_email: str,
    reset_url: str,
    token_expiry_hours: int = 1
) -> Dict[str, Any]:
    """
    Request password reset (async).
    
    Args:
        email: User email address
        sendgrid_api_key: SendGrid API key
        from_email: Sender email address
        reset_url: Base URL for password reset (token will be appended)
        token_expiry_hours: Token expiration in hours (default: 1)
    
    Returns:
        dict with reset token info:
        {
            'reset_token': str,
            'expires_at': str,
            'email_sent': bool
        }
    
    Raises:
        ApexValidationError: If input validation fails
        ApexEmailError: If email sending fails
    """
    if not email or not isinstance(email, str):
        raise ApexValidationError("Email is required")
    if not sendgrid_api_key:
        raise ApexValidationError("sendgrid_api_key is required")
    if not from_email:
        raise ApexValidationError("from_email is required")
    if not reset_url:
        raise ApexValidationError("reset_url is required")
    
    # Generate reset token
    reset_token = secrets.token_urlsafe(32)
    expires_at = datetime.now(timezone.utc) + timedelta(hours=token_expiry_hours)
    
    # Send reset email
    email_sent = False
    email_message = None
    try:
        full_reset_url = f"{reset_url}?token={reset_token}"
        email_result = await send_reset_email(
            to_email=email,
            to_name=email.split('@')[0],  # Use email prefix as name
            reset_url=full_reset_url,
            sendgrid_api_key=sendgrid_api_key,
            from_email=from_email
        )
        email_sent = email_result.get('success', False)
        email_message = email_result.get('message', 'Email sending status unknown')
    except Exception as e:
        # If send_reset_email returns error dict, extract message
        if isinstance(e, dict):
            email_message = e.get('message', str(e))
        else:
            email_message = f"Failed to send reset email: {str(e)}"
    
    return {
        'reset_token': reset_token,
        'expires_at': expires_at.isoformat(),
        'email_sent': email_sent,
        'message': email_message if email_message else ('Password reset email sent successfully' if email_sent else 'Failed to send password reset email')
    }


def forgot_password_sync(
    email: str,
    sendgrid_api_key: str,
    from_email: str,
    reset_url: str,
    token_expiry_hours: int = 1
) -> Dict[str, Any]:
    """Sync wrapper for forgot_password."""
    from apexsaas.core.utils.async_runner import run_async
    try:
        result = run_async(forgot_password(
            email=email,
            sendgrid_api_key=sendgrid_api_key,
            from_email=from_email,
            reset_url=reset_url,
            token_expiry_hours=token_expiry_hours
        ))
        return result
    except Exception as e:
        # Generate token even if email fails
        import secrets
        from datetime import datetime, timedelta, timezone
        reset_token = secrets.token_urlsafe(32)
        expires_at = datetime.now(timezone.utc) + timedelta(hours=token_expiry_hours)
        return {
            'reset_token': reset_token,
            'expires_at': expires_at.isoformat(),
            'email_sent': False,
            'message': f"Failed to send reset email: {str(e)}"
        }
