import platform
import asyncio
from playwright.async_api import async_playwright
import argparse
import os
from datetime import datetime
from pathlib import Path
import logging
from typing import List, Optional
import uuid
from playwright_helper import BASE_PROFILE_DIR, BASE_STATE_DIR, PersistentBrowser
logging.getLogger(__name__)


async def new_context(url, persistent_browser: PersistentBrowser, context_id: str, extension_paths: List[Path], **kwargs):
    logging.info(kwargs)
    # Create a new context with the pre-set extensions
    context = await persistent_browser.new_context(
        context_id=context_id,
        extension_paths=extension_paths,
        **kwargs
    )

    # Open a new page in the context
    page = await context.new_page()

    # Navigate to a sample website
    await page.goto(url)

    # Print the page title as an example action
    logging.info(f"Page title for context {context_id}: {await page.title()}")

    return context




async def monitor_stream(log_path, domain):
    async with async_playwright() as p:
        browser_is_pw = False
        #try:
        #   browser = await p.chromium.connect_over_cdp("http://localhost:9222")
        #except:
        #   user_data_dir = './user-data'
        #   cont = await p.chromium.launch_persistent_context(user_data_dir, 
        #                                                     #viewport=None, 
        #                                                     headless=False, 
        #                                                     args=[
        #                                                        "--disable-infobars", 
        #                                                        #"--disable-features=Antaniu"
        #                                                          ], 
        #                                                     ignore_default_args=["--enable-automation", "--no-sandbox"],)
        #   pages = cont.pages
        #   browser_is_pw = True
        ##   if pages:
        #      page = pages[0]
        #   else:
        #      page = await cont.new_page()
        #   logger.info(page.url)
        #   await page.goto('http://localhost:5000/chat')
        #   logger.info("Browser session retained")
        #   #await browser.close()
        #   browser = cont.browser

        # Ensure base directories exist
        BASE_PROFILE_DIR.mkdir(parents=True, exist_ok=True)
        BASE_STATE_DIR.mkdir(parents=True, exist_ok=True)

        use_persistent_context = False

        # Define pre-set extensions to be copied to all contexts
        EXTENSION_PATHS = [
            Path("./my_extension1"),  # Example: use forward slashes for cross-platform compatibility
            Path("./my_extension2")   # Replace with actual paths to unpacked extension directories
        ]


        # Create simulated browser with the chosen mode and extensions
        browser = PersistentBrowser(p, BASE_PROFILE_DIR, use_persistent_context, EXTENSION_PATHS, 
                                                            args=[
                                                               "--disable-infobars", 
                                                               "--disable-features=Antaniu"
                                                                  ], 
                                                             ignore_default_args=["--enable-automation", "--no-sandbox"])
        await browser.launch()

        # Create tasks for multiple contexts
        tasks = []

        context_id = str(uuid.uuid4())  # Unique ID for each context
        ##tasks.append(new_context("http://localhost:5000/chat", browser, context_id, EXTENSION_PATHS))
        ##await asyncio.gather(*tasks)
        await new_context("http://localhost:5000/chat", browser, context_id, EXTENSION_PATHS,viewport=None)



        bw = 0
        dw = 0
        bh = 0
        bw = 0
        while len(browser.contexts()) > 0:
            #browser = cont.browser
            #if browser:
            #   contexts = browser.contexts
            #else:
            #   contexts = [cont]
            contexts = browser.contexts()
            logging.info("MUMBER OF CONTEXTS: %d", len(browser.contexts()))
            for context in contexts:
               logger.debug("@@@@@@@@@@@ NEW CONTEXT @@@@@@@@")
               if browser_is_pw:
                  sizedone=False
               logging.info("NUMBER OF PAGES IN THIS CONTEXT: %d", len(context.pages))
               for page in context.pages:
                  logger.info("newpagess----------------")
                  if browser_is_pw and not sizedone:
                     w = await page.evaluate('window.outerWidth')
                     h = await page.evaluate('window.outerHeight')
                     if bw==0 and bh==0:
                        tw = page.viewport_size["width"]
                        th = page.viewport_size["height"]
                        dw = w-tw
                        dh = h-th
                        logger.info("ViewPort difference: %d %d", dw, dh)
                     elif bw!=w or bh!=h:
                        logger.info("outerWindow detected: %d %d", w, h)
                        logger.info("ViewPort difference: %d %d", dw, dh)
                        logger.info("Change ViewPort Size: %d %d", w-dw, h-dh)
                        await page.set_viewport_size({"width": w-dw, "height": h-dh})
                        # XXX I NEED TO CHANGE THE VIEWPORT OF ALL PAGES OR IT
                        # GET CONFUSED. EASY: TODO: USE A FUCKING TATE MACHINE
                        sizedone=True
                     bw = w
                     bh = h
                  #logger.info("Size: %d %d", w, h)
                  if domain in  page.url:
                     logger.info(f"Found Streamate tab")
                     # XXX THIS IS FUCKONG BLOCKING, TODO: RAKE IT OUT AND PUT THE
                     # WHOLE THING IN A STATE MACHINE
                     await monitor_requests(page, log_path)
               if len(context.pages) < 1 and len(browser.contexts()) == 1:
                  #await context.close()
                  logging.info("CLOOOOOOSSSINNNNNNGGGG")
                  await browser.close()
                    
            # XXX TODO: I ALREADY SAID MAKE A FUCKING STATE MACHINE?
            #logger.info("PORCDIOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO\b\b")
            await asyncio.sleep(.1)  # Check every 0.1 seconds
    # Close the simulated browser, saving states and backing up profiles
    #await browser.close()


