import sys
import os
import random
import time
import requests
import json
import threading
import re
import string
import zipfile
import shutil
import platform
import subprocess
from datetime import datetime
from unidecode import unidecode
from bs4 import BeautifulSoup

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver import ActionChains
from selenium.webdriver.support.select import Select

from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.core.os_manager import ChromeType

from rich.console import Console
from rich.panel import Panel
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn, TaskProgressColumn
from rich.table import Table
from rich.prompt import Prompt, Confirm
from rich.live import Live
from rich.text import Text

# Configuration directories
CONFIG_DIR = 'config'
DATA_DIR = 'data'

# Try to import config
try:
    sys.path.insert(0, CONFIG_DIR)
    from config import YOUR_BIRTHDAY, YOUR_GENDER, YOUR_PASSWORD, FIVESIM_API_KEY, FIVESIM_COUNTRY, FIVESIM_OPERATOR, USE_ARABIC_NAMES, NAMES_FILE
except ImportError:
    YOUR_BIRTHDAY = '2 4 1950'
    YOUR_GENDER = '1'
    YOUR_PASSWORD = ''
    FIVESIM_API_KEY = ''
    FIVESIM_COUNTRY = 'usa'
    FIVESIM_OPERATOR = 'any'
    USE_ARABIC_NAMES = True
    NAMES_FILE = os.path.join(DATA_DIR, 'names.txt')

# Load password from file if not in config
if not YOUR_PASSWORD:
    try:
        password_file = os.path.join(CONFIG_DIR, 'password.txt')
        with open(password_file, 'r', encoding='utf-8') as f:
            your_password = f.read().strip()
    except FileNotFoundError:
        print('Error: config/password.txt file not found! Please create it.')
        your_password = ''
else:
    your_password = YOUR_PASSWORD

# Load 5sim API key from file if not in config
if not FIVESIM_API_KEY:
    try:
        fivesim_file = os.path.join(CONFIG_DIR, '5sim_config.txt')
        with open(fivesim_file, 'r', encoding='utf-8') as f:
            FIVESIM_API_KEY = f.read().strip()
    except FileNotFoundError:
        FIVESIM_API_KEY = ''

your_birthday = YOUR_BIRTHDAY
your_gender = YOUR_GENDER

console = Console()

CONFIG = {
    'version': '2.0.0',
    'theme_color': 'cyan',
    'secondary_color': 'magenta',
    'success_color': 'green',
    'error_color': 'red',
    'warning_color': 'yellow'
}


