"""Auth business logic. All MFA/TOTP crypto is delegated to the MCP auth service."""
import base64
import random
from io import BytesIO

import qrcode
from django.conf import settings
from django.core.mail import send_mail
from django.utils import timezone
from rest_framework_simplejwt.tokens import RefreshToken

from . import mcp_client
from .models import OTPRecord


def generate_totp_secret() -> str:
    return mcp_client.generate_mfa_secret()


def get_provisioning_uri(secret: str, email: str) -> str:
    return mcp_client.get_provisioning_uri(secret, email)


def verify_totp(secret: str, code: str) -> bool:
    if not secret or not code:
        return False
    return mcp_client.verify_mfa_code(secret, code)


def qr_code_base64(uri: str) -> str:
    img = qrcode.make(uri)
    buffered = BytesIO()
    img.save(buffered, format="PNG")
    return "data:image/png;base64," + base64.b64encode(buffered.getvalue()).decode()


def issue_tokens(user) -> dict:
    refresh = RefreshToken.for_user(user)
    return {"access": str(refresh.access_token), "refresh": str(refresh)}


import logging

logger = logging.getLogger(__name__)

def generate_otp_for_user(user) -> str:
    """Create or refresh the 6-digit OTP (used by email OTP and the MCP agent flow)."""
    otp = f"{random.randint(100000, 999999)}"
    OTPRecord.objects.update_or_create(
        user=user,
        defaults={"otp_code": otp, "created_at": timezone.now(), "retry_count": 0},
    )
    return otp


def send_email_otp(user) -> dict:
    """Send a secure OTP to user's registered email via Django SMTP."""
    otp = generate_otp_for_user(user)

    subject = "Password Reset Verification Code - TA-ATS"
    message = (
        f"Hello {user.full_name or user.username},\n\n"
        f"Your password reset verification code is: {otp}\n\n"
        f"This code will expire in {getattr(settings, 'OTP_EXPIRY_MINUTES', 5)} minutes. "
        "If you did not request a password reset, please ignore this email.\n\n"
        "Best regards,\nTA-ATS Team"
    )

    from_email = getattr(settings, "DEFAULT_FROM_EMAIL", None) or getattr(settings, "EMAIL_HOST_USER", None) or "no-reply@ta-ats.local"

    try:
        send_mail(
            subject=subject,
            message=message,
            from_email=from_email,
            recipient_list=[user.email],
            fail_silently=False,
        )
    except Exception as e:
        logger.warning("Email OTP delivery failed for %s: %s", user.email, e)
        raise RuntimeError(f"Could not deliver email verification code: {e}") from e

    return {
        "success": True,
        "message": "A reset code has been sent to your registered email address.",
        "otp": otp,
    }


def check_email_otp(user, code: str) -> bool:
    """Validate the emailed OTP WITHOUT consuming it (for a separate verify step)."""
    record = OTPRecord.objects.filter(user=user).first()
    if not record or record.is_expired():
        return False
    return record.otp_code == code


def verify_email_otp(user, code: str) -> bool:
    """Check the emailed OTP against the stored record (with expiry), consuming it."""
    record = OTPRecord.objects.filter(user=user).first()
    if not record or record.is_expired():
        return False
    if record.otp_code != code:
        return False
    record.delete()
    return True
