import pygame # type: ignore
import os
import logging
import platform

# Version actuelle de l'application
app_version = "2.2.0.3"

def get_operating_system():
    """Renvoie le nom du système d'exploitation."""
    return platform.system()
#log dans la console le système d'exploitation
print(f"Système d'exploitation : {get_operating_system()}")


def get_application_root():
    """Détermine le dossier de l'application de manière portable."""
    try:
        # Obtenir le chemin absolu du fichier config.py
        current_file = os.path.abspath(__file__)
        # Remonter au dossier parent de config.py (par exemple, dossier de l'application)
        app_root = os.path.dirname(os.path.dirname(current_file))
        print(f"Dossier de l'application : {app_root}")
        return app_root
    except NameError:
        # Si __file__ n'est pas défini (par exemple, exécution dans un REPL)
        return os.path.abspath(os.getcwd())

def get_system_root():
    OPERATING_SYSTEM = get_operating_system()
    """Détermine le dossier racine du système de fichiers (par exemple, /userdata ou C:\\)."""
    try:
        if OPERATING_SYSTEM == "Windows":
            # Sur Windows, extraire la lettre de disque
            current_path = os.path.abspath(__file__)
            drive, _ = os.path.splitdrive(current_path)
            system_root = drive + os.sep
            print(f"Dossier racine du système : {system_root}")
            return system_root
        elif OPERATING_SYSTEM == "Linux":
            # tester si c'est batocera :
            if os.path.exists("/usr/share/batocera"):
                OPERATING_SYSTEM = "Batocera"
                #remonter jusqu'à atteindre /userdata
                current_path = os.path.abspath(__file__)
                current_dir = current_path
                while current_dir != os.path.dirname(current_dir):  # Tant qu'on peut remonter
                    parent_dir = os.path.dirname(current_dir)
                    if os.path.basename(parent_dir) == "userdata":  # Vérifier si le parent est userdata
                        system_root = parent_dir
                        print(f"Dossier racine du système : {system_root}")
                        return system_root
                    current_dir = parent_dir
                # Si userdata n'est pas trouvé, retourner /
                return "/"
            else:
                return "/"
    except NameError:
        
        return "/" if not OPERATING_SYSTEM == "Windows" else os.path.splitdrive(os.getcwd())[0] + os.sep


# Chemins de base
SYSTEM_FOLDER = get_system_root()
APP_FOLDER = os.path.join(get_application_root(), "RGSX")
ROMS_FOLDER = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER))), "roms")
SAVE_FOLDER = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER))), "saves", "ports", "rgsx")
RETROBAT_DATA_FOLDER = os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER)))



# Configuration du logging
logger = logging.getLogger(__name__)
log_dir = os.path.join(APP_FOLDER, "logs")
log_file = os.path.join(log_dir, "RGSX.log")

# Chemins de base
GAMELISTXML = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER))), "roms", "ports", "gamelist.xml")
GAMELISTXML_WINDOWS = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER))), "roms", "windows", "gamelist.xml")
#Dossier /roms/ports/rgsx
UPDATE_FOLDER = os.path.join(APP_FOLDER, "update")
LANGUAGES_FOLDER = os.path.join(APP_FOLDER, "languages")
MUSIC_FOLDER = os.path.join(APP_FOLDER, "assets", "music")

#Dossier /saves/ports/rgsx
IMAGES_FOLDER = os.path.join(SAVE_FOLDER, "images")
GAMES_FOLDER = os.path.join(SAVE_FOLDER, "games")
SOURCES_FILE = os.path.join(SAVE_FOLDER, "systems_list.json")
JSON_EXTENSIONS = os.path.join(SAVE_FOLDER, "rom_extensions.json")
PRECONF_CONTROLS_PATH = os.path.join(APP_FOLDER, "assets", "controls")
CONTROLS_CONFIG_PATH = os.path.join(SAVE_FOLDER, "controls.json")
HISTORY_PATH = os.path.join(SAVE_FOLDER, "history.json")
API_KEY_1FICHIER = os.path.join(SAVE_FOLDER, "1fichierAPI.txt")
RGSX_SETTINGS_PATH = os.path.join(SAVE_FOLDER, "rgsx_settings.json")

# URL
OTA_SERVER_URL = "https://retrogamesets.fr/softs/"
OTA_VERSION_ENDPOINT = os.path.join(OTA_SERVER_URL, "version.json")
OTA_UPDATE_ZIP = os.path.join(OTA_SERVER_URL, "RGSX.zip")
OTA_data_ZIP = os.path.join(OTA_SERVER_URL, "games.zip")