def load_user_agents():
    """Load user agents from config/user_agents.txt file"""
    user_agents_list = []
    try:
        user_agents_file = os.path.join(CONFIG_DIR, 'user_agents.txt')
        with open(user_agents_file, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                if line:
                    user_agents_list.append(line)
        return user_agents_list if user_agents_list else get_default_user_agents()
    except FileNotFoundError:
        return get_default_user_agents()


def get_default_user_agents():
    """Default user agents fallback"""
    return [
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
    ]


user_agents = load_user_agents()


def load_names_from_file():
    """Load names from names.txt file"""
    names_list = []
    try:
        names_file = NAMES_FILE if os.path.exists(NAMES_FILE) else os.path.join(DATA_DIR, 'names.txt')
        with open(names_file, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                if line:
                    names_list.append(line)
        return names_list
    except FileNotFoundError:
        return []


names_list = load_names_from_file()
arabic_first_names = []
arabic_last_names = []


def get_matrix_animation():
    """Matrix-style code rain animation frames"""
    frames = []
    chars = '01█▓▒░'
    for i in range(4):
        frame = ''
        for _ in range(3):
            line = ''.join([random.choice(chars) for _ in range(40)])
            frame += f'[{CONFIG["success_color"]}]{line}[/]\n'
        frames.append(frame)
    return frames


def show_beautiful_banner():
    """Display a beautiful banner with animations"""
    banner = f'''
[{CONFIG["theme_color"]}]
██████╗ ███╗   ███╗ █████╗ ██╗██╗         ██████╗██████╗ ███████╗ █████╗ ████████╗ ██████╗ ██████╗ 
██╔════╝████╗ ████║██╔══██╗██║██║        ██╔════╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗
██║  ███╗██╔████╔██║███████║██║██║        ██║     ██████╔╝█████╗  ███████║   ██║   ██║   ██║██████╔╝
██║   ██║██║╚██╔╝██║██╔══██║██║██║        ██║     ██╔══██╗██╔══╝  ██╔══██║   ██║   ██║   ██║██╔══██╗
╚██████╔╝██║ ╚═╝ ██║██║  ██║██║███████╗   ╚██████╗██║  ██║███████╗██║  ██║   ██║   ╚██████╔╝██║  ██║
 ╚═════╝ ╚═╝     ╚═╝╚═╝  ╚═╝╚═╝╚══════╝    ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝   ╚═╝    ╚═════╝ ╚═╝  ╚═╝
[/]

[{CONFIG["secondary_color"]}]✨ The Ultimate Gmail Account Creator v{CONFIG["version"]} ✨[/]
'''
    
    feature_text = [
        '🚀 Advanced Anti-Detection System',
        '🔒 Phone Verification Bypass',
        '🌐 Smart Proxy Integration',
        '🎨 Beautiful Modern Interface',
        '📊 Detailed Statistics',
        '💾 Auto-Save Accounts',
        '🔄 Auto-Retry on Failure',
        '⚡ Lightning Fast Creation'
    ]
    
    copyright_info = f'''
[{CONFIG["warning_color"]}]━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[/]
[{CONFIG["theme_color"]}]© 2025 Shadow Hacker - All Rights Reserved[/]
[{CONFIG["secondary_color"]}]🌐 Website: https://www.shadowhackr.com[/]
[{CONFIG["secondary_color"]}]📘 Facebook: www.facebook.com/ShadowHackr[/]
[{CONFIG["secondary_color"]}]📱 WhatsApp: +962796668987[/]
[{CONFIG["warning_color"]}]━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[/]
'''
    
    features_str = '\n'.join(feature_text)
    console.print(Panel(
        f'{banner}\n\n{features_str}\n{copyright_info}',
        border_style=CONFIG["theme_color"],
        padding=(1, 2),
        title='[bold]Welcome to Gmail Creator Pro[/]',
        subtitle='[bold]By SHADOWHACKER[/]'
    ))


def show_beautiful_menu():
    """Display a beautiful menu with animations"""
    menu_items = [
        ('1', 'Create Gmail Accounts', '🚀 Start creating new Gmail accounts automatically'),
        ('2', 'View Statistics', '📊 View detailed creation statistics and success rates'),
        ('3', 'Settings', '⚙️ Configure proxy, user agents, and other settings'),
        ('4', 'View Saved Accounts', '📁 View all created accounts and their details'),
        ('5', 'Exit', '👋 Exit the application')
    ]
    
    table = Table(show_header=True, header_style="bold cyan")
    table.add_column("Option", style="cyan", width=8)
    table.add_column("Action", style="magenta", width=25)
    table.add_column("Description", style="green")
    
    for option, action, desc in menu_items:
        table.add_row(option, action, desc)
    
    console.print("\n")
    console.print(table)
    console.print("\n")


def save_account(email, password):
    """Save account details safely (handles empty or broken JSON)"""
    try:
        accounts_file = os.path.join(DATA_DIR, 'accounts.json')
        os.makedirs(DATA_DIR, exist_ok=True)

        accounts = []

        if os.path.exists(accounts_file):
            try:
                with open(accounts_file, 'r', encoding='utf-8') as f:
                    content = f.read().strip()
                    if content:
                        accounts = json.loads(content)
            except Exception:
                accounts = []

        accounts.append({
            'email': email,
            'password': password,
            'created_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'status': 'active'
        })

        with open(accounts_file, 'w', encoding='utf-8') as f:
            json.dump(accounts, f, indent=4, ensure_ascii=False)

        console.print(
            f'[{CONFIG["success_color"]}]✓ Account saved successfully![/]'
        )

    except Exception as e:
        console.print(
            f'[{CONFIG["error_color"]}]Error saving account: {str(e)}[/]'
        )



def view_statistics():
    """Show beautiful statistics dashboard"""
    try:
        accounts_file = os.path.join(DATA_DIR, 'accounts.json')
        with open(accounts_file, 'r') as f:
            accounts = json.load(f)
        
        total = len(accounts)
        active = sum(1 for acc in accounts if acc['status'] == 'active')
        success_rate = (active / total * 100) if total > 0 else 0
        
        stats_table = Table(
            title=f'[{CONFIG["theme_color"]}]Account Creation Statistics[/]',
            show_header=True,
            header_style='bold'
        )
        stats_table.add_column('Metric', style=CONFIG["theme_color"])
        stats_table.add_column('Value', justify='right', style=CONFIG["success_color"])
        
        stats_table.add_row('Total Accounts Created', str(total))
        stats_table.add_row('Active Accounts', str(active))
        stats_table.add_row('Success Rate', f'{success_rate:.1f}%')
        stats_table.add_row('Last Creation', accounts[-1]['created_at'] if accounts else 'N/A')
        
        console.print(Panel(stats_table, border_style=CONFIG["theme_color"]))
    except Exception as e:
        console.print(f'[{CONFIG["error_color"]}]Error loading statistics: {str(e)}[/]')


def human_typing(element, text, delay_range=(0.1, 0.3)):
    """Simulate human typing"""
    for char in text:
        element.send_keys(char)
        time.sleep(random.uniform(*delay_range))


def human_click(driver, element):
    """Simulate human click"""
    actions = ActionChains(driver)
    actions.move_to_element(element).pause(random.uniform(0.2, 0.5)).click().perform()
    time.sleep(random.uniform(0.5, 1.2))


def warm_up_session(driver):
    """Warm up browsing session to appear more human-like"""
    print('🔥 Warming up browsing session...')
    try:
        driver.get('https://www.google.com/')
        time.sleep(random.uniform(5, 8))
        
        search_box = driver.find_element(By.NAME, 'q')
        queries = ['today weather', 'sports news', 'dream interpretation', 'currency rates', 
                   'best movies 2025', 'how to bake bread', 'tech news 2025']
        query = random.choice(queries)
        search_box.send_keys(query)
        search_box.submit()
        print(f'🔍 Searched: {query}')
        time.sleep(random.uniform(6, 10))
        
        links = driver.find_elements(By.XPATH, '//h3')
        if links:
            random.choice(links).click()
            print('🌐 Browsed first result...')
            time.sleep(random.uniform(8, 12))
        
        driver.get('https://www.bbc.com/')
        time.sleep(random.uniform(6, 10))
        
        driver.get('https://www.wikipedia.org/')
        time.sleep(random.uniform(6, 10))
        
        driver.get('https://www.google.com/maps')
        print('🗺️ Opened Google Maps...')
        time.sleep(random.uniform(5, 8))
        
        driver.get('https://www.youtube.com/watch?v=dQw4w9WgXcQ')
        print('🎬 Watching YouTube video...')
        time.sleep(random.uniform(15, 25))
        
        print('✅ Session warmed up!')
    except Exception as e:
        print(f'⚠️ Error warming session: {e}')


def try_set_gender(driver, gender_values):
    """Try to set gender using multiple methods"""
    for value in gender_values:
        try:
            gender_elem = driver.find_element(By.CSS_SELECTOR, 'select#gender, select[aria-label="Gender"]')
            select = Select(gender_elem)
            select.select_by_value(value)
            
            if gender_elem.get_attribute('value') == value or gender_elem.get_attribute('value').lower() == value.lower():
                return True
            
            # Try JavaScript method
            driver.execute_script('''
                let genderSelect = document.querySelector('select#gender') || 
                                     document.querySelector('select[aria-label="Gender"]');
                if (genderSelect) {
                    genderSelect.value = arguments[0];
                    genderSelect.dispatchEvent(new Event('change', { bubbles: true }));
                }
            ''', value)
            
            result = driver.execute_script('''
                let genderSelect = document.querySelector('select#gender') || 
                                     document.querySelector('select[aria-label="Gender"]');
                return genderSelect ? genderSelect.value : null;
            ''')
            
            if result and (result == value or result.lower() == value.lower()):
                return True
                
            # Try visible text
            select.select_by_visible_text(value)
            return True
        except Exception:
            continue
    
    return False


def try_set_month(driver, month_values):
    """Try to set month using multiple methods"""
    for value in month_values:
        try:
            month_elem = driver.find_element(By.CSS_SELECTOR, 'select#month, select[aria-label="Month"], select[name="month"]')
            select = Select(month_elem)
            select.select_by_value(value)
            
            if month_elem.get_attribute('value') == value or month_elem.get_attribute('value').lower() == value.lower():
                return True
            
            # Try JavaScript method
            driver.execute_script('''
                function setMonthValue(value) {
                    let monthSelect = document.querySelector('select#month') || 
                                      document.querySelector('select[aria-label="Month"]') ||
                                      document.querySelector('select[name="month"]');
                    if (monthSelect) {
                        monthSelect.value = arguments[0];
                        monthSelect.dispatchEvent(new Event('change', { bubbles: true }));
                        for (let i = 0; i < monthSelect.options.length; i++) {
                            if (monthSelect.options[i].value === arguments[0]) {
                                monthSelect.selectedIndex = i;
                                break;
                            }
                        }
                        monthSelect.dispatchEvent(new Event('input', { bubbles: true }));
                        monthSelect.dispatchEvent(new Event('change', { bubbles: true }));
                    }
                }
                setMonthValue(arguments[0]);
            ''', value)
            
            result = driver.execute_script('''
                let monthSelect = document.querySelector('select#month') || 
                                      document.querySelector('select[aria-label="Month"]') ||
                                      document.querySelector('select[name="month"]');
                return monthSelect ? monthSelect.value : null;
            ''')
            
            if result and (result == value or result.lower() == value.lower()):
                return True
                
            # Try visible text
            select.select_by_visible_text(value)
            return True
        except Exception:
            continue
    
    return False


def try_click_month_dropdown(driver, month_name):
    """Try to click month from dropdown"""
    try:
        month_dropdown = driver.find_element(By.XPATH, '//*[@id="month"]/div/div[1]/div')
        month_dropdown.click()
        time.sleep(1)
        
        options = driver.find_elements(By.XPATH, '//*[@id="month"]/div/div[2]/ul/li')
        for option in options:
            if month_name.strip().lower() in option.text.strip().lower():
                option.click()
                return True
        return False
    except Exception:
        return False


def try_click_gender_dropdown(driver, gender_text):
    """Try to click gender from dropdown"""
    try:
        gender_dropdown = driver.find_element(By.XPATH, '//*[@id="gender"]/div/div[1]/div')
        gender_dropdown.click()
        time.sleep(1)
        
        options = driver.find_elements(By.XPATH, '//*[@id="gender"]/div/div[2]/ul/li')
        for option in options:
            if gender_text.strip().lower() in option.text.strip().lower():
                option.click()
                return True
        return False
    except Exception:
        return False


def update_progress_with_animation(progress, task_id, message, percentage):
    """Update progress with smooth animation"""
    current = progress.tasks[task_id].completed
    steps = 10
    step_size = (percentage - current) / steps
    
    for i in range(steps):
        new_percentage = current + step_size * (i + 1)
        progress.update(task_id, description=f'[{CONFIG["theme_color"]}]{message}...[/]', completed=new_percentage)
        time.sleep(0.05)


def validate_birthday(birthday_str):
    """Validate and parse birthday string"""
    try:
        parts = birthday_str.split()
        month, day, year = parts[0], parts[1], parts[2]
        
        if not 1 <= int(month) <= 12:
            month = '1'
        if not 1 <= int(day) <= 31:
            day = '1'
        if not 1900 <= int(year) <= 2010:
            year = '1990'
        
        return (month, day, year)
    except Exception:
        return ('1', '1', '1990')


def generate_realistic_name():
    """Generate names from external file only - NO fallback"""
    if names_list:
        full_name = random.choice(names_list)
        return full_name
    else:
        print('Error: names.txt is empty or not found! Please add names to names.txt')
        return f'User{random.randint(1000, 9999)}'


def bypass_phone_verification(driver, wait):
    """Enhanced phone verification bypass with multiple strategies"""
    console.print(f'[{CONFIG["warning_color"]}]Attempting to skip phone verification...[/]')
    
    skip_button_selectors = [
        '//button[contains(text(), "Skip")]',
        '//button[contains(text(), "تخطي")]',
        '//span[contains(text(), "Skip")]',
        '//span[contains(text(), "تخطي")]',
        '//div[contains(text(), "Skip")]',
        '//div[contains(text(), "تخطي")]',
        '//button[@aria-label="Skip"]',
        '//button[contains(@class, "VfPpkd-LgbsSe") and contains(text(), "Skip")]'
    ]
    
    for selector in skip_button_selectors:
        try:
            skip_button = WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, selector)))
            driver.execute_script('arguments[0].click();', skip_button)
            time.sleep(2)
            console.print(f'[{CONFIG["success_color"]}]✓ Skipped phone verification![/]')
            return True
        except Exception:
            continue
    
    # Try alternative methods
    alternative_selectors = [
        '//button[contains(text(), "Try another way")]',
        '//button[contains(text(), "Try a different way")]',
        '//span[contains(text(), "Try another way")]',
        '//div[contains(text(), "Try another way")]'
    ]
    
    for selector in alternative_selectors:
        try:
            alternative_button = WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, selector)))
            driver.execute_script('arguments[0].click();', alternative_button)
            time.sleep(2)
            
            skip_options = [
                '//div[contains(text(), "Skip")]',
                '//button[contains(text(), "Skip")]',
                '//span[contains(text(), "Skip")]'
            ]
            
            for skip_sel in skip_options:
                try:
                    skip_btn = driver.find_element(By.XPATH, skip_sel)
                    if skip_btn.is_displayed():
                        driver.execute_script('arguments[0].click();', skip_btn)
                        time.sleep(2)
                        console.print(f'[{CONFIG["success_color"]}]✓ Skipped via alternative method![/]')
                        return True
                except Exception:
                    continue
        except Exception:
            continue
    
    # Try close buttons
    close_selectors = [
        '//button[@aria-label="Close"]',
        '//button[contains(@class, "close")]',
        '//button[contains(@aria-label, "Back")]'
    ]
    
    for selector in close_selectors:
        try:
            close_btn = driver.find_element(By.XPATH, selector)
            if close_btn.is_displayed():
                driver.execute_script('arguments[0].click();', close_btn)
                time.sleep(2)
                return True
        except Exception:
            continue
    
    return False


