#!/usr/bin/env python3
"""Six Senses site structure extractor for bigbreath.co design reference."""
import json, re, time
from pathlib import Path
from playwright.sync_api import sync_playwright

OUT = Path("/home/sirdrez/arisingmedia-websites/bigbreath.co/.planning/ref-patterns/sixsenses")
OUT.mkdir(parents=True, exist_ok=True)

UA = "Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0"

PAGES = [
    ("homepage", "https://www.sixsenses.com/en/"),
    ("resorts", "https://www.sixsenses.com/en/resorts"),
    ("wellness", "https://www.sixsenses.com/en/wellness"),
]

COOKIE_SELECTORS = [
    "button:has-text('Accept All')",
    "button:has-text('Accept')",
    "[id*='onetrust-accept']",
    ".cookie-accept",
    "[class*='accept-all']",
    "[aria-label*='Accept']",
    "button:has-text('I Accept')",
    "button:has-text('Agree')",
]

def dismiss_cookies(page):
    for sel in COOKIE_SELECTORS:
        try:
            btn = page.locator(sel).first
            if btn.is_visible(timeout=2000):
                btn.click()
                page.wait_for_timeout(800)
                return True
        except Exception:
            pass
    return False

def get_computed(page, selector, prop):
    try:
        return page.eval_on_selector(selector, f"el => getComputedStyle(el).{prop}")
    except Exception:
        return ""

def extract_sections(page):
    sections = []
    # grab top-level structural elements
    handles = page.query_selector_all("main > *, article > *, [role='main'] > *, body > section, body > div > section, body > div > article")
    if not handles:
        handles = page.query_selector_all("section, article, [class*='section'], [class*='block'], [class*='hero'], [class*='module']")

    seen = set()
    for h in handles[:40]:
        try:
            tag = h.evaluate("el => el.tagName.toLowerCase()")
            cls = h.evaluate("el => el.className") or ""
            role = h.get_attribute("role") or ""
            bb = h.bounding_box()
            if not bb or bb["height"] < 40:
                continue
            uid = f"{tag}|{cls[:60]}"
            if uid in seen:
                continue
            seen.add(uid)

            bg = h.evaluate("el => getComputedStyle(el).backgroundColor")
            pt = h.evaluate("el => getComputedStyle(el).paddingTop")
            pb = h.evaluate("el => getComputedStyle(el).paddingBottom")
            txt = (h.inner_text() or "")[:400].replace("\n", " ").strip()

            # card/grid detection
            cards = h.query_selector_all("[class*='card'], [class*='item'], [class*='tile'], article, li[class]")
            card_count = len(cards)

            # video detection
            has_video = bool(h.query_selector("video, [class*='video'], iframe[src*='vimeo'], iframe[src*='youtube']"))

            # image detection
            imgs = h.query_selector_all("img, [class*='image'], picture")
            has_img = len(imgs) > 0

            # guess section type
            sec_type = "unknown"
            cls_lower = cls.lower()
            txt_lower = txt.lower()
            w = bb["width"]
            h_px = bb["height"]

            if any(x in cls_lower for x in ["hero", "banner", "masthead", "jumbotron"]):
                sec_type = "hero"
            elif has_video and h_px > 400:
                sec_type = "hero_video" if card_count == 0 else "video_block"
            elif card_count >= 3:
                sec_type = "card_grid"
            elif any(x in cls_lower for x in ["quote", "testimonial", "pull"]):
                sec_type = "quote"
            elif any(x in cls_lower for x in ["footer", "foot"]) or tag == "footer":
                sec_type = "footer"
            elif any(x in cls_lower for x in ["nav", "header", "menu"]) or tag in ("header", "nav"):
                sec_type = "nav"
            elif any(x in cls_lower for x in ["split", "editorial", "feature"]):
                sec_type = "editorial_split"
            elif any(x in cls_lower for x in ["newsletter", "subscribe", "signup"]):
                sec_type = "newsletter"
            elif any(x in cls_lower for x in ["journal", "blog", "news", "article"]):
                sec_type = "journal_teaser"
            elif any(x in cls_lower for x in ["map", "location", "destination"]):
                sec_type = "location_map"
            elif any(x in cls_lower for x in ["carousel", "slider", "swiper"]):
                sec_type = "carousel"
            elif any(x in cls_lower for x in ["list", "index", "directory"]):
                sec_type = "named_list"
            elif any(x in cls_lower for x in ["wellness", "spa", "service"]):
                sec_type = "wellness_strip"
            elif has_img and len(txt) < 200 and h_px > 400:
                sec_type = "editorial_split"
            elif len(txt) > 300 and not has_img:
                sec_type = "philosophy_block"
            elif h_px > 500 and has_img:
                sec_type = "full_bleed_image"

            sections.append({
                "tag": tag,
                "class": cls[:120],
                "role": role,
                "type": sec_type,
                "bg": bg,
                "padding_top": pt,
                "padding_bottom": pb,
                "width_px": round(bb["width"]),
                "height_px": round(bb["height"]),
                "card_count": card_count,
                "has_video": has_video,
                "has_image": has_img,
                "text_snippet": txt[:300],
            })
        except Exception:
            pass
    return sections

