from playwright.sync_api import sync_playwright
import os
from dotenv import load_dotenv
from pathlib import Path

def ensure_state_folder():
    """Create state folder if it doesn't exist"""
    state_folder = Path("state")
    state_folder.mkdir(exist_ok=True)
    return state_folder

def get_state_path():
    """Get the full path to the login state file"""
    return Path("state/login_state.json")

def login_and_save_state(username, password, phone_or_email, storage_path=None):
    if storage_path is None:
        storage_path = get_state_path()
    
    with sync_playwright() as p:
        # Ensure state folder exists
        ensure_state_folder()

        # If we already have a state file, we can return True
        if storage_path.exists():
            print(f"[api_free_connector] - {storage_path} exists. Using existing state.")
            return True

        browser = p.chromium.launch(headless=False, slow_mo=1000)
        context = browser.new_context()
        page = context.new_page()

        # 1) Navigate to login
        page.goto("https://x.com/login")
        page.wait_for_timeout(1000)

        # 2) Fill in username
        page.wait_for_selector('input[name="text"]', timeout=10000)
        page.fill('input[name="text"]', username)
        page.keyboard.press("Enter")     

        try:
            # Attempt normal login flow
            page.wait_for_selector('input[name="password"]', timeout=5000)  # reduced from 10000
            page.fill('input[name="password"]', password)
            page.keyboard.press("Enter")

            # Wait for successful login
            page.wait_for_url(lambda url: "home" in url, timeout=5000)
            print("[api_free_connector] - Logged in successfully through normal flow.")

        except:
            print(f"[api_free_connector] - Normal login failed: Checking for unusual activity...")

            try:
                # Check for unusual activity challenge
                page.wait_for_selector('input[data-testid="ocfEnterTextTextInput"]', timeout=3000)

                # Fill in phone or username
                page.fill('input[data-testid="ocfEnterTextTextInput"]', phone_or_email)
                page.keyboard.press("Enter")
                page.wait_for_load_state("networkidle")

                # Enter password again after challenge
                page.wait_for_selector('input[name="password"]', timeout=5000)
                page.fill('input[name="password"]', password)
                page.keyboard.press("Enter")

                # Wait for successful login after challenge
                page.wait_for_url(lambda url: "home" in url, timeout=5000)
                print("[api_free_connector] -  Logged in successfully after challenge.")

            except:
                print("[api_free_connector] - Error: Login failed - unusual activity flow could not be completed.")
                browser.close()
                return False

        # Save the current browser context's storage state to a file
        context.storage_state(path=str(storage_path))
        print(f"[api_free_connector] - Storage state saved to {storage_path}.")

        browser.close()
        return True

def post_tweet_with_saved_state(tweet_text, storage_path=None):
    if storage_path is None:
        storage_path = get_state_path()
        
    with sync_playwright() as p:
        # Create a new context with the previously saved state
        browser = p.chromium.launch(headless=False)
        context = browser.new_context(storage_state=str(storage_path))
        page = context.new_page()

        # Now page is already logged in if state.json is still valid
        page.goto("https://x.com/home")
        # Post a tweet
        tweet_box_selector = 'div[data-testid="tweetTextarea_0"]'
        page.wait_for_selector(tweet_box_selector, timeout=10000)
        page.fill(tweet_box_selector, tweet_text)

        # post_button_selector = 'div[data-testid="tweetButtonInline"]'
        post_button_selector = 'button[data-testid="tweetButtonInline"]'
        # page.wait_for_selector(post_button_selector, state="visible", timeout=20000)  # Wait for visible

        page.wait_for_selector(post_button_selector, timeout=10000)
        page.click(post_button_selector)
        page.wait_for_timeout(3000)
        print(f"[Twitter API Free Connector] - Tweet posted: {tweet_text}")

        browser.close()
        return True

if __name__ == "__main__":
    """
    Example usage. Replace the placeholders with your real credentials.
    'phone_or_username' is used if the suspicious activity screen appears
    asking you to confirm via phone or username.
    """
    load_dotenv()
    
    # Test post
    X_POST_TEXT = "Hello"

    # Ensure state folder exists and get state file path
    state_path = get_state_path()

    # check if login state exists
    if state_path.exists():
        print(f"[INFO] {state_path} exists. Using existing state.")
    else:
        print(f"[INFO] {state_path} does not exist. Logging in and saving state.")
        login_and_save_state(
            username=os.getenv("X_USERNAME"),
            password=os.getenv("X_PASSWORD"),
            phone_or_email=os.getenv("X_PHONE_OR_EMAIL"),
            storage_path=state_path
        )

    post_tweet_with_saved_state(
        tweet_text=X_POST_TEXT,
        storage_path=state_path
    )