async def monitor_requests(page, log_path):
    async def log_request(request):
        if request.resource_type not in ['document', 'image', 'font', 'stylesheet']:
            log_entry = f"[{datetime.now()}] Request: {request.method} {request.url}\n"
            with open(log_path, 'a') as f:
                f.write(log_entry)
    async def log_response(response):
        #print(await response.body())
        #print(response.request.resource_type)
        #if response.request.resource_type not in ['document', 'image', 'font', 'stylesheet']:
        if response.request.resource_type in ['xhr'] and not response.url.endswith(".mp3"):
            log_entry = f"[{datetime.now()}] Response: {response.status} {response.url} -> BODY: "
            log_body = await response.body()
            with open(log_path, 'a') as f:
                f.write(log_entry)
                print(log_body)
                f.write(str(log_body))
                f.write("\n\n")
    async def log_websocket(ws):
        def writelog(payload, origin, url):
           logging.info(origin+": "+str(payload)+"\n")
           log_entry = f"[{datetime.now()}] WS: {origin} {url} -> Message: "
           with open(log_path, 'a') as f:
               f.write(log_entry)
               f.write(origin+": ")
               f.write(str(payload)+"\n\n")
        logging.info(f"WebSocket opened: {ws.url}")
        ws.on("framesent", lambda payload: writelog(payload, 'framesent', ws.url))
        ws.on("framereceived", lambda payload: writelog( payload, 'framereceived', ws.url))
        ws.on("close", lambda payload: print("WebSocket closed"))
    page.on("request", log_request)
    page.on("response", log_response)
    page.on("websocket", log_websocket)
    while True:
        await asyncio.sleep(1)



def run_browser():
    lpath=str(Path(Path.home(), Path('streamon.log')))
    
    # Check if browser should be launched automatically
    auto_launch = config.getboolean('Browser', 'auto_launch', fallback=False)
    
    if not auto_launch:
        logging.info("Browser auto-launch is disabled. Set auto_launch=true in [Browser] section of shmcamstudio.conf to enable.")
        return
    
    logging.info("Starting browser...")
    log_dir = os.path.dirname(lpath)
    if log_dir and not os.path.exists(log_dir):
        os.makedirs(log_dir)
    asyncio.run(monitor_stream(lpath, "performerclient.streamatemodels.com"))