def get_5sim_phone_number():
    """Get phone number from 5sim API"""
    if not FIVESIM_API_KEY:
        console.print(f'[{CONFIG["error_color"]}]5sim API key not configured![/]')
        return None
    
    try:
        url = f'https://5sim.net/v1/user/buy/activation/{FIVESIM_COUNTRY}/{FIVESIM_OPERATOR}/google'
        headers = {
            'Authorization': f'Bearer {FIVESIM_API_KEY}',
            'Accept': 'application/json'
        }
        
        response = requests.get(url, headers=headers, timeout=10)
        
        if response.status_code == 200:
            data = response.json()
            phone_number = data.get('phone')
            order_id = data.get('id')
            
            if phone_number:
                console.print(f'[{CONFIG["success_color"]}]✓ Got phone number from 5sim: {phone_number}[/]')
                return {
                    'phone': phone_number,
                    'order_id': order_id,
                    'service': '5sim'
                }
        
        console.print(f'[{CONFIG["error_color"]}]5sim API error: {response.status_code} - {response.text}[/]')
        return None
    except Exception as e:
        console.print(f'[{CONFIG["error_color"]}]Error getting 5sim number: {str(e)}[/]')
        return None


def get_5sim_verification_code(order_id, max_wait=120):
    """Get verification code from 5sim API"""
    if not FIVESIM_API_KEY or not order_id:
        return None
    
    url = f'https://5sim.net/v1/user/check/{order_id}'
    headers = {
        'Authorization': f'Bearer {FIVESIM_API_KEY}',
        'Accept': 'application/json'
    }
    
    start_time = time.time()
    
    while time.time() - start_time < max_wait:
        try:
            response = requests.get(url, headers=headers, timeout=10)
            
            if response.status_code == 200:
                data = response.json()
                sms = data.get('sms')
                
                if sms and len(sms) > 0:
                    latest_sms = sms[0]
                    code_text = latest_sms.get('text', '')
                    
                    # Extract 6-digit code
                    code_match = re.search(r'\b\d{6}\b', code_text)
                    if code_match:
                        code = code_match.group()
                        console.print(f'[{CONFIG["success_color"]}]✓ Got verification code: {code}[/]')
                        return code
                    
                    # Fallback: extract any digits
                    code_match = re.search(r'\d+', code_text)
                    if code_match:
                        code = code_match.group()[:6]
                        console.print(f'[{CONFIG["success_color"]}]✓ Got verification code: {code}[/]')
                        return code
            
            time.sleep(3)
        except Exception as e:
            console.print(f'[{CONFIG["error_color"]}]Error getting 5sim code: {str(e)}[/]')
            time.sleep(3)
    
    return None


