"""
OTP generation, storage, and verification service.
"""
import random
import string
from datetime import datetime, timedelta
from flask_mail import Message
from flask import current_app
from app.extensions import mail

def generate_otp(length: int = 6) -> str:
    """Generate random OTP code."""
    return "".join(random.choices(string.digits, k=length))

def generate_expires_at(minutes: int = 10) -> datetime:
    """Generate expiry time for OTP."""
    return datetime.utcnow() + timedelta(minutes=minutes)

def send_otp_email(email: str, otp: str, user_name: str = ""):
    """Send OTP email to user (Arabic)."""
    try:
        msg = Message(
            "Jadwa AI - Your Verification Code",
            recipients=[email],
        )
        msg.html = f"""
        <div style="font-family:Arial,sans-serif;max-width:500px;margin:0 auto;padding:20px;text-align:center">
            <h2 style="color:#D2AF20;margin-bottom:5px">Jadwa AI</h2>
            <p style="font-size:16px;margin:20px 0;color:#fff">
                Hello {user_name or 'User'},<br>
                Your verification code is:
            </p>
            <div style="background:#D2AF20;color:#000;font-size:32px;font-weight:bold;
                        padding:20px 40px;border-radius:10px;letter-spacing:5px;margin:20px 0;">
                {otp}
            </div>
            <p style="color:#aaa;font-size:14px">
                This code expires in 10 minutes.<br>
                If you didn't request this, please ignore this email.
            </p>
        </div>
        """
        mail.send(msg)
        return True
    except Exception as e:
        return False

def send_otp_email_en(email: str, otp: str, user_name: str = ""):
    """Send OTP email to user (English)."""
    try:
        msg = Message(
            "Jadwa AI - Your Verification Code",
            recipients=[email],
        )
        msg.html = f"""
        <div style="font-family:Arial,sans-serif;max-width:500px;margin:0 auto;padding:20px;text-align:center">
            <h2 style="color:#D2AF20;margin-bottom:5px">Jadwa AI</h2>
            <p style="font-size:16px;margin:20px 0;color:#fff">
                Hello {user_name or 'User'},<br>
                Your verification code is:
            </p>
            <div style="background:#D2AF20;color:#000;font-size:32px;font-weight:bold;
                        padding:20px 40px;border-radius:10px;letter-spacing:5px;margin:20px 0;">
                {otp}
            </div>
            <p style="color:#aaa;font-size:14px">
                This code expires in 10 minutes.<br>
                If you didn't request this, please ignore this email.
            </p>
        </div>
        """
        mail.send(msg)
        current_app.logger.info(f"OTP email sent to {email}")
        return True
    except Exception as e:
        current_app.logger.error(f"Failed to send OTP email to {email}: {e}")
        import traceback
        current_app.logger.error(traceback.format_exc())
        return False

def store_otp(user_id: int, otp: str, expiry_minutes: int = 10, db=None):
    """Store OTP for user."""
    from app.models.user import User
    if db is None:
        db = current_app.extensions['db']
    user = User.query.get(user_id)
    if user:
        user.otp_code = otp
        user.otp_expires_at = datetime.utcnow() + timedelta(minutes=expiry_minutes)
        db.session.commit()

def verify_otp(user, code: str) -> bool:
    """Verify OTP for user."""
    if not user or not user.otp_code or not user.otp_expires_at:
        return False
    if datetime.utcnow() > user.otp_expires_at:
        return False
    return user.otp_code == code

def clear_otp(user, db=None):
    """Clear used OTP."""
    if db is None:
        db = current_app.extensions['db']
    if user:
        user.otp_code = None
        user.otp_expires_at = None
        db.session.commit()

def verify_otp_from_session(session_otp, code: str) -> bool:
    """Verify OTP from session data (for registration)."""
    if not session_otp:
        return False
    expires_at_str = session_otp.get("expires_at")
    if not expires_at_str:
        return False
    try:
        expires_at = datetime.fromisoformat(expires_at_str)
        if datetime.utcnow() > expires_at:
            return False
    except (ValueError, TypeError):
        return False
    return session_otp.get("code") == code
