# selenium_handlers.py
import time
import sys
import threading
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,
    WebDriverException,
    ElementClickInterceptedException,
)
import logging
from logger import app_logger  # Use central logger

# Import ConsoleUI for type hinting
try:
    from console_ui import ConsoleUI
except ImportError:
    ConsoleUI = None  # Fallback type

# --- Site-Specific Selenium Handlers ---
# Each handler should:
# 1. Accept driver, config, ui
# 2. Attempt to find and click the download element.
# 3. Log actions and errors using app_logger.
# 4. Return True on successful click initiation, False otherwise.


def handle_pixeldrain(driver, config, ui: ConsoleUI | None = None):
    """Handles download from pixeldrain.com."""
    thread_name = threading.current_thread().name
    app_logger.info(f"[{thread_name}] Executing Pixeldrain handler...")
    wait_time = config.getfloat("Selenium", "pixeldrain_button_wait", fallback=45.0)
    # FIX: Updated XPath to look for button containing "Download" OR "DL all files" (case-insensitive)
    # Using normalize-space() to handle potential extra whitespace in button text
    download_button_xpath = "//button[span[text()='Download' or text()='DL all files']]"

    try:
        app_logger.debug(
            f"[{thread_name}] Waiting for Pixeldrain download button ({wait_time}s)..."
        )
        wait = WebDriverWait(driver, wait_time)
        download_button = wait.until(
            EC.element_to_be_clickable((By.XPATH, download_button_xpath))
        )
        app_logger.debug(
            f"[{thread_name}] Pixeldrain download button found. Clicking..."
        )

        try:
            driver.execute_script(
                "arguments[0].scrollIntoView({block: 'center'});", download_button
            )
            time.sleep(0.5)
            driver.execute_script("arguments[0].click();", download_button)
            app_logger.info(
                f"[{thread_name}] Clicked Pixeldrain download button via JS."
            )
            return True
        except Exception as js_click_err:
            app_logger.warning(
                f"[{thread_name}] JavaScript click failed ({js_click_err}), attempting direct click..."
            )
            try:
                download_button.click()
                app_logger.info(
                    f"[{thread_name}] Clicked Pixeldrain download button directly."
                )
                return True
            except ElementClickInterceptedException as e:
                app_logger.error(
                    f"[{thread_name}] Direct click intercepted for Pixeldrain button: {e}"
                )
                return False
            except Exception as direct_click_err:
                app_logger.error(
                    f"[{thread_name}] Direct click failed for Pixeldrain button: {direct_click_err}",
                    exc_info=True,
                )
                return False

    except TimeoutException:
        app_logger.error(
            f"[{thread_name}] Timed out waiting for Pixeldrain download button after {wait_time}s."
        )
    except NoSuchElementException:
        app_logger.error(
            f"[{thread_name}] Could not find Pixeldrain download button using XPath: {download_button_xpath}"
        )
    except WebDriverException as e:
        app_logger.error(
            f"[{thread_name}] WebDriver error during Pixeldrain interaction: {e}",
            exc_info=True,
        )
    except Exception as e:
        app_logger.error(
            f"[{thread_name}] Unexpected error in Pixeldrain handler: {e}",
            exc_info=True,
        )
    return False