def get_temp_phone_number():
    """Get temporary phone number from multiple services (5sim preferred)"""
    if FIVESIM_API_KEY:
        phone_data = get_5sim_phone_number()
        if phone_data:
            return phone_data
    
    console.print(f'[{CONFIG["warning_color"]}]No phone service available. Please configure 5sim API key.[/]')
    return None


def get_verification_code_smart(phone_data=None):
    """Get verification code with smart retry"""
    if phone_data and phone_data.get('service') == '5sim':
        return get_5sim_verification_code(phone_data.get('order_id'))
    
    # Fallback - wait for manual entry
    max_retries = 5
    for attempt in range(max_retries):
        try:
            time.sleep(5)
        except Exception:
            time.sleep(2)
    
    return None

def is_qr_verification_present(driver):
    """Detect Google QR verification screen"""
    qr_xpaths = [
        '//img[contains(@src, "qr")]',
        '//div[contains(text(), "Scan")]',
        '//div[contains(text(), "scan")]',
        '//h1[contains(text(), "Scan")]',
        '//h1[contains(text(), "Use your phone")]'
    ]
    for xp in qr_xpaths:
        try:
            driver.find_element(By.XPATH, xp)
            return True
        except Exception:
            continue
    return False

def handle_verification_smart(driver, wait, progress):
    """Smart phone / QR verification handler"""
    update_progress_with_animation(
        progress,
        progress.tasks[0].id,
        'Handling phone verification',
        85
    )

    # Detect phone verification
    try:
        driver.find_element(By.NAME, 'phoneNumberId')
        phone_required = True
    except Exception:
        phone_required = False

    # No phone → check QR
    if not phone_required:
        if is_qr_verification_present(driver):
            console.print(
                f'[{CONFIG["warning_color"]}]QR verification required – aborting[/]'
            )
        console.print(
            f'[{CONFIG["warning_color"]}]Waiting for manual QR scan (120s)...[/]'
        )
        time.sleep(120)
        return True


        console.print(
            f'[{CONFIG["success_color"]}]✓ No phone verification required[/]'
        )
        return True

    # Phone required
    console.print(
        f'[{CONFIG["warning_color"]}]Phone verification required[/]'
    )

    # SMS disabled → abort
    if SMS_PROVIDER is None:
        console.print(
            f'[{CONFIG["warning_color"]}]SMS provider disabled – skipping account creation[/]'
        )
        return "PHONE_REQUIRED"

    # SMS enabled (5sim)
    if SMS_PROVIDER == "5sim":
        phone_data = get_temp_phone_number()
        if not phone_data:
            console.print(
                f'[{CONFIG["error_color"]}]Could not get phone number – aborting[/]'
            )
            return False

        phone_number = phone_data.get('phone')

        phone_input = wait.until(
            EC.presence_of_element_located((By.NAME, 'phoneNumberId'))
        )
        phone_input.clear()
        time.sleep(0.5)
        human_typing(phone_input, phone_number)
        time.sleep(1)

        # Click Next
        next_button_selectors = [
            '//button[contains(text(), "Next")]',
            '//button[@type="submit"]',
            '//button[contains(@class, "VfPpkd-LgbsSe")]'
        ]

        for selector in next_button_selectors:
            try:
                btn = driver.find_element(By.XPATH, selector)
                if btn.is_displayed() and btn.is_enabled():
                    driver.execute_script('arguments[0].click();', btn)
                    break
            except Exception:
                continue

        time.sleep(3)
        return True

        # Wait for code input
        code_input = WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.NAME, 'code')))
        console.print(f'[{CONFIG["warning_color"]}]Waiting for verification code from 5sim...[/]')
        
        # Get verification code
        verification_code = get_verification_code_smart(phone_data)
        if not verification_code:
            console.print(f'[{CONFIG["error_color"]}]Could not get verification code. Trying manual skip...[/]')
            if bypass_phone_verification(driver, wait):
                return True
            return False
        
        # Enter verification code
        code_input.clear()
        time.sleep(0.5)
        human_typing(code_input, verification_code)
        time.sleep(1)
        
        # Click verify
        verify_button_selectors = [
            '//button[contains(text(), "Verify")]',
            '//button[contains(text(), "Next")]',
            '//button[@type="submit"]'
        ]
        
        for selector in verify_button_selectors:
            try:
                verify_btn = driver.find_element(By.XPATH, selector)
                if verify_btn.is_displayed() and verify_btn.is_enabled():
                    driver.execute_script('arguments[0].click();', verify_btn)
                    break
            except Exception:
                continue
        
        time.sleep(3)
        console.print(f'[{CONFIG["success_color"]}]✓ Phone verification completed![/]')
        return True
        

