import re, json, html, subprocess, os, openpyxl
PUB = "/srv/apps/brentwood/laravel/storage/app/public"

# --- sheet: slug -> Title Area Type ---
wb = openpyxl.load_workbook('/srv/apps/brentwood/brentwood-pages.xlsx', read_only=True, data_only=True)
ws = wb['Migration Map']; rows=list(ws.iter_rows(values_only=True)); H=rows[0]
ix={n:i for i,n in enumerate(H)}
SHEET=[]
for r in rows[1:]:
    slug=(str(r[ix['Slug']]).strip() if r[ix['Slug']] else '')
    tat=(str(r[ix['Title Area Type']]).strip() if r[ix['Title Area Type']] else '')
    if slug: SHEET.append((slug,tat))

WANT={'Image - Simple','Image - Slider','Image - Dual','Video - MP4','Video - YouTube'}

def fetch(slug):
    try:
        return subprocess.run(["curl","-s","--max-time","30","-b","/tmp/demoing-cookies.txt",
            "https://brentwood.demoing.info"+slug], capture_output=True, text=True, timeout=40).stdout
    except Exception: return ""

def attr_json_at(h,i):
    seg=h[i:i+300000]; m=re.search(r"=(['\"])\s*([{\[])",seg)
    if not m: return None
    q=m.group(1); s=m.start(2)
    try: end=seg.index(q,s)
    except ValueError: return None
    raw=seg[s:end]
    if q=='"': raw=html.unescape(raw)
    try: return json.loads(raw)
    except: return None

def walk_photos(n,out):
    if isinstance(n,dict):
        if ('large' in n or 'small' in n) and 'content_id' in n and 'id' in n:
            p=n.get('large') or n.get('medium') or n.get('small')
            if isinstance(p,str) and '/photos/' in p.replace('\\/','/'):
                out.append((n.get('content_id'),n['id'],n.get('sort_order',0),p.replace('\\/','/')))
        for v in n.values(): walk_photos(v,out)
    elif isinstance(n,list):
        for v in n: walk_photos(v,out)

def extract(slug):
    h=fetch(slug)
    if not h: return {"detected":"fetch_fail"}
    tags=['video-player','slideshow','photo-container','photo-viewer']
    occ=sorted((m.start(),t) for t in tags for m in re.finditer('<'+t,h))
    if not occ: return {"detected":"none"}
    d0=attr_json_at(h,occ[0][0]); o=d0[0] if isinstance(d0,list) and d0 else d0
    ct=o.get("content_type","") if isinstance(o,dict) else ""; cid=o.get("content_id") if isinstance(o,dict) else None
    if "EmbedVideo" in ct or occ[0][1]=="video-player":
        txt=json.dumps(d0).replace('\\/','/')
        vids=sorted(set(re.findall(r'videos/\d+/[A-Za-z0-9._-]+\.mp4',txt)))
        pick=next((v for v in vids if v.endswith('_medium.mp4')), None) or next((v for v in vids if v.endswith('_large.mp4')),None) or (vids[0] if vids else None)
        return {"detected":"video","video":pick,"all_videos":vids}
    if "Youtube" in ct:
        yid=re.search(r'"video_id":"?([A-Za-z0-9_-]{6,})"?',json.dumps(d0))
        return {"detected":"youtube","youtube_id":yid.group(1) if yid else None}
    allp=[]
    for pos,_ in occ:
        dd=attr_json_at(h,pos)
        if dd is not None: walk_photos(dd,allp)
    seen={}
    for c,pid,so,p in allp:
        if c==cid: seen[pid]=(so,p)
    slides=[p for _,p in sorted(seen.values())]
    typ="dual" if ("PhotoBlock" in ct and len(slides)==2) else ("slider" if len(slides)>1 else "image")
    return {"detected":typ,"slides":slides}

SHEET_MAP={'Image - Simple':'image','Image - Slider':'slider','Image - Dual':'dual',
           'Video - MP4':'video','Video - YouTube':'youtube'}
manifest=[]; n=0
todo=[(s,t) for s,t in SHEET if t in WANT]
print(f"sweeping {len(todo)} pages...")
for slug,tat in todo:
    n+=1
    r=extract(slug)
    media=r.get('slides') or ([r['video']] if r.get('video') else [])
    on_disk=[m for m in media if m and os.path.isfile(PUB+'/'+m.lstrip('/'))]
    rec={"slug":slug,"sheet_type":SHEET_MAP.get(tat,tat),"detected":r.get("detected"),
         "media":media,"on_disk":len(on_disk),"missing":[m for m in media if m not in on_disk],
         "youtube_id":r.get("youtube_id")}
    manifest.append(rec)
    if n%20==0: print(f"  {n}/{len(todo)}")
json.dump(manifest, open('/tmp/page-heroes-manifest.json','w'), indent=1)
print("done ->/tmp/page-heroes-manifest.json")