def handle_mega(driver, config, ui: ConsoleUI | None = None):
    """Handles download from mega.nz."""
    thread_name = threading.current_thread().name
    app_logger.info(f"[{thread_name}] Executing Mega.nz handler...")
    wait_time = config.getfloat("Selenium", "mega_button_wait", fallback=60.0)
    download_button_xpath = "//button[contains(@class, 'js-download-button') or contains(@class, 'mega-button') or contains(@class, 'download-file')][.//span[contains(translate(., 'DOWNLOAD', 'download'), 'download')] or contains(translate(., 'DOWNLOAD', 'download'), 'download')]"
    accept_cookies_xpath = "//button[contains(@class, 'js-accept-cookies') or contains(translate(normalize-space(.), 'ACCEPT', 'accept'), 'accept')][not(ancestor::*[contains(@style,'display: none')])]"
    transfer_dialog_xpath = "//div[contains(@class, 'transfer-dialog') or contains(@class,'mega-dialog') or contains(@class,'transfer-panel')]"

    try:
        try:
            wait_short = WebDriverWait(driver, 10)
            app_logger.debug(f"[{thread_name}] Checking for Mega cookie banner...")
            cookie_button = wait_short.until(
                EC.element_to_be_clickable((By.XPATH, accept_cookies_xpath))
            )
            app_logger.info(f"[{thread_name}] Cookie banner found. Clicking accept...")
            driver.execute_script("arguments[0].click();", cookie_button)
            time.sleep(1)
        except TimeoutException:
            app_logger.debug(f"[{thread_name}] Cookie banner not found or timed out.")
        except Exception as e:
            app_logger.warning(
                f"[{thread_name}] Non-fatal error handling cookie banner: {e}"
            )

        app_logger.debug(
            f"[{thread_name}] Waiting for Mega download button ({wait_time}s)..."
        )
        wait_long = WebDriverWait(driver, wait_time)
        wait_long.until(
            EC.presence_of_element_located((By.XPATH, download_button_xpath))
        )
        download_button = wait_long.until(
            EC.element_to_be_clickable((By.XPATH, download_button_xpath))
        )

        app_logger.debug(f"[{thread_name}] Mega download button found. Clicking...")
        driver.execute_script(
            "arguments[0].scrollIntoView({block: 'center'});", download_button
        )
        time.sleep(0.5)
        driver.execute_script("arguments[0].click();", download_button)
        app_logger.info(f"[{thread_name}] Clicked Mega download button.")

        try:
            WebDriverWait(driver, 25).until(
                EC.visibility_of_element_located((By.XPATH, transfer_dialog_xpath))
            )
            app_logger.info(f"[{thread_name}] Mega internal transfer dialog detected.")
        except TimeoutException:
            app_logger.debug(
                f"[{thread_name}] Mega internal transfer dialog did not appear quickly, proceeding anyway."
            )
        return True

    except TimeoutException:
        app_logger.error(
            f"[{thread_name}] Timed out waiting for Mega download button after {wait_time}s."
        )
    except NoSuchElementException:
        app_logger.error(
            f"[{thread_name}] Could not find Mega download button using XPath: {download_button_xpath}"
        )
    except WebDriverException as e:
        app_logger.error(
            f"[{thread_name}] WebDriver error during Mega interaction: {e}",
            exc_info=True,
        )
    except Exception as e:
        app_logger.error(
            f"[{thread_name}] Unexpected error in Mega handler: {e}", exc_info=True
        )
    return False


def handle_mediafire(driver, config, ui: ConsoleUI | None = None):
    """Handles download from mediafire.com."""
    thread_name = threading.current_thread().name
    app_logger.info(f"[{thread_name}] Executing Mediafire handler...")
    wait_time = config.getfloat("Selenium", "mediafire_button_wait", fallback=15.0)
    download_button_xpath = "//*[@id='downloadButton' and not(ancestor::*[contains(@style,'display: none')])]"

    try:
        app_logger.debug(
            f"[{thread_name}] Waiting for Mediafire download button ({wait_time}s)..."
        )
        wait = WebDriverWait(driver, wait_time)
        wait.until(EC.presence_of_element_located((By.XPATH, download_button_xpath)))
        download_button = wait.until(
            EC.element_to_be_clickable((By.XPATH, download_button_xpath))
        )
        app_logger.debug(
            f"[{thread_name}] Mediafire download button found and clickable. Clicking..."
        )

        driver.execute_script(
            "arguments[0].scrollIntoView({block: 'center'});", download_button
        )
        time.sleep(0.5)
        download_button.click()
        app_logger.info(f"[{thread_name}] Clicked Mediafire download button.")
        return True
    except TimeoutException:
        app_logger.error(
            f"[{thread_name}] Timed out waiting for Mediafire download button (XPath: {download_button_xpath}) after {wait_time}s."
        )
    except NoSuchElementException:
        app_logger.error(
            f"[{thread_name}] Could not find Mediafire download button using XPath: {download_button_xpath}"
        )
    except WebDriverException as e:
        app_logger.error(
            f"[{thread_name}] WebDriver error during Mediafire interaction: {e}",
            exc_info=True,
        )
    except Exception as e:
        app_logger.error(
            f"[{thread_name}] Unexpected error in Mediafire handler: {e}", exc_info=True
        )
    return False


if __name__ == "__main__":
    print("This module contains Selenium handlers and is not meant to be run directly.")