def safe_click(driver, element, retries=3):
    """Enhanced safe click with multiple methods"""
    for attempt in range(retries):
        try:
            # Method 1: JavaScript click
            driver.execute_script('arguments[0].click();', element)
            return True
        except Exception:
            try:
                # Method 2: ActionChains
                ActionChains(driver).move_to_element(element).click().perform()
                return True
            except Exception:
                try:
                    # Method 3: Regular click
                    element.click()
                    return True
                except Exception:
                    try:
                        # Method 4: Dispatch event
                        driver.execute_script('''
                            var event = new MouseEvent('click', {
                                'view': window,
                                'bubbles': true,
                                'cancelable': true
                            });
                            arguments[0].dispatchEvent(event);
                        ''', element)
                        return True
                    except Exception:
                        if attempt == retries - 1:
                            return False
                        time.sleep(1)
    
    return False


def create_account(driver, wait, progress, task_id, your_username, your_password):
    """Create Gmail account with all steps"""
    update_progress_with_animation(progress, task_id, 'Opening Gmail signup', 10)
    
    # Load signup page with retries
    max_retries = 3
    success = False
    
    for attempt in range(max_retries):
        try:
            driver.delete_all_cookies()
            driver.execute_script('window.localStorage.clear();')
            driver.execute_script('window.sessionStorage.clear();')
            
            driver.get('https://accounts.google.com/signup/v2/webcreateaccount?flowName=GlifWebSignIn&flowEntry=SignUp')
            wait.until(EC.presence_of_element_located((By.NAME, 'firstName')))
            success = True
            break
        except Exception as e:
            if attempt == max_retries - 1:
                raise Exception(f'Could not load signup page: {str(e)}')
            time.sleep(2)
            driver.refresh()
    
    if not success:
        raise Exception('Failed to load signup page after multiple attempts')
    
    time.sleep(2)
    
    # Fill first and last name
    first_name = generate_realistic_name()
    last_name = generate_realistic_name()
    
    driver.execute_script('''
        let firstNameField = document.querySelector('input[name="firstName"]');
        if (firstNameField) {
            firstNameField.value = arguments[0];
            firstNameField.dispatchEvent(new Event('input', { bubbles: true }));
            firstNameField.dispatchEvent(new Event('change', { bubbles: true }));
        }
    ''', first_name)
    
    driver.execute_script('''
        let lastNameField = document.querySelector('input[name="lastName"]');
        if (lastNameField) {
            lastNameField.value = arguments[0];
            lastNameField.dispatchEvent(new Event('input', { bubbles: true }));
            lastNameField.dispatchEvent(new Event('change', { bubbles: true }));
        }
    ''', last_name)
    
    time.sleep(1.5)
    
    # Click next
    driver.execute_script('''
        let nextButton = Array.from(document.querySelectorAll('button')).find(button => 
            button.textContent.toLowerCase().includes('next'));
        if (nextButton) nextButton.click();
    ''')
    
    time.sleep(3)
    
    # Fill birthday and gender
    month, day, year = validate_birthday(your_birthday)
    
    month_names = ['January', 'February', 'March', 'April', 'May', 'June', 
                   'July', 'August', 'September', 'October', 'November', 'December']
    
    month_values = [month, str(int(month))]
    if month.isdigit() and 1 <= int(month) <= 12:
        month_values.append(month_names[int(month) - 1])
    
    month_selected = try_set_month(driver, month_values)
    if not month_selected and month.isdigit() and 1 <= int(month) <= 12:
        try_click_month_dropdown(driver, month_names[int(month) - 1])
    
    time.sleep(2)
    
    # Fill day and year
    driver.execute_script('''
        // Fill day
        let dayField = document.querySelector('input[name="day"]');
        if (dayField) {
            dayField.value = arguments[0];
            dayField.dispatchEvent(new Event('input', { bubbles: true }));
            dayField.dispatchEvent(new Event('change', { bubbles: true }));
        }
        // Fill year
        let yearField = document.querySelector('input[name="year"]');
        if (yearField) {
            yearField.value = arguments[1];
            yearField.dispatchEvent(new Event('input', { bubbles: true }));
            yearField.dispatchEvent(new Event('change', { bubbles: true }));
        }
    ''', day, year)
    
    # Set gender
    gender_values = [your_gender, '1', '2', '3', 'MALE', 'FEMALE', 'OTHER', 'ذكر', 'أنثى', 'اخرى']
    gender_texts = ['Male', 'Female', 'Other', 'ذكر', 'أنثى', 'اخرى']
    
    gender_selected = try_set_gender(driver, gender_values)
    if not gender_selected:
        for gtext in gender_texts:
            if try_click_gender_dropdown(driver, gtext):
                break
    
    time.sleep(1)
    
    # Click next
    driver.execute_script('''
        function clickNext() {
            // Try multiple methods to find the next button
            let nextButton = Array.from(document.querySelectorAll('button')).find(button => 
                button.textContent.toLowerCase().includes('next')) ||
                document.querySelector('button[type="submit"]') ||
                document.querySelector('button.VfPpkd-LgbsSe');
            
            if (nextButton) {
                nextButton.click();
                return true;
            }
            return false;
        }
        return clickNext();
    ''')
    
    time.sleep(2)
    
    # Wait for email selection page
    heading_xpaths = [
        '//div[contains(text(), "Choose your Gmail address")]',
        '//div[contains(text(), "Create an email address")]',
        '//h1[contains(text(), "Create an email address")]',
        '//h1[contains(text(), "Choose your Gmail address")]'
    ]
    
    heading_found = False
    for hx in heading_xpaths:
        try:
            wait.until(EC.presence_of_element_located((By.XPATH, hx)))
            heading_found = True
            break
        except Exception:
            continue
    
    if not heading_found:
        raise Exception('Email-selection heading not found (UI text may have changed).')
    
    time.sleep(2)
    
    # Click "Create your own Gmail address"
    create_own_option = None
    xpath_selectors = [
        '//div[contains(text(), "Create your own Gmail address")]',
        '//span[contains(text(), "Create your own Gmail address")]',
        '//label[contains(text(), "Create your own Gmail address")]',
        '//div[contains(@class, "VfPpkd-StrnGf-rymPhb")]//span[contains(text(), "Create your own")]'
    ]
    
    for xpath in xpath_selectors:
        try:
            elements = driver.find_elements(By.XPATH, xpath)
            for element in elements:
                if element.is_displayed():
                    create_own_option = element
                    break
            if create_own_option:
                break
        except Exception:
            continue
    
    if create_own_option:
        driver.execute_script('arguments[0].scrollIntoView(true);', create_own_option)
        time.sleep(1)
        
        try:
            create_own_option.click()
        except Exception:
            try:
                # Try radio button
                radio_button = driver.find_element(By.XPATH, 
                    '//input[@type="radio" and following-sibling::*[contains(text(), "Create your own")]]')
                radio_button.click()
            except Exception:
                # Try JavaScript click
                driver.execute_script('arguments[0].click();', create_own_option)
        
        time.sleep(2)
        
        # Enter username
        username_field = None
        field_selectors = [
            '//input[@type="text"]',
            '//input[@name="Username"]',
            '//input[@jsname="YPqjbf"]',
            '//input[contains(@class, "whsOnd")]',
            '//input[contains(@class, "VfPpkd-fmcmS-wGMbrd")]'
        ]
        
        for selector in field_selectors:
            try:
                elements = driver.find_elements(By.XPATH, selector)
                for element in elements:
                    if element.is_displayed() and element.is_enabled():
                        username_field = element
                        break
                if username_field:
                    break
            except Exception:
                continue
        
        if username_field:
            username_field.clear()
            time.sleep(0.5)
            
            try:
                username_field.send_keys(your_username)
            except Exception:
                try:
                    driver.execute_script('arguments[0].value = arguments[1];', username_field, your_username)
                except Exception:
                    ActionChains(driver).move_to_element(username_field).click().send_keys(your_username).perform()
            
            time.sleep(1)
            
            # Click next
            next_button = None
            button_selectors = [
                '//button[contains(text(), "Next")]',
                '//button[contains(@class, "VfPpkd-LgbsSe")]',
                '//button[@type="submit"]'
            ]
            
            for selector in button_selectors:
                try:
                    elements = driver.find_elements(By.XPATH, selector)
                    for element in elements:
                        if element.is_displayed() and element.is_enabled():
                            next_button = element
                            break
                    if next_button:
                        break
                except Exception:
                    continue
            
            if next_button:
                driver.execute_script('arguments[0].scrollIntoView(true);', next_button)
                time.sleep(0.5)
                
                try:
                    next_button.click()
                except Exception:
                    try:
                        driver.execute_script('arguments[0].click();', next_button)
                    except Exception:
                        ActionChains(driver).move_to_element(next_button).click().perform()
                
                time.sleep(2)
        else:
            console.print(f'[{CONFIG["error_color"]}]Could not find username field[/]')
            return False
    else:
        console.print(f'[{CONFIG["error_color"]}]Could not find "Create your own Gmail address" option[/]')
        return False
    
    # Enter password
    update_progress_with_animation(progress, task_id, 'Entering password', 80)
    time.sleep(3)
    
    try:
        password_field = wait.until(EC.presence_of_element_located((By.NAME, 'Passwd')))
        confirm_field = wait.until(EC.presence_of_element_located((By.NAME, 'PasswdAgain')))
        
        wait.until(EC.element_to_be_clickable((By.NAME, 'Passwd')))
        wait.until(EC.element_to_be_clickable((By.NAME, 'PasswdAgain')))
        
        password_field.clear()
        confirm_field.clear()
        time.sleep(1)
        
        # Type password character by character
        password_field.click()
        for char in your_password:
            password_field.send_keys(char)
            time.sleep(0.05)
        
        time.sleep(1)
        
        confirm_field.click()
        for char in your_password:
            confirm_field.send_keys(char)
            time.sleep(0.05)
        
        time.sleep(1)
        
        # Verify password was entered
        if password_field.get_attribute('value') != your_password or confirm_field.get_attribute('value') != your_password:
            driver.execute_script('''
                arguments[0].value = arguments[2];
                arguments[0].dispatchEvent(new Event('input', { bubbles: true }));
                arguments[0].dispatchEvent(new Event('change', { bubbles: true }));
                arguments[1].value = arguments[2];
                arguments[1].dispatchEvent(new Event('input', { bubbles: true }));
                arguments[1].dispatchEvent(new Event('change', { bubbles: true }));
            ''', password_field, confirm_field, your_password)
            time.sleep(1)
        
        # Try to show password
        try:
            show_password = driver.find_element(By.XPATH, '//input[@type="checkbox"]')
            if show_password and show_password.is_displayed():
                show_password.click()
                time.sleep(1)
        except Exception:
            pass
        
        # Click next
        next_button = wait.until(EC.presence_of_element_located(
            (By.XPATH, '//button[contains(@class, "VfPpkd-LgbsSe") and contains(@class, "VfPpkd-LgbsSe-OWXEXe-k8QpJ")]')))
        wait.until(EC.element_to_be_clickable(
            (By.XPATH, '//button[contains(@class, "VfPpkd-LgbsSe") and contains(@class, "VfPpkd-LgbsSe-OWXEXe-k8QpJ")]')))
        
        driver.execute_script('arguments[0].scrollIntoView(true);', next_button)
        time.sleep(1)
        driver.execute_script('arguments[0].click();', next_button)
        time.sleep(3)
        
        # Wait for password page to disappear
        wait.until(lambda driver: len(driver.find_elements(By.NAME, 'Passwd')) == 0)
        
        # Handle phone verification
        result = handle_verification_smart(driver, wait, progress)

        if result is True:
            update_progress_with_animation(
                progress,
                task_id,
                'Account created successfully!',
                100
            )
            save_account(f'{your_username}@gmail.com', your_password)
            return True

        if result in ("PHONE_REQUIRED", "QR_REQUIRED"):
            console.print(
                f'[{CONFIG["warning_color"]}]Account not confirmed – additional verification required[/]'
            )
            return False
            
    except Exception as e:
        console.print(f'[{CONFIG["error_color"]}]Error in password entry: {str(e)}[/]')
        return False


