#!/usr/bin/env python3
"""GIG AI-Visibility runner. Asks a prompt set across answer engines, detects whether
GIG Gulf (and competitors) get cited, scores by GEO phase, saves a dated snapshot.
Action-first weekly report is generated by report.py from the saved snapshots."""
import json, os, re, sys, time, datetime, urllib.request, concurrent.futures as cf

ROOT = os.path.dirname(os.path.abspath(__file__))
CRED = os.path.expanduser("~/ClaudeWork/Claude/credentials.md")  # host path; in sandbox use mounted
# Resolve credentials.md across host/sandbox
for p in [CRED, "/sessions/jolly-practical-lamport/mnt/ClaudeWork/Claude/credentials.md"]:
    if os.path.exists(p): CRED = p; break

def key(section, pat):
    f=False
    for l in open(CRED, errors="ignore"):
        if l.startswith("### "+section): f=True; continue
        if f and re.search(pat, l):
            m=re.search(pat, l); return m.group(0)
    return None

ANTH = key("Anthropic API", r"sk-ant-[A-Za-z0-9_-]{20,}")
OAI  = key("OpenAI", r"sk-[A-Za-z0-9_-]{20,}")
SERP = key("Serper", r"[a-f0-9]{40}")

# GIG Gulf is the rebrand of AXA Gulf (UAE, 2022). AXA legacy equity is OWNED demand —
# AXA queries deliver up to ~25% of GIG GWP. So in this UAE tool, an "AXA" mention counts
# as GIG-favourable (legacy equity), NOT a competitor.
GIG = [r"gig gulf", r"giggulf", r"gig insurance", r"gulf insurance group", r"gig-gulf", r"\baxa\b"]
COMP = {"Sukoon":[r"sukoon","oman insurance"],"Tawuniya":["tawuniya"],"Salama":["salama"],
        "Orient":["orient insurance"],"Watania":["watania"],"Daman":["daman"],
        "ADNIC":["adnic"],"RSA/Liva":["liva","rsa "],"Dubai Insurance":["dubai insurance"],
        "Noor Takaful":["noor takaful"],"Yallacompare":["yallacompare","policybazaar","insurancemarket","souqalmal"]}

def mentioned(text, pats):
    t=text.lower()
    return any(re.search(p, t) for p in pats)

def comp_hits(text):
    return [c for c,pats in COMP.items() if mentioned(text,pats)]

def http(url, data, headers, timeout=30):
    req=urllib.request.Request(url, data=json.dumps(data).encode(), headers=headers)
    with urllib.request.urlopen(req, timeout=timeout) as r: return json.loads(r.read())

def ask_openai(q):
    d=http("https://api.openai.com/v1/chat/completions",
        {"model":"gpt-4o-mini","max_tokens":400,"messages":[
         {"role":"system","content":"You are an insurance shopping assistant for the UAE. Name specific insurers and brands."},
         {"role":"user","content":q}]},
        {"Authorization":f"Bearer {OAI}","Content-Type":"application/json"})
    return d["choices"][0]["message"]["content"]

def ask_claude(q):
    d=http("https://api.anthropic.com/v1/messages",
        {"model":"claude-haiku-4-5-20251001","max_tokens":400,"messages":[
         {"role":"user","content":"You are an insurance shopping assistant for the UAE. Name specific insurers and brands.\n\n"+q}]},
        {"x-api-key":ANTH,"anthropic-version":"2023-06-01","content-type":"application/json"})
    return d["content"][0]["text"]

def ask_google(q):
    d=http("https://google.serper.dev/search",{"q":q,"gl":"ae","num":10},
        {"X-API-KEY":SERP,"Content-Type":"application/json"})
    parts=[]
    if "answerBox" in d: parts.append(json.dumps(d["answerBox"]))
    for o in d.get("organic",[])[:10]:
        parts.append(o.get("title","")+" "+o.get("link","")+" "+o.get("snippet",""))
    return "\n".join(parts)

ENGINES={"ChatGPT":ask_openai,"Claude":ask_claude,"Google":ask_google}

def run_one(p, eng):
    try:
        txt=ENGINES[eng](p["q"])
        return {"id":p["id"],"phase":p["phase"],"lob":p["lob"],"q":p["q"],"engine":eng,
                "gig":mentioned(txt,GIG),"competitors":comp_hits(txt),"ok":True,"text":txt[:1200]}
    except Exception as e:
        return {"id":p["id"],"phase":p["phase"],"lob":p["lob"],"q":p["q"],"engine":eng,
                "gig":None,"competitors":[],"ok":False,"err":str(e)[:200]}

def main():
    prompts=json.load(open(os.path.join(ROOT,"prompts.json")))
    jobs=[(p,e) for p in prompts for e in ENGINES]
    rows=[]
    with cf.ThreadPoolExecutor(max_workers=12) as ex:
        futs=[ex.submit(run_one,p,e) for p,e in jobs]
        for f in cf.as_completed(futs): rows.append(f.result())
    date=datetime.date.today().isoformat()
    os.makedirs(os.path.join(ROOT,"snapshots"),exist_ok=True)
    out=os.path.join(ROOT,"snapshots",f"{date}.json")
    json.dump({"date":date,"rows":rows},open(out,"w"),indent=1)
    ok=[r for r in rows if r["ok"]]
    gig=sum(1 for r in ok if r["gig"]); n=len(ok)
    print(f"saved {out} | {n} calls ok / {len(rows)} | GIG cited in {gig}/{n} = {gig/n*100:.0f}%")
    fails=[r for r in rows if not r["ok"]]
    if fails: print("FAILS:",len(fails),fails[0].get("err"))

if __name__=="__main__": main()
