#!/usr/bin/env python3
"""
One-Click Ngrok Fix for ERR_NGROK_3200
Handles all common ngrok issues automatically
"""

import subprocess
import time
import requests
import json
import os
import webbrowser

def print_header(text):
    print("\n" + "="*70)
    print(f"  {text}")
    print("="*70)

def print_step(num, total, text):
    print(f"\n[{num}/{total}] {text}")

def kill_ngrok():
    """Kill all ngrok processes"""
    print("  → Stopping ngrok...")
    subprocess.run(['taskkill', '/IM', 'ngrok.exe', '/F'],
                   stdout=subprocess.DEVNULL,
                   stderr=subprocess.DEVNULL)
    time.sleep(2)

def start_ngrok():
    """Start ngrok with best settings for OAuth"""
    print("  → Starting ngrok tunnel...")
    # Use --host-header=rewrite for better compatibility
    subprocess.Popen('ngrok http 5000 --host-header=rewrite',
                    shell=True,
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL)
    print("  → Waiting for tunnel to establish...")
    for i in range(10):
        print(f"     {i+1}/10...", end='\r')
        time.sleep(1)
    print()

def get_tunnel_info():
    """Get tunnel information from ngrok API"""
    try:
        response = requests.get('http://127.0.0.1:4040/api/tunnels', timeout=3)
        data = response.json()
        tunnels = data.get('tunnels', [])
        
        if not tunnels:
            return None
        
        # Get HTTPS tunnel
        for tunnel in tunnels:
            if tunnel.get('proto') == 'https':
                return {
                    'url': tunnel.get('public_url'),
                    'name': tunnel.get('name'),
                    'config': tunnel.get('config', {})
                }
        
        return {
            'url': tunnels[0].get('public_url'),
            'name': tunnels[0].get('name'),
            'config': tunnels[0].get('config', {})
        }
    except Exception as e:
        print(f"  ✗ Error: {e}")
        return None

def update_credentials(url):
    """Update credentials.json with new ngrok URL"""
    try:
        with open('credentials.json', 'r') as f:
            creds = json.load(f)
        
        callback_url = f"{url}/oauth2callback"
        creds['web']['redirect_uris'] = [callback_url]
        creds['web']['javascript_origins'] = [url]
        
        with open('credentials.json', 'w') as f:
            json.dump(creds, f, indent=2)
        
        return callback_url
    except Exception as e:
        print(f"  ✗ Error updating credentials: {e}")
        return None

def check_flask():
    """Check if Flask is running"""
    try:
        response = requests.get('http://localhost:5000', timeout=3)
        return True
    except:
        return False

def test_ngrok_url(url):
    """Test if ngrok URL is accessible"""
    try:
        response = requests.get(url, timeout=10, allow_redirects=True, verify=False)
        return response.status_code
    except Exception as e:
        return None

def main():
    print_header("🔧 NGROK COMPLETE FIX - ERR_NGROK_3200")
    
    # Step 1: Check Flask
    print_step(1, 6, "Checking Flask Application")
    if check_flask():
        print("  ✓ Flask is running on localhost:5000")
    else:
        print("  ✗ Flask is NOT running!")
        print("\n⚠️  Please start Flask first:")
        print("     python app.py")
        return
    
    # Step 2: Restart ngrok
    print_step(2, 6, "Restarting ngrok Tunnel")
    kill_ngrok()
    print("  ✓ Stopped old tunnels")
    start_ngrok()
    print("  ✓ Started new tunnel")
    
    # Step 3: Get tunnel info
    print_step(3, 6, "Getting Tunnel Information")
    info = get_tunnel_info()
    if not info:
        print("  ✗ Could not get tunnel information")
        print("\n⚠️  ngrok might not be installed or configured")
        print("     Visit: https://ngrok.com/download")
        return
    
    url = info['url']
    print(f"  ✓ Tunnel URL: {url}")
    
    # Step 4: Update credentials
    print_step(4, 6, "Updating OAuth Credentials")
    callback = update_credentials(url)
    if callback:
        print(f"  ✓ Updated credentials.json")
        print(f"     Redirect URI: {callback}")
    else:
        print("  ✗ Failed to update credentials")
        return
    
    # Step 5: Test URL
    print_step(5, 6, "Testing ngrok URL")
    status = test_ngrok_url(url)
    if status == 200:
        print(f"  ✓ URL is accessible (HTTP {status})")
    elif status:
        print(f"  ⚠️  URL returned HTTP {status}")
    else:
        print(f"  ✗ URL is not accessible")
    
    # Step 6: Instructions
    print_step(6, 6, "Final Setup Instructions")
    
    print_header("✅ NGROK IS NOW RUNNING")
    
    print("\n📍 Your Application URL:")
    print(f"   {url}")
    
    print("\n🔐 Google Cloud Console Setup (REQUIRED):")
    print(f"   1. Go to: https://console.cloud.google.com/apis/credentials")
    print(f"   2. Edit your OAuth 2.0 Client ID")
    print(f"   3. Update these settings:")
    print(f"")
    print(f"      Authorized redirect URIs:")
    print(f"      {callback}")
    print(f"")
    print(f"      Authorized JavaScript origins:")
    print(f"      {url}")
    print(f"")
    print(f"   4. Click SAVE")
    
    print("\n🌐 Access Your App:")
    print(f"   1. Visit: {url}")
    print(f"   2. Click 'Visit Site' on ngrok warning page (if shown)")
    print(f"   3. Clear browser cache (Ctrl+Shift+Delete)")
    print(f"   4. Try logging in")
    
    print("\n⚠️  IMPORTANT: Ngrok Free Tier Limitations")
    print("   • Shows interstitial warning page")
    print("   • URL changes each time ngrok restarts")
    print("   • Must update Google Console after each restart")
    print("   • Consider upgrading: $8/month for static domain")
    
    print("\n💡 Alternative Solutions:")
    print("   • Upgrade to ngrok Personal: https://dashboard.ngrok.com/billing")
    print("   • Use LocalTunnel: npm install -g localtunnel")
    print("   • Deploy to cloud: Railway, Render, Fly.io (free tiers)")
    
    print("\n📝 If errors persist:")
    print("   1. Completely clear browser cache")
    print("   2. Use incognito/private browsing")
    print("   3. Verify Google Console settings match exactly")
    print("   4. Make sure you click through ngrok interstitial BEFORE logging in")
    
    # Offer to open URLs
    print("\n🔗 Quick Actions:")
    open_browser = input("   Open app in browser? (y/n): ").strip().lower()
    if open_browser == 'y':
        print(f"   Opening {url}...")
        webbrowser.open(url)
    
    open_console = input("   Open Google Cloud Console? (y/n): ").strip().lower()
    if open_console == 'y':
        print("   Opening Google Cloud Console...")
        webbrowser.open("https://console.cloud.google.com/apis/credentials")
    
    print("\n" + "="*70)
    print("  ✅ Setup Complete!")
    print("="*70)
    print()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print("\n\n⚠️  Interrupted by user")
    except Exception as e:
        print(f"\n\n❌ Error: {e}")
        import traceback
        traceback.print_exc()