def create_driver():
    """Create and configure Chrome driver with optimal settings"""
    chrome_options = ChromeOptions()
    
    # Basic options
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--disable-dev-shm-usage')
    chrome_options.add_argument('--disable-gpu')
    chrome_options.add_argument('--disable-infobars')
    chrome_options.add_argument('--disable-notifications')
    chrome_options.add_argument('--disable-software-rasterizer')
    chrome_options.add_argument('--disable-webgl')
    chrome_options.add_argument('--disable-webgl2')
    chrome_options.add_argument('--disable-logging')
    chrome_options.add_argument('--log-level=3')
    chrome_options.add_argument('--ignore-certificate-errors')
    chrome_options.add_argument('--ignore-ssl-errors')
    chrome_options.add_argument('--no-experiments')
    chrome_options.add_argument('--no-default-browser-check')
    chrome_options.add_argument('--no-first-run')
    chrome_options.add_argument('--disable-blink-features=AutomationControlled')
    chrome_options.add_argument(f'user-agent={random.choice(user_agents)}')
    chrome_options.add_argument('--disable-extensions')
    chrome_options.add_argument('--disable-popup-blocking')
    chrome_options.add_argument("--lang=en-US")
    
    service = ChromeService()
    
    max_retries = 3
    for attempt in range(max_retries):
        try:
            driver = webdriver.Chrome(service=service, options=chrome_options)
            driver.maximize_window()
            driver.set_page_load_timeout(30)
            
            # Remove webdriver property
            driver.execute_script('''
                Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
                Object.defineProperty(navigator, 'plugins', {get: () => [1, 2, 3, 4, 5]});
                Object.defineProperty(navigator, 'languages', {get: () => ['en-US', 'en']});
                Object.defineProperty(navigator, 'platform', {get: () => 'Win32'});
            ''')
            
            # Test the driver
            driver.get('https://www.google.com/?hl=en')
            time.sleep(2)
            
            return driver
        except Exception as e:
            if attempt == max_retries - 1:
                raise Exception(f'Failed to create browser after {max_retries} attempts: {str(e)}')
            time.sleep(2)
            if 'driver' in locals():
                try:
                    driver.quit()
                except Exception:
                    pass


