from fastapi import HTTPException
import random
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from datetime import datetime, timedelta
import pytz
from src.db.mongodb import db
from src.config import settings


def generate_otp(email: str) -> int:
    otp = random.randint(100000, 999999)
    india_tz = pytz.timezone("Asia/Kolkata")
    expires_at = datetime.now(india_tz) + timedelta(minutes=5)

    otp_store = {
      "email": email,
      "otp": otp,
      "expires_at": expires_at.isoformat(),
      "verified": False
    }
    db.otps.update_one(
      {"email": email},
      {"$set": otp_store},          
      upsert=True                   
    )
    return otp

def send_otp_mail(email, otp):
    smtp_server = settings.SMTP_SERVER
    smtp_port = settings.SMTP_PORT
    sender_email = settings.EMAIL_SENDER
    sender_password = settings.EMAIL_PASSWORD

    receiver_email = email
    subject = "Trail event OTP verification."
    body = f"Your OTP is: {otp}"

    msg = MIMEMultipart()
    msg["From"] = sender_email
    msg["To"] = receiver_email
    msg["Subject"] = subject
    msg.attach(MIMEText(body, "plain"))
    try:
        with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:
            server.ehlo()
            try:
                server.login(sender_email, sender_password)
            except Exception as e:
                return {"error": f"Failed to send email: {str(e)}"}
            
            server.sendmail(sender_email, receiver_email, msg.as_string())
        return {"message": "Email sent successfully"}
    except Exception as e:
        return {"error": f"Failed to send email: {str(e)}"}

def verify_otp(email:str, otp: int)-> bool:
    record = db.otps.find_one({"email": email, "otp": otp})
    
    if not record:
        raise HTTPException(status_code=404, detail="OTP not found")

    if record["verified"]:
        raise HTTPException(status_code=400, detail="OTP already verified")

    india_tz = pytz.timezone("Asia/Kolkata")
    now_ist = datetime.now(india_tz)
    now_time = datetime.fromisoformat(now_ist.isoformat())

    if now_time.timestamp() > datetime.fromisoformat(record["expires_at"]).timestamp():
        raise HTTPException(status_code=400, detail="OTP expired")

    if record["otp"] != otp:
        raise HTTPException(status_code=400, detail="Invalid OTP")

    db.otps.update_one(
      {"_id": record["_id"]},
      {"$set": {"verified": True}}
    )

    return {"verified": True}

