import asyncio
from sqlmodel import SQLModel, Session, create_engine
from src.fmatch.saas.routing.models import RoutingRule, RoutingPool, RoutingPoolMember, LeadInput
from src.fmatch.saas.routing.engine import route_lead, CRMAdapter

class DummyCRM(CRMAdapter):
    async def find_account_by_lead(self, lead: LeadInput):
        if lead.company and "Adobe" in lead.company:
            return {"id":"001A", "name":"Adobe","website":"adobe.com","owner_id":"user_ae_1","abm_tier":1}
        return None

def setup_memdb():
    engine = create_engine("sqlite:///:memory:")
    SQLModel.metadata.create_all(engine)
    return engine

def seed(db: Session, tenant_id="t1"):
    # One pool
    db.add(RoutingPool(id="pool_default", tenant_id=tenant_id, name="Default"))
    db.add(RoutingPoolMember(id="m1", pool_id="pool_default", tenant_id=tenant_id, user_id="sdr_1"))
    # One rule: ABM Tier 1 → account owner (relation ignored here)
    db.add(RoutingRule(
        id="r1", tenant_id=tenant_id, name="Tier1 to AE", priority=1,
        condition={"abm_tier":{"in":[1]}},
        action={"type":"assign_owner"}
    ))
    db.commit()

def test_account_owner_routing():
    engine = setup_memdb()
    with Session(engine) as db:
        seed(db)
        lead = LeadInput(lead_id="L1", company="Adobe", email="j@adobe.com")
        decision = asyncio.get_event_loop().run_until_complete(
            route_lead(db, DummyCRM(), "t1", lead, preview=False)
        )
        assert decision.decision == "assign_owner"
        assert decision.owner_id == "user_ae_1"

def test_default_pool_when_no_owner():
    class NoOwnerCRM(CRMAdapter):
        async def find_account_by_lead(self, lead: LeadInput):
            return None
    engine = setup_memdb()
    with Session(engine) as db:
        seed(db)
        lead = LeadInput(lead_id="L2", company="UnknownCo", email="x@unknown.io")
        decision = asyncio.get_event_loop().run_until_complete(
            route_lead(db, NoOwnerCRM(), "t1", lead, preview=False)
        )
        # No rule match and no default pool env here → no_op
        assert decision.decision in {"no_op","assign_owner"}  # assign_owner if rule matches for some reason