#CHEMINS DES EXECUTABLES
UNRAR_EXE = os.path.join(APP_FOLDER,"assets", "unrar.exe")
XDVDFS_EXE = os.path.join(APP_FOLDER,"assets", "xdvdfs.exe")
XDVDFS_LINUX = os.path.join(APP_FOLDER,"assets", "xdvdfs")
unrar_download_exe = os.path.join(OTA_SERVER_URL, "unrar.exe")
xdvdfs_download_exe = os.path.join(OTA_SERVER_URL, "xdvdfs.exe")


xdvdfs_download_linux = os.path.join(OTA_SERVER_URL, "xdvdfs")

# Print des chemins pour debug
print(f"RETROBAT_DATA_FOLDER: {RETROBAT_DATA_FOLDER}")
print(f"ROMS_FOLDER: {ROMS_FOLDER}")
print(f"SAVE_FOLDER: {SAVE_FOLDER}")
print(f"RGSX APP_FOLDER: {APP_FOLDER}")
print(f"RGSX LOGS_FOLDER: {log_dir}")
print(f"RGSX SETTINGS PATH: {RGSX_SETTINGS_PATH}")
print(f"GAMELISTXML: {GAMELISTXML}")
print(f"GAMELISTXML_WINDOWS: {GAMELISTXML_WINDOWS}")
print(f"UPDATE_FOLDER: {UPDATE_FOLDER}")
print(f"LANGUAGES_FOLDER: {LANGUAGES_FOLDER}")
print(f"JSON_EXTENSIONS: {JSON_EXTENSIONS}")
print(f"MUSIC_FOLDER: {MUSIC_FOLDER}")
print(f"IMAGES_FOLDER: {IMAGES_FOLDER}")
print(f"GAMES_FOLDER: {GAMES_FOLDER}")
print(f"SOURCES_FILE: {SOURCES_FILE}")
print(f"CONTROLS_CONFIG_PATH: {CONTROLS_CONFIG_PATH}")
print(f"HISTORY_PATH: {HISTORY_PATH}")



# Constantes pour la répétition automatique dans pause_menu
REPEAT_DELAY = 350  # Délai initial avant répétition (ms) - augmenté pour éviter les doubles actions
REPEAT_INTERVAL = 120  # Intervalle entre répétitions (ms) - ajusté pour une navigation plus contrôlée
REPEAT_ACTION_DEBOUNCE = 150  # Délai anti-rebond pour répétitions (ms) - augmenté pour éviter les doubles actions


# Variables d'état
platforms = []
current_platform = 0
accessibility_mode = False  # Mode accessibilité pour les polices agrandies
accessibility_settings = {"font_scale": 1.0}
font_scale_options = [0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0]
current_font_scale_index = 3  # Index pour 1.0
platform_names = {}  # {platform_id: platform_name}
games = []
current_game = 0
menu_state = "popup"
confirm_choice = False
scroll_offset = 0
visible_games = 15
popup_start_time = 0
last_progress_update = 0
needs_redraw = True
transition_state = "idle"
transition_progress = 0.0
transition_duration = 18
games_count = {}
music_enabled = True  # Par défaut la musique est activée
sources_mode = "rgsx"  # Mode des sources de jeux (rgsx/custom)
custom_sources_url = ""  # URL personnalisée si mode custom

# Variables pour la sélection de langue
selected_language_index = 0