def main():
    """Main application loop with beautiful UI"""
    while True:
        try:
            os.system('cls' if os.name == 'nt' else 'clear')
            show_beautiful_banner()
            show_beautiful_menu()
            
            choice = Prompt.ask(
                f'[{CONFIG["theme_color"]}]Select an option[/]',
                choices=['1', '2', '3', '4', '5'],
                default='1'
            )
            
            if choice == '1':
                num_accounts = int(Prompt.ask(
                    f'[{CONFIG["theme_color"]}]How many accounts do you want to create?[/]',
                    default='1'
                ))
                
                console.print(Panel(
                    f'[{CONFIG["success_color"]}]Starting creation of {num_accounts} accounts...[/]\n'
                    f'[{CONFIG["warning_color"]}]Press Ctrl+C to stop the process[/]',
                    border_style=CONFIG["theme_color"]
                ))
                
                with Progress(
                    SpinnerColumn(),
                    TextColumn('[progress.description]{task.description}'),
                    BarColumn(complete_style=CONFIG["theme_color"]),
                    TaskProgressColumn(),
                    console=console
                ) as progress:
                    overall_task = progress.add_task(
                        f'[{CONFIG["theme_color"]}]Overall Progress',
                        total=num_accounts
                    )
                    account_task = progress.add_task(
                        f'[{CONFIG["theme_color"]}]Current Account',
                        total=100
                    )
                    
                    for i in range(num_accounts):
                        try:
                            driver = create_driver()
                            if not driver:
                                raise Exception('Failed to create browser')
                            
                            wait = WebDriverWait(driver, 10)
                            
                            # Generate username
                            name = generate_realistic_name()
                            name_parts = name.split()
                            
                            if len(name_parts) >= 2:
                                first_name = name_parts[0].lower()
                                last_name = name_parts[-1].lower()
                            else:
                                first_name = name_parts[0].lower()
                                last_name = 'user'
                            
                            username = f'{first_name}{last_name}{random.randint(1000, 9999)}'
                            
                            # Create account
                            success = create_account(driver, wait, progress, account_task, username, your_password)
                            
                            if success:
                                console.print(f'[{CONFIG["success_color"]}]✓ Account created successfully: {username}@gmail.com[/]')
                            else:
                                console.print(f'[{CONFIG["error_color"]}]✗ Failed to create account: {username}@gmail.com[/]')
                            
                            try:
                                driver.quit()
                            except Exception:
                                pass
                            
                            progress.update(overall_task, advance=1)
                            progress.update(account_task, completed=0)
                            
                        except Exception as e:
                            console.print(f'[{CONFIG["error_color"]}]Error in account creation cycle: {str(e)}[/]')
                            try:
                                driver.quit()
                            except Exception:
                                pass
                
                input(f'\n[{CONFIG["theme_color"]}]Press Enter to continue...[/]')
                
            elif choice == '2':
                view_statistics()
                input(f'\n[{CONFIG["theme_color"]}]Press Enter to continue...[/]')
                
            elif choice == '3':
                console.print(f'[{CONFIG["warning_color"]}]Settings menu coming soon![/]')
                input(f'\n[{CONFIG["theme_color"]}]Press Enter to continue...[/]')
                
            elif choice == '4':
                console.print(f'[{CONFIG["warning_color"]}]View accounts feature coming soon![/]')
                input(f'\n[{CONFIG["theme_color"]}]Press Enter to continue...[/]')
                
            elif choice == '5':
                console.print(f'[{CONFIG["warning_color"]}]Thanks for using Gmail Creator Pro! Goodbye! 👋[/]')
                break
                
        except KeyboardInterrupt:
            console.print(f'\n[{CONFIG["warning_color"]}]Process interrupted by user.[/]')
            break
        except Exception as e:
            console.print(f'\n[{CONFIG["error_color"]}]An error occurred: {str(e)}[/]')
            input(f'\n[{CONFIG["theme_color"]}]Press Enter to continue...[/]')
    
    # Show exit message
    console.print(f'\n[{CONFIG["theme_color"]}]━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[/]')
    console.print(f'[{CONFIG["theme_color"]}]© 2025 Shadow Hacker - All Rights Reserved[/]')
    console.print(f'[{CONFIG["secondary_color"]}]🌐 Website: https://www.shadowhackr.com[/]')
    console.print(f'[{CONFIG["secondary_color"]}]📘 Facebook: www.facebook.com/ShadowHackr[/]')
    console.print(f'[{CONFIG["secondary_color"]}]📱 WhatsApp: +962796668987[/]')
    console.print(f'[{CONFIG["theme_color"]}]━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[/]\n')


if __name__ == '__main__':
    main()