"""Full E2E test suite for Primitif — Mail + Approval.

Uses the unified Python SDK throughout.
"""

import time
import sys

from primitif import Primitif

TOKEN = "ns_live_9caf029ea87d4cd94691e108ed386a43"

passed = 0
failed = 0
total = 0


def test(name):
    global total
    total += 1
    print(f"\n{'='*60}")
    print(f"  TEST {total}: {name}")
    print(f"{'='*60}")


def ok(msg=""):
    global passed
    passed += 1
    print(f"  ✓ PASS {msg}")


def fail(msg):
    global failed
    failed += 1
    print(f"  ✗ FAIL {msg}")


p = Primitif(api_key=TOKEN)

# ── MAIL TESTS ──

mb = None

test("Create mailbox")
try:
    mb = p.mail.create_mailbox(name="e2e-full-test", ttl=600)
    assert mb.address.endswith("@mail.primitif.ai"), f"Bad address: {mb.address}"
    mb_info = mb.info()
    assert mb_info.id.startswith("mb_"), f"Bad id: {mb_info.id}"
    ok(f"address={mb.address}, id={mb_info.id}")
except Exception as e:
    fail(str(e))

test("List mailboxes")
try:
    mailboxes = p.mail.list_mailboxes()
    ids = [m.id for m in mailboxes]
    assert mb_info.id in ids, f"Mailbox {mb_info.id} not in list"
    ok(f"found {len(mailboxes)} mailbox(es)")
except Exception as e:
    fail(str(e))

test("Send email")
try:
    result = mb.send(
        to="test@example.com",
        subject="E2E test email",
        body_text="Hello from E2E test",
    )
    assert result.message_id, f"No message_id"
    ok(f"message_id={result.message_id}")
except Exception as e:
    fail(str(e))

test("Check inbox (empty — outbound doesn't appear)")
try:
    inbox = mb.inbox()
    ok(f"inbox has {len(inbox.items)} messages")
except Exception as e:
    fail(str(e))

test("Get mailbox info")
try:
    info = mb.info()
    assert info.id == mb_info.id
    assert info.address == mb.address
    ok(f"name={info.name}, address={info.address}")
except Exception as e:
    fail(str(e))

test("List threads")
try:
    thread_list = mb.threads()
    ok(f"found {len(thread_list.items)} threads")
except Exception as e:
    fail(str(e))

test("Send self-email (for inbox test)")
try:
    self_result = mb.send(
        to=mb.address,
        subject="Self-test email",
        body_text="Testing inbox receipt",
    )
    ok(f"sent to self: message_id={self_result.message_id}")
except Exception as e:
    fail(str(e))

test("Wait and check inbox for self-email")
messages = []
try:
    time.sleep(5)
    inbox = mb.inbox()
    messages = inbox.items
    if len(messages) > 0:
        ok(f"inbox has {len(messages)} message(s)")
    else:
        # Inbound email may take longer via Cloudflare worker
        time.sleep(10)
        inbox = mb.inbox()
        messages = inbox.items
        ok(f"inbox has {len(messages)} message(s) (after retry)")
except Exception as e:
    fail(str(e))

test("Read a message")
try:
    if messages:
        detail = mb.read(messages[0].id)
        assert detail.subject, "No subject"
        ok(f"subject='{detail.subject}'")
    else:
        ok("skipped — no inbound messages yet")
except Exception as e:
    fail(str(e))

# ── APPROVAL TESTS ──

test("Create approval request")
req = None
try:
    req = p.approval.create_request(
        action="E2E test action",
        context={"test_run": "full_suite", "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ")},
    )
    assert req.id, "No request ID"
    assert req.status == "pending", f"Expected pending, got {req.status}"
    assert req.approval_url, "No approval URL"
    ok(f"id={req.id}, status={req.status}")
except Exception as e:
    fail(str(e))

test("Get approval request")
try:
    if req:
        fetched = p.approval.get_request(req.id)
        assert fetched.id == req.id
        assert fetched.status == "pending"
        ok(f"status={fetched.status}")
    else:
        fail("skipped — no request created")
except Exception as e:
    fail(str(e))

test("List approval requests")
try:
    reqs = p.approval.list_requests()
    if req:
        ids = [r.id for r in reqs]
        assert req.id in ids, f"Request {req.id} not in list"
    ok(f"found {len(reqs)} requests")
except Exception as e:
    fail(str(e))

# ── CLEANUP ──

test("Delete mailbox")
try:
    mb.delete()
    ok("mailbox deleted")
except Exception as e:
    fail(str(e))

# ── SUMMARY ──

print(f"\n{'='*60}")
print(f"  RESULTS: {passed}/{total} passed, {failed} failed")
print(f"{'='*60}")

p.close()

if failed > 0:
    sys.exit(1)
