"""
Session Extraction Tool
=======================
Extracts browser session data (cookies, storage, fingerprint) for web scraping.

Usage:
    uv run intelliscraper/scripts/get_session_data.py --url "https://himalayas.app" --site "himalayas" --output "./himalayas_session.json"
    # Or, using the installed CLI command:
    `intelliscraper-session --url "https://himalayas.app" --site "himalayas" --output "./himalayas_session.json"`
"""

import argparse
import logging

from playwright.sync_api import sync_playwright

from intelliscraper.common.models import Session


def extract_and_save_session(url: str, site: str, output_filepath: str):
    """
    Extract complete session data from a website.

    Opens browser, waits for manual login, then extracts cookies,
    localStorage, sessionStorage, and fingerprint data.

    Args:
        url: Target website URL
        site : Domain name of targeted site (any unique str)
        output_filepath: Path to save session JSON file
    """

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        context = browser.new_context(
            viewport={"width": 1920, "height": 1080},
            user_agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
        )
        page = context.new_page()

        # Navigate to site
        page.goto(url)
        logging.info(f"Login into site: {url}")
        logging.info("After log in press enter.")
        input("Press enter after logging in")

        session_data = {
            #  base_url
            "base_url": url,
            # website subdomain
            "site": site,
            # cookies
            "cookies": context.cookies(),
            # localStorage
            "localStorage": page.evaluate(
                """
                () => {
                    let items = {};
                    for (let i = 0; i < localStorage.length; i++) {
                        let key = localStorage.key(i);
                        items[key] = localStorage.getItem(key);
                    }
                    return items;
                }
            """
            ),
            # Session Storage
            "sessionStorage": page.evaluate(
                """
                () => {
                    let items = {};
                    for (let i = 0; i < sessionStorage.length; i++) {
                        let key = sessionStorage.key(i);
                        items[key] = sessionStorage.getItem(key);
                    }
                    return items;
                }
            """
            ),
            # Browser Fingerprint
            # TODO: Varify all properties (Due to it is generated by AI)
            "fingerprint": page.evaluate(
                """
                () => {
                    return {
                        userAgent: navigator.userAgent,
                        platform: navigator.platform,
                        language: navigator.language,
                        languages: navigator.languages,
                        hardwareConcurrency: navigator.hardwareConcurrency,
                        deviceMemory: navigator.deviceMemory,
                        screenResolution: {
                            width: screen.width,
                            height: screen.height,
                            colorDepth: screen.colorDepth
                        },
                        timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
                        timezoneOffset: new Date().getTimezoneOffset(),
                        webglVendor: (() => {
                            try {
                                const canvas = document.createElement('canvas');
                                const gl = canvas.getContext('webgl');
                                const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
                                return gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
                            } catch(e) { return null; }
                        })(),
                        webglRenderer: (() => {
                            try {
                                const canvas = document.createElement('canvas');
                                const gl = canvas.getContext('webgl');
                                const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
                                return gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
                            } catch(e) { return null; }
                        })(),
                        canvasFingerprint: (() => {
                            try {
                                const canvas = document.createElement('canvas');
                                const ctx = canvas.getContext('2d');
                                ctx.textBaseline = 'top';
                                ctx.font = '14px Arial';
                                ctx.fillText('Browser fingerprint', 2, 2);
                                return canvas.toDataURL();
                            } catch(e) { return null; }
                        })()
                    };
                }
            """
            ),
        }
        try:
            session_data = Session(**session_data).model_dump_json(indent=2)
            with open(output_filepath, "w") as f:
                f.write(session_data)
            logging.info(
                "Successfully extracted and saved data to the output JSON file"
            )
        except Exception as e:
            logging.error(f"Failed to save session: {e}")
            raise

        finally:
            browser.close()


def main():
    logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--url", required=True, help="Url for which session data we want to extract"
    )
    parser.add_argument(
        "--site", required=True, help="Domain name of targeted site (any Unique string)"
    )
    parser.add_argument(
        "--output",
        required=True,
        help="output filepath where you want to save session data int file",
    )
    args = parser.parse_args()
    extract_and_save_session(url=args.url, site=args.site, output_filepath=args.output)


if __name__ == "__main__":
    main()