loading_progress = 0.0
current_loading_system = ""
error_message = ""
repeat_action = None
repeat_start_time = 0
repeat_last_action = 0
repeat_key = None 
filtered_games = []
search_mode = False
search_query = ""
filter_active = False
extension_confirm_selection = 0
pending_download = None
controls_config = {}
selected_option = 0
previous_menu_state = None
history = []  # Liste des entrées d'historique avec platform, game_name, status, url, progress, message, timestamp
download_progress = {}
download_tasks = {}  # Dictionnaire pour les tâches de téléchargement
download_result_message = ""
download_result_error = False
download_result_start_time = 0
needs_redraw = False
current_history_item = 0
history_scroll_offset = 0  # Offset pour le défilement de l'historique
visible_history_items = 15  # Nombre d'éléments d'historique visibles (ajusté dynamiquement)
confirm_clear_selection = 0  # confirmation clear historique
confirm_cancel_selection = 0  # confirmation annulation téléchargement
last_state_change_time = 0  # Temps du dernier changement d'état pour debounce
debounce_delay = 200  # Délai de debounce en millisecondes
platform_dicts = []  # Liste des dictionnaires de plateformes
selected_key = (0, 0)  # Position du curseur dans le clavier virtuel
redownload_confirm_selection = 0  # Sélection pour la confirmation de redownload
popup_message = ""  # Message à afficher dans les popups
popup_timer = 0  # Temps restant pour le popup en millisecondes (0 = inactif)
last_frame_time = pygame.time.get_ticks()
current_music_name = None
music_popup_start_time = 0
selected_games = set()  # Indices des jeux sélectionnés pour un téléchargement multiple (menu game)
batch_download_indices = []  # File d'attente des indices de jeux à traiter en lot
batch_in_progress = False  # Indique qu'un lot est en cours
batch_pending_game = None  # Données du jeu en attente de confirmation d'extension

# Indicateurs d'entrée (détectés au démarrage)
joystick = False
keyboard = False
xbox_controller = False
playstation_controller = False
nintendo_controller = False
logitech_controller = False
eightbitdo_controller = False
steam_controller = False
trimui_controller = False
generic_controller = False

# --- Filtre plateformes (UI) ---
selected_filter_index = 0  # index dans la liste visible triée
filter_platforms_scroll_offset = 0  # défilement si liste longue
filter_platforms_dirty = False  # indique si modifications non sauvegardées
filter_platforms_selection = []  # copie de travail des plateformes visibles (bool masque?) structure: list of (name, hidden_bool)


GRID_COLS = 3  # Number of columns in the platform grid
GRID_ROWS = 4  # Number of rows in the platform grid

# Résolution de l'écran fallback
# Utilisée si la résolution définie dépasse les capacités de l'écran
SCREEN_WIDTH = 800
"""Largeur de l'écran en pixels."""
SCREEN_HEIGHT = 600
"""Hauteur de l'écran en pixels."""

# Polices
FONT = None
"""Police par défaut pour l'affichage, initialisée via init_font()."""
progress_font = None
"""Police pour l'affichage de la progression."""
title_font = None
"""Police pour les titres."""
search_font = None
"""Police pour la recherche."""
small_font = None
"""Police pour les petits textes."""

def init_font():
    """Initialise les polices après pygame.init()."""

    global font, progress_font, title_font, search_font, small_font
    font_scale = accessibility_settings.get("font_scale", 1.0)
    try:
        font_path = os.path.join(APP_FOLDER, "assets", "Pixel-UniCode.ttf")
        font = pygame.font.Font(font_path, int(36 * font_scale))
        title_font = pygame.font.Font(font_path, int(48 * font_scale))
        search_font = pygame.font.Font(font_path, int(48 * font_scale))
        progress_font = pygame.font.Font(font_path, int(36 * font_scale))
        small_font = pygame.font.Font(font_path, int(28 * font_scale))
        logger.debug(f"Polices Pixel-UniCode initialisées (font_scale: {font_scale})")
    except Exception as e:
        try:
            font = pygame.font.SysFont("arial", int(48 * font_scale))
            title_font = pygame.font.SysFont("arial", int(60 * font_scale))
            search_font = pygame.font.SysFont("arial", int(60 * font_scale))
            progress_font = pygame.font.SysFont("arial", int(36 * font_scale))
            small_font = pygame.font.SysFont("arial", int(28 * font_scale))
            logger.debug(f"Polices Arial initialisées (font_scale: {font_scale})")
        except Exception as e2:
            logger.error(f"Erreur lors de l'initialisation des polices : {e2}")
            font = None
            progress_font = None
            title_font = None
            search_font = None
            small_font = None

# Indique si une vérification/installation des mises à jour a déjà été effectuée au démarrage
update_checked = False

def validate_resolution():
    """Valide la résolution de l'écran par rapport aux capacités de l'écran."""
    display_info = pygame.display.Info()
    if SCREEN_WIDTH > display_info.current_w or SCREEN_HEIGHT > display_info.current_h:
        logger.warning(f"Résolution {SCREEN_WIDTH}x{SCREEN_HEIGHT} dépasse les limites de l'écran")
        return display_info.current_w, display_info.current_h
    return SCREEN_WIDTH, SCREEN_HEIGHT