"""UAT for GET /custody/liability-report/{user_id}. Run INSIDE ams-shiva-api-1."""
import sys, time, uuid, httpx

BASE="http://localhost:8000/api/v1"; TEN={"X-Tenant-Slug":"demo-enterprise"}
P=F=0
def ok(n,c,x=""):
    global P,F
    if c: P+=1; print(f"  PASS {n} {x}")
    else: F+=1; print(f"  FAIL {n} {x}")

def login(email,pw,retries=4):
    last=""
    for _ in range(retries):
        try:
            r=httpx.post(f"{BASE}/auth/login",json={"email":email,"password":pw},headers=TEN,timeout=30)
            if r.status_code==200: return r.json()["data"]["access_token"]
            last=f"{r.status_code} {r.text[:120]}"
            if r.status_code==429: break
        except Exception as e: last=str(e)
        time.sleep(1.5)
    raise RuntimeError(f"login failed {email}: {last}")

def H(tok): return {**TEN,"Authorization":f"Bearer {tok}"}

def main():
    admin=login("admin@demo-enterprise.in","demo1234"); ah=H(admin)

    # Fresh custodian
    tag=uuid.uuid4().hex[:8]
    email=f"uat-lr-{tag}@demo-enterprise.in"
    r=httpx.post(f"{BASE}/users",json={"name":f"LR {tag}","email":email,"password":"Uat!2345","role":"Custodian"},headers=ah,timeout=30)
    ok("create custodian",r.status_code in (200,201),r.status_code)
    cust_id=r.json()["data"]["id"]
    time.sleep(1)
    cust_tok=login(email,"Uat!2345"); ch=H(cust_tok)

    # Empty report first
    r=httpx.get(f"{BASE}/custody/liability-report/{cust_id}",params={"format":"json"},headers=ah,timeout=30)
    ok("empty report 200",r.status_code==200,r.status_code)
    ok("empty report []",r.json()["data"]==[],r.json()["data"])

    # Build an active custody: create asset -> assign -> accept
    ac=httpx.get(f"{BASE}/masters/asset-classes",params={"page_size":1},headers=ah,timeout=30).json()["data"]
    acid=(ac["items"] if isinstance(ac,dict) else ac)[0]["id"]
    loc=httpx.get(f"{BASE}/masters/locations",params={"page_size":1},headers=ah,timeout=30).json()["data"]
    locid=(loc["items"] if isinstance(loc,dict) else loc)[0]["id"]
    fs=httpx.get(f"{BASE}/masters/funding-source-masters",params={"is_active":True,"page_size":50},headers=ah,timeout=30).json()["data"]
    fsi=fs["items"] if isinstance(fs,dict) else fs
    funding=next((x["code"] for x in fsi if x.get("status")=="active"),fsi[0]["code"])
    a=httpx.post(f"{BASE}/assets",json={"name":f"LR Asset {tag}","asset_class_id":acid,"location_id":locid,"acquisition_date":"2026-01-01T00:00:00Z","acquisition_cost":50000,"funding_source":funding},headers=ah,timeout=30)
    ok("create asset",a.status_code in (200,201),a.status_code)
    aid=a.json()["data"]["id"]
    asg=httpx.post(f"{BASE}/assets/{aid}/custody",json={"custodian_user_id":cust_id},headers=ah,timeout=30)
    ok("assign custody",asg.status_code in (200,201),asg.status_code)
    cid=asg.json()["data"]["id"]
    acc=httpx.put(f"{BASE}/custody/{cid}/accept",json={"device_id":"uat","ip_address":"127.0.0.1"},headers=ch,timeout=30)
    ok("accept custody",acc.status_code==200,acc.status_code)

    # Report now has the asset with correct fields
    r=httpx.get(f"{BASE}/custody/liability-report/{cust_id}",params={"format":"json"},headers=ah,timeout=30)
    ok("report 200",r.status_code==200,r.status_code)
    data=r.json()["data"]
    ok("report has 1 row",len(data)==1,len(data))
    if data:
        row=data[0]
        ok("row has asset_ref",bool(row.get("asset_ref")),row.get("asset_ref"))
        ok("row name matches",row.get("name")==f"LR Asset {tag}",row.get("name"))
        ok("acquisition_cost=50000",row.get("acquisition_cost")==50000,row.get("acquisition_cost"))
        ok("net_book_value present (NBV or cost)",row.get("net_book_value") is not None,row.get("net_book_value"))

    # RBAC: custodian may view SELF
    r=httpx.get(f"{BASE}/custody/liability-report/{cust_id}",params={"format":"json"},headers=ch,timeout=30)
    ok("custodian self 200",r.status_code==200,r.status_code)

    # RBAC: custodian may NOT view ANOTHER user (403)
    other=login("admin@demo-enterprise.in","demo1234")  # admin's own id != cust
    admin_id=httpx.get(f"{BASE}/auth/me",headers=ah,timeout=30).json()["data"].get("id") or \
             httpx.get(f"{BASE}/auth/me",headers=ah,timeout=30).json()["data"].get("user_id")
    r=httpx.get(f"{BASE}/custody/liability-report/{admin_id}",params={"format":"json"},headers=ch,timeout=30)
    ok("custodian other 403",r.status_code==403,r.status_code)

    # format=pdf -> 501
    r=httpx.get(f"{BASE}/custody/liability-report/{cust_id}",params={"format":"pdf"},headers=ah,timeout=30)
    ok("pdf 501",r.status_code==501,r.status_code)

    # Unauthenticated -> 401
    r=httpx.get(f"{BASE}/custody/liability-report/{cust_id}",params={"format":"json"},headers=TEN,timeout=30)
    ok("unauth 401",r.status_code==401,r.status_code)

    print(f"\n==== {P} passed, {F} failed ====")
    sys.exit(1 if F else 0)

if __name__=="__main__":
    main()
