"""End-to-end exercise of the sign-in-code flow against the live app and DB.

Creates a throwaway account, walks the two real HTTP routes, and removes the
account again. Only the SMTP hop is stubbed, and only so the code can be read.
"""
import uuid
from fastapi.testclient import TestClient

from app.database import SessionLocal
from app.models.user import User
from app.models.email_verification import EmailVerification
from app.models.login_code import LoginCode
from app.services import email_service, login_codes

captured = {}
async def fake_send(to_email, name, code):
    captured['code'] = code
    captured['to'] = to_email

import app.routers.login_code as lc
lc.email_service.send_login_code_email = fake_send

from app.main import app
client = TestClient(app)

db = SessionLocal()
addr = f"codetest+{uuid.uuid4().hex[:8]}@codetest.pedshub.com"
user = User(email=addr, name="Code Test", hashed_password=None, role="user")
db.add(user); db.commit(); db.refresh(user)
import datetime as _dt
_now = _dt.datetime.utcnow()
db.add(EmailVerification(user_id=user.id, token=uuid.uuid4().hex,
                         expires_at=_now + _dt.timedelta(days=1), verified_at=_now))
db.commit()
print(f"user {user.id} {addr}")

try:
    r = client.post("/api/auth/login-code", json={"email": addr})
    print("request  :", r.status_code, r.json())
    print("captured :", captured.get('code'), "->", login_codes.for_display(captured.get('code','')))

    row = db.query(LoginCode).filter(LoginCode.user_id == user.id).order_by(LoginCode.id.desc()).first()
    print("row      : id", row.id, "expires", row.expires_at, "attempts", row.attempts)

    bad = client.post("/api/auth/login-code/verify", json={"email": addr, "code": "AAAAAA"})
    print("wrong    :", bad.status_code, bad.json())

    typed = login_codes.for_display(captured['code']).lower()   # as a person would type it
    ok = client.post("/api/auth/login-code/verify", json={"email": addr, "code": typed})
    print("right    :", ok.status_code, str(ok.json())[:90])

    again = client.post("/api/auth/login-code/verify", json={"email": addr, "code": typed})
    print("reuse    :", again.status_code, again.json())

    if ok.status_code == 200:
        token = ok.json()["access_token"]
        me = client.get("/api/auth/me", headers={"Authorization": f"Bearer {token}"})
        print("session  :", me.status_code, str(me.json())[:120])

    unknown = client.post("/api/auth/login-code", json={"email": "nobody-here@codetest.pedshub.com"})
    print("unknown  :", unknown.status_code, unknown.json())
finally:
    db.query(LoginCode).filter(LoginCode.user_id == user.id).delete()
    db.query(EmailVerification).filter(EmailVerification.user_id == user.id).delete()
    db.query(User).filter(User.id == user.id).delete()
    db.commit()
    print("cleaned up")
