#!/usr/bin/env python3
import time
import re
import os
import json
import sys
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import paramiko

# Suprimir warnings de paramiko
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning, module="paramiko")

def setup_driver():
    """
    Configura Chrome con opciones optimizadas
    """
    print("Configurando Chrome driver...")
    
    chrome_options = Options()
    chrome_options.binary_location = "/usr/bin/chromium-browser"
    
    # Configuración básica
    chrome_options.add_argument("--headless=new")
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("window-size=1920,1080")
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")
    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
    chrome_options.add_experimental_option('useAutomationExtension', False)
    
    # Configuración de user-agent y idioma
    chrome_options.add_argument("--lang=en-US,en;q=0.9")
    chrome_options.add_argument("--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
    
    try:
        service = Service('/usr/bin/chromedriver')
        driver = webdriver.Chrome(service=service, options=chrome_options)
        print("✓ Driver configurado exitosamente")
        return driver
    except Exception as e:
        print(f"✗ Error configurando driver: {e}")
        sys.exit(1)

def load_cookies_from_file(driver, base_url, cookie_file='chaturbate_cookies.json'):
    """
    Carga cookies desde un archivo JSON
    """
    try:
        if not os.path.exists(cookie_file):
            print(f"✗ Archivo de cookies '{cookie_file}' no encontrado")
            return False
            
        print(f"Cargando cookies desde {cookie_file}...")
        
        # Primero cargar la página principal
        driver.get(base_url)
        time.sleep(2)
        
        # Limpiar cookies existentes
        driver.delete_all_cookies()
        
        # Leer cookies del archivo
        with open(cookie_file, 'r', encoding='utf-8') as f:
            cookies = json.load(f)
        
        cookies_loaded = 0
        for cookie in cookies:
            try:
                # Asegurar dominio correcto
                if 'domain' not in cookie:
                    cookie['domain'] = '.chaturbate.com'
                elif not cookie['domain'].startswith('.'):
                    cookie['domain'] = '.' + cookie['domain']
                
                # Manejar sameSite
                if 'sameSite' in cookie and cookie['sameSite'] not in ['Strict', 'Lax', 'None']:
                    cookie['sameSite'] = 'Lax'
                
                # Eliminar campos problemáticos
                cookie_copy = {k: v for k, v in cookie.items() 
                             if k not in ['hostOnly', 'session', 'storeId', 'id', 'httpOnly']}
                
                driver.add_cookie(cookie_copy)
                cookies_loaded += 1
                
            except Exception as e:
                continue
        
        print(f"✓ Se cargaron {cookies_loaded} cookies")
        
        # Refrescar para aplicar cookies
        driver.get(base_url)
        time.sleep(3)
        
        # Verificar si las cookies funcionaron
        if "age_verification" not in driver.current_url:
            print("✓ Cookies aplicadas correctamente")
            return True
        else:
            print("✗ Las cookies no evitaron la verificación de edad")
            return False
            
    except Exception as e:
        print(f"✗ Error cargando cookies: {e}")
        return False

def handle_age_verification(driver):
    """
    Maneja la verificación de edad de manera más robusta
    """
    try:
        time.sleep(3)
        current_url = driver.current_url.lower()
        page_source = driver.page_source.lower()
        
        # Verificar si estamos en página de verificación
        age_indicators = [
            'age_verification', 'age-verification', 'verify-age', 'age_check',
            'age verification', 'confirm your age', 'enter your age'
        ]
        
        is_age_page = any(indicator in current_url or indicator in page_source 
                         for indicator in age_indicators)
        
        if is_age_page:
            print("Página de verificación de edad detectada, intentando manejar...")
            
            # Estrategia 1: Buscar botones por texto
            button_texts = ['Enter', 'ENTER', 'Enter Site', 'Continue', 'Verify', 'Yes, I am over 18']
            
            for text in button_texts:
                try:
                    xpath = f"//*[contains(translate(text(), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), '{text.upper()}')]"
                    elements = driver.find_elements(By.XPATH, xpath)
                    for element in elements:
                        if element.is_displayed() and element.is_enabled():
                            driver.execute_script("arguments[0].click();", element)
                            print(f"✓ Click en botón: {text}")
                            time.sleep(3)
                            return True
                except:
                    continue
            
            # Estrategia 2: Buscar por selectores comunes
            selectors = [
                "//button[@type='submit']",
                "//input[@type='submit']",
                "//a[contains(@class, 'btn')]",
                "//button[contains(@class, 'btn')]",
                "//*[@id='enter']",
                "//*[contains(@onclick, 'age')]"
            ]
            
            for selector in selectors:
                try:
                    element = driver.find_element(By.XPATH, selector)
                    if element.is_displayed() and element.is_enabled():
                        driver.execute_script("arguments[0].click();", element)
                        print(f"✓ Click en elemento: {selector}")
                        time.sleep(3)
                        return True
                except:
                    continue
            
            print("✗ No se pudo encontrar botón de verificación")
            return False
        else:
            print("✓ Sin verificación de edad detectada")
            return True
            
    except Exception as e:
        print(f"✗ Error en verificación de edad: {e}")
        return False

def scrape_profiles(driver, base_url, num_pages, usuarios_existentes):
    """
    Escanea las páginas de male-cams y devuelve perfiles
    """
    profiles = {}
    pattern = re.compile(r"^/([\w\-]+)/$")
    
    for page in range(1, num_pages + 1):
        if page == 1:
            page_url = base_url + "/male-cams/"
        else:
            page_url = base_url + f"/male-cams/?page={page}"
            
        print(f"Scrapeando página {page}: {page_url}")
        
        try:
            driver.get(page_url)
            time.sleep(5)  # Esperar a que cargue
            
            # Manejar verificación de edad
            age_handled = handle_age_verification(driver)
            if not age_handled:
                print("⚠ Continuando a pesar de verificación de edad...")
            
            # Buscar enlaces de perfiles
            a_tags = driver.find_elements(By.XPATH, '//a[@data-room-nav="true"]')
            print(f"  Encontrados {len(a_tags)} enlaces en la página")
            
            profiles_found = 0
            for a in a_tags:
                try:
                    href = a.get_attribute("href")
                    if not href:
                        continue
                        
                    # Convertir a URL absoluta si es relativa
                    if not href.startswith("http"):
                        if href.startswith("/"):
                            href = base_url + href
                    
                    # Asegurar que la URL termine con "/"
                    if not href.endswith("/"):
                        href += "/"
                    
                    # Validar el formato
                    relative = href[len(base_url):]
                    match = pattern.match(relative)
                    if match:
                        username = match.group(1)
                        
                        # Filtrar usuarios no deseados
                        if (username.lower() not in ['male-cams', 'female-cams', 'couple-cams', 'trans-cams'] and 
                            username not in usuarios_existentes):
                            
                            # Generar URL de imagen
                            image_url = f"https://thumb.live.mmcdn.com/riw/{username}.jpg?58095157"
                            profiles[href] = image_url
                            profiles_found += 1
                            print(f"  ✓ Perfil añadido: {username}")
                
                except Exception as e:
                    continue
            
            print(f"  Página {page}: {profiles_found} perfiles nuevos")
                    
        except Exception as e:
            print(f"✗ Error en página {page}: {e}")
            continue
            
    return profiles

def extract_m3u8(driver, profile_url):
    """
    Extrae la URL m3u8 del perfil
    """
    m3u8_regex = re.compile(r"(https?://[^\s\"']+?\.m3u8[^\s\"']*)")
    
    try:
        print(f"  Extrayendo m3u8 de: {profile_url}")
        driver.get(profile_url)
        time.sleep(5)  # Esperar a que cargue el stream
        
        # Manejar verificación de edad si aparece
        handle_age_verification(driver)
        
        # Buscar m3u8 en el HTML
        html = driver.page_source
        match = m3u8_regex.search(html)
        
        if match:
            m3u8_url = match.group(1)
            # Limpiar la URL
            m3u8_url = m3u8_url.encode("utf-8").decode("unicode_escape")
            m3u8_url = re.sub(r'\\/', '/', m3u8_url)
            
            print(f"  ✓ m3u8 encontrado")
            return m3u8_url
        else:
            print("  ✗ No se encontró m3u8 en la página")
            return None
            
    except Exception as e:
        print(f"  ✗ Error extrayendo m3u8: {e}")
        return None

def upload_file(local_path, remote_path, hostname, username, password):
    """
    Sube archivo via SFTP
    """
    try:
        print(f"Subiendo archivo a {hostname}...")
        transport = paramiko.Transport((hostname, 22))
        transport.connect(username=username, password=password)
        sftp = paramiko.SFTPClient.from_transport(transport)
        sftp.put(local_path, remote_path)
        sftp.close()
        transport.close()
        print(f"✓ Archivo subido exitosamente a: {remote_path}")
        return True
    except Exception as e:
        print(f"✗ Error subiendo archivo: {e}")
        return False

def main():
    print("=== SCRAPER DE CHATURBATE - VERSIÓN COMPLETA ===\n")
    
    base_url = "https://chaturbate.com"
    num_pages = 3  # Reducido para pruebas, puedes aumentar después
    archivo_salida = "hombres.m3u"
    cookie_file = "chaturbate_cookies.json"

    # No leer archivos existentes - empezar desde cero
    usuarios_existentes = set()
    print("Iniciando scraping desde cero...")

    # Configurar driver
    driver = setup_driver()
    
    try:
        # Intentar cargar cookies
        cookies_loaded = False
        if os.path.exists(cookie_file):
            cookies_loaded = load_cookies_from_file(driver, base_url, cookie_file)
        else:
            print("ℹ No se encontró archivo de cookies, continuando sin ellas...")

        # PASO 1: Scrapear perfiles
        print("\n" + "="*50)
        print("PASO 1: SCRAPEANDO PERFILES")
        print("="*50)
        
        profiles = scrape_profiles(driver, base_url, num_pages, usuarios_existentes)
        print(f"\n✓ Scraping completado: {len(profiles)} perfiles encontrados")

        if not profiles:
            print("✗ No se encontraron perfiles. Posibles causas:")
            print("  - El sitio está bloqueando el acceso")
            print("  - La verificación de edad no se puede superar")
            print("  - Cambios en la estructura del sitio")
            return

        # PASO 2: Extraer URLs m3u8
        print("\n" + "="*50)
        print("PASO 2: EXTRAYENDO URLs M3U8")
        print("="*50)
        
        results = {}
        successful_extractions = 0
        
        for i, (profile_url, image_url) in enumerate(profiles.items(), 1):
            print(f"[{i}/{len(profiles)}] Procesando perfil...")
            m3u8_url = extract_m3u8(driver, profile_url)
            
            if m3u8_url:
                results[profile_url] = (m3u8_url, image_url)
                successful_extractions += 1
            else:
                print(f"  ✗ No se pudo extraer m3u8")
        
        print(f"\n✓ Extracción completada: {successful_extractions}/{len(profiles)} streams obtenidos")

        # PASO 3: Guardar archivo M3U
        print("\n" + "="*50)
        print("PASO 3: GUARDANDO ARCHIVO M3U")
        print("="*50)
        
        try:
            with open(archivo_salida, "w", encoding="utf-8") as f:
                f.write("#EXTM3U\n")
                for perfil_url, data in results.items():
                    m3u8_url, image_url = data
                    username = perfil_url.replace("https://chaturbate.com/", "").strip("/")
                    # Eliminar query parameters de la imagen
                    fixed_image_url = image_url.split("?")[0]
                    
                    f.write(f'#EXTINF:-1 tvg-id="" tvg-name="{username}" tvg-logo="{fixed_image_url}" group-title="xxxmen",{username}\n')
                    f.write(f'{m3u8_url}\n')
                
            print(f"✓ Archivo guardado: '{archivo_salida}'")
            print(f"✓ Total de streams: {len(results)}")

            # PASO 4: Subir al servidor
            if len(results) > 0:
                print("\n" + "="*50)
                print("PASO 4: SUBIENDO AL SERVIDOR")
                print("="*50)
                
                upload_success = upload_file(
                    archivo_salida,
                    "/home/migosu/disco/web/servidor-mitilingo/script/hombres.m3u",
                    "mitilingo.com",
                    "migosu",
                    "Michelito84"
                )
                
                if upload_success:
                    print("🎉 PROCESO COMPLETADO EXITOSAMENTE!")
                else:
                    print("⚠ Proceso completado pero falló la subida")
            else:
                print("✗ No hay streams para subir")
                
        except Exception as e:
            print(f"✗ Error guardando archivo: {e}")
        
    except Exception as e:
        print(f"✗ Error en el proceso principal: {e}")
        
    finally:
        driver.quit()
        print("\n=== SCRAPING FINALIZADO ===")

if __name__ == "__main__":
    main()