def run():
    structure = {}
    screenshots = []

    with sync_playwright() as p:
        browser = p.firefox.launch(headless=True, args=["--no-sandbox"])
        ctx = browser.new_context(
            viewport={"width": 1440, "height": 900},
            user_agent=UA,
        )
        ctx.set_extra_http_headers({
            "Accept-Language": "en-US,en;q=0.9",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        })

        for slug, url in PAGES:
            print(f"  Loading {slug}: {url}")
            page = ctx.new_page()
            try:
                resp = page.goto(url, wait_until="domcontentloaded", timeout=60000)
                page.wait_for_timeout(3000)
                dismiss_cookies(page)
                page.wait_for_timeout(1500)

                # try networkidle with short timeout, fallback to load
                try:
                    page.wait_for_load_state("networkidle", timeout=15000)
                except Exception:
                    pass

                page.wait_for_timeout(2000)

                # screenshot
                shot_path = OUT / f"{slug}.png"
                page.screenshot(path=str(shot_path), full_page=True, timeout=30000)
                screenshots.append(str(shot_path))
                print(f"    Screenshot: {shot_path}")

                # if resorts page, try to follow first resort link
                if slug == "resorts":
                    resort_links = page.query_selector_all("a[href*='/resorts/']")
                    if resort_links:
                        first_href = resort_links[0].get_attribute("href")
                        if first_href and first_href != "/en/resorts":
                            full_url = first_href if first_href.startswith("http") else f"https://www.sixsenses.com{first_href}"
                            print(f"    Following resort link: {full_url}")
                            page2 = ctx.new_page()
                            try:
                                page2.goto(full_url, wait_until="domcontentloaded", timeout=60000)
                                page2.wait_for_timeout(3000)
                                dismiss_cookies(page2)
                                page2.wait_for_timeout(1500)
                                try:
                                    page2.wait_for_load_state("networkidle", timeout=15000)
                                except Exception:
                                    pass
                                page2.wait_for_timeout(2000)
                                shot2 = OUT / "resort_detail.png"
                                page2.screenshot(path=str(shot2), full_page=True, timeout=30000)
                                screenshots.append(str(shot2))
                                secs2 = extract_sections(page2)
                                structure["resort_detail"] = {
                                    "url": full_url,
                                    "status": page2.url,
                                    "sections": secs2,
                                }
                                print(f"    Resort detail: {len(secs2)} sections")
                            except Exception as e:
                                structure["resort_detail"] = {"url": full_url, "error": str(e)}
                            finally:
                                page2.close()

                sections = extract_sections(page)
                structure[slug] = {
                    "url": url,
                    "final_url": page.url,
                    "http_status": resp.status if resp else None,
                    "sections": sections,
                }
                print(f"    Sections found: {len(sections)}")

            except Exception as e:
                structure[slug] = {"url": url, "error": str(e)}
                print(f"    ERROR: {e}")
            finally:
                page.close()

        browser.close()

    # save structure
    out_json = OUT / "structure.json"
    out_json.write_text(json.dumps(structure, indent=2))
    print(f"\nstructure.json written: {out_json.stat().st_size} bytes")
    print(f"Screenshots: {len(screenshots)}")
    return structure, screenshots

if __name__ == "__main__":
    s, shots = run()
    print(f"\nDone. Pages: {list(s.keys())}")
