#!/usr/bin/env python3
import argparse
import logging
import os
import sys
import time

# Ensure GramAddict is in PYTHONPATH if script is run directly
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from GramAddict.core.device_facade import create_device

# Setup a clean logger for the toolkit
logging.basicConfig(level=logging.INFO, format="[%(asctime)s] %(levelname)s | %(message)s", datefmt="%H:%M:%S")
logger = logging.getLogger("TestingToolkit")


def _save_dump(device, fixture_dir, filename, description):
    logger.info(f"⏳ Waiting for UI to settle for [{description}]...")
    time.sleep(3.5)  # ensure animations finish

    xml_data = device.dump_hierarchy()
    if not xml_data or len(xml_data) < 100:
        logger.warning(f"⚠️ Received empty or exceptionally small XML dump for {filename}. Is the app open?")

    path = os.path.join(fixture_dir, filename)
    with open(path, "w", encoding="utf-8") as f:
        f.write(xml_data)
    logger.info(f"✅ Saved REAL DUMP to {filename} ({len(xml_data)} bytes)")

    # Capture screenshot
    try:
        import base64

        screenshot_b64 = device.get_screenshot_b64()
        if screenshot_b64:
            screenshot_data = base64.b64decode(screenshot_b64)
            screenshot_filename = filename.replace(".xml", ".jpg")
            screenshot_path = os.path.join(fixture_dir, screenshot_filename)
            with open(screenshot_path, "wb") as f:
                f.write(screenshot_data)
            logger.info(f"✅ Saved REAL SCREENSHOT to {screenshot_filename}")
        else:
            logger.warning(f"⚠️ Failed to capture screenshot for {filename}")
    except Exception as e:
        logger.error(f"Failed to capture screenshot: {e}")


def run_interactive_guide(device, fixture_dir):
    print("\n" + "=" * 60)
    print("🤖 AUTOMATED E2E DUMP CAPTURE GUIDE")
    print("=" * 60)
    print("This guide will help you refresh the golden fixtures for the E2E suite.")
    print("Please follow the instructions on your phone/emulator.")
    print("=" * 60 + "\n")

    steps = [
        ("comment_sheet.xml", "Post Comment Sheet", "Open any post and open its comment section."),
        ("stories_feed_dump.xml", "Active Story Playback", "Tap any user's story ring on the HomeFeed."),
        ("dm_inbox_dump.xml", "DM Inbox / Threads List", "Go to your DM inbox list."),
        ("scraping_profile_dump.xml", "Own Profile Root", "Go to your OWN profile tab."),
        ("unfollow_list_dump.xml", "Following List", "On your profile, tap 'Following' to open the list."),
        ("search_feed_dump.xml", "Explore Search Focus", "Tap Explore, then tap into the Search bar."),
        ("reels_feed_dump.xml", "Reels Video Feed", "Go to the Reels tab and let a video play."),
        ("notifications_dump.xml", "Activity Feed", "Tap the Heart/Notifications icon."),
        ("explore_feed_dump.xml", "Explore Grid", "Tap the Explore tab (just the grid visible)."),
        ("user_profile_dump.xml", "Alien Profile Root", "Go to ANY OTHER user's profile."),
        ("followers_list_dump.xml", "Followers List", "On that user's profile, tap 'Followers'."),
        ("carousel_post_dump.xml", "Carousel Post", "Find a post with multiple images on your feed."),
        ("home_feed_with_ad.xml", "Sponsored Ad", "Scroll until you see a 'Sponsored' post."),
        ("dm_thread_dump.xml", "DM Chat Thread", "Open any specific chat conversation."),
    ]

    for i, (fname, desc, instr) in enumerate(steps, 1):
        try:
            print(f"\n👉 {i}/{len(steps)}. {desc.upper()}:")
            print(f"   {instr}")
            input("   Press ENTER when ready to capture...")
            _save_dump(device, fixture_dir, fname, desc)
        except KeyboardInterrupt:
            print("\n🛑 Guide interrupted.")
            return

    print("\n" + "=" * 60)
    logger.info("🎉 Capture Sequence Complete! All fixtures have been updated.")
    print("=" * 60 + "\n")


def main():
    parser = argparse.ArgumentParser(description="Instagram Bot Testing Toolkit - Fixture Management")
    parser.add_argument("--config", help="Path to your bot's .yml config (to auto-extract device ID)")
    parser.add_argument("--device", help="Manual ADB device ID (e.g., emulator-5554)")
    parser.add_argument("--fixture", help="Name of a single fixture to sync (e.g., explore_feed_dump.xml)")
    parser.add_argument("--interactive", action="store_true", help="Launch the full interactive capture guide")
    args = parser.parse_args()

    device_id = args.device

    # Auto-detect config if not provided
    if not args.config:
        if os.path.exists("test_config.yml"):
            args.config = "test_config.yml"
        elif os.path.exists("config.yml"):
            args.config = "config.yml"

    # Try to extract device from config if provided
    if args.config:
        try:
            import yaml

            with open(args.config, "r", encoding="utf-8") as f:
                config_data = yaml.safe_load(f)
            device_id = config_data.get("device") or device_id
            logger.info(f"Loaded device ID from config: {device_id}")
        except Exception as e:
            logger.warning(f"Could not read config file {args.config}: {e}")

    if not device_id:
        logger.error("No device ID provided! Use --device or --config to specify which device to connect to.")
        sys.exit(1)

    fixture_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "tests", "fixtures")
    os.makedirs(fixture_dir, exist_ok=True)

    print(f"Connecting to {device_id}...")
    try:
        device = create_device(device_id, "com.instagram.android")
        # Quick connectivity check
        device.get_info()
    except Exception as e:
        logger.error(f"Failed to connect to device: {e}")
        sys.exit(1)

    if args.interactive:
        run_interactive_guide(device, fixture_dir)
    elif args.fixture:
        fname = args.fixture
        if not fname.endswith(".xml"):
            fname += ".xml"
        _save_dump(device, fixture_dir, fname, f"Single Fixture: {fname}")
    else:
        logger.info("Nothing to do. Use --interactive or --fixture <name>.")
        parser.print_help()


if __name__ == "__main__":
    main()
