#!/usr/bin/env python3
"""
Progression Loader - Terminal User Interface (TUI)
A text-based interface for managing RimWorld Steam Workshop collections
"""

import os
import sys
import time
import threading
import xml.etree.ElementTree as ET
from pathlib import Path
from dotenv import load_dotenv
import webbrowser
import requests
import re
from urllib.parse import urlparse, parse_qs

# Rich imports for TUI
from rich.console import Console
from rich.panel import Panel
from rich.text import Text
from rich.layout import Layout
from rich.live import Live
from rich.prompt import Prompt, Confirm
from rich.table import Table
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.align import Align
from rich.columns import Columns
from rich import box

# Import existing modules
from update_checker import UpdateChecker
from update_config import get_update_config

# Load environment variables
load_dotenv()

# Steam Collections page inspired color scheme for TUI
TUI_COLORS = {
    'bg_primary': '#1b2838',        # Steam dark blue background
    'bg_secondary': '#2a475e',      # Steam medium blue background
    'bg_tertiary': '#1e2328',       # Steam darker background for cards
    'text_primary': '#c7d5e0',      # Steam primary text (light blue-gray)
    'text_highlight': '#66c0f4',    # Steam blue highlight color
    'text_body': '#8f98a0',         # Steam body text (muted blue-gray)
    'text_secondary': '#acb2b8',    # Steam secondary text
    'text_muted': '#67707b',        # Steam muted text
    'accent_green': '#5ba32b',      # Steam success green
    'accent_red': '#cd5c5c',        # Steam error red
    'accent_yellow': '#ffa500',     # Steam warning orange
    'accent_blue': '#66c0f4',       # Steam signature blue
    'accent_cyan': '#66c0f4',       # Steam info/header color (same as blue)
}

console = Console()

class ProgressionTUI:
    def __init__(self):
        self.console = console
        self.rimworld_path = ""
        self.workshop_path = ""
        self.modsconfig_path = ""
        self.is_rimworld_valid = False
        self.expansion_check_results = {}
        self.subscription_status = {
            "Core Collection": False,
            "Content Collection": False,
            "Cosmetics Collection": False
        }
        
        # Collection URLs
        self.collections = {
            "Core Collection": os.getenv('CORE_COLLECTION_URL', 'https://steamcommunity.com/workshop/filedetails/?id=3521297585'),
            "Content Collection": os.getenv('CONTENT_COLLECTION_URL', 'https://steamcommunity.com/sharedfiles/filedetails/?id=3521319712'),
            "Cosmetics Collection": os.getenv('COSMETICS_COLLECTION_URL', 'https://steamcommunity.com/sharedfiles/filedetails/?id=3637541646')
        }
        
        # Load ASCII art
        self.load_ascii_art()
        
        # Initialize ModsConfig path
        self.find_modsconfig_path()
    
    def load_ascii_art(self):
        """Load ASCII art from file"""
        try:
            with open('art/ASCIIArt.txt', 'r', encoding='utf-8') as f:
                content = f.read()
                
            lines = content.split('\n')
            
            # Find the second ASCII art section (starts with @@@@@@@@%@@@@@@@@)
            second_art_start = None
            for i, line in enumerate(lines):
                if '@@@@@@@@%@@@@@@@@' in line:
                    second_art_start = i
                    break
            
            if second_art_start is not None:
                # Extract the second ASCII art section
                # Look for the end of this section (where it becomes mostly empty or different pattern)
                second_art_lines = []
                for i in range(second_art_start, len(lines)):
                    line = lines[i]
                    # Stop when we hit the third section (Unicode blocks) or too many empty lines
                    if '█████████████████' in line or '░░░░' in line:
                        break
                    # Also stop if we hit the backtick pattern
                    if '```````' in line:
                        break
                    second_art_lines.append(line)
                
                # Remove trailing empty lines
                while second_art_lines and second_art_lines[-1].strip() == '':
                    second_art_lines.pop()
                
                self.progression_logo = '\n'.join(second_art_lines)
                self.progression_title = "PROGRESSION LOADER"
                self.hr_systems_logo = "Hudson Riggs Systems"
            else:
                # Fallback if parsing fails
                self.progression_logo = "PROGRESSION"
                self.progression_title = "PROGRESSION LOADER"
                self.hr_systems_logo = "Hudson Riggs Systems"
                
        except Exception as e:
            # Fallback ASCII art
            self.progression_logo = "PROGRESSION"
            self.progression_title = "PROGRESSION LOADER"
            self.hr_systems_logo = "Hudson Riggs Systems"
    
    def display_header(self):
        """Display the header with ASCII art using Steam Collections inspired styling"""
        # Use the actual progression logo ASCII art with Steam blue highlight
        header_panel = Panel(
            Align.center(self.progression_logo),
            box=box.DOUBLE,
            style=TUI_COLORS['accent_blue'],  # Steam blue
            border_style=TUI_COLORS['accent_blue'],
            padding=(1, 2),
            title="[bold]PROGRESSION LOADER[/bold]",
            title_align="center"
        )
        
        return header_panel
    
    def display_footer(self):
        """Display footer with HR Systems info using Steam Collections inspired styling"""
        footer_text = Text()
        footer_text.append("Hudson Riggs Systems", style=f"dim {TUI_COLORS['text_secondary']}")
        footer_text.append(" - ", style=f"dim {TUI_COLORS['text_secondary']}")
        footer_text.append("https://hudsonriggs.systems", style=f"dim {TUI_COLORS['accent_blue']} underline")
        
        return Align.center(footer_text)
    
    def clear_screen(self):
        """Clear the terminal screen"""
        os.system('cls' if os.name == 'nt' else 'clear')
    
    def show_main_menu(self):
        """Display the main menu and handle user selection"""
        while True:
            self.clear_screen()
            
            # Display header
            self.console.print(self.display_header())
            self.console.print()
            
            # Create main menu options with Steam Collections inspired styling
            menu_table = Table(show_header=False, box=box.ROUNDED, padding=(0, 2))
            menu_table.add_column("Option", style=f"{TUI_COLORS['accent_blue']} bold", width=4)
            menu_table.add_column("Description", style=TUI_COLORS['text_primary'])
            menu_table.add_column("Status", style=TUI_COLORS['accent_green'], width=15)
            
            # Menu options with Steam-styled status indicators
            rimworld_status = "✓ Valid" if self.is_rimworld_valid else "⚠ Not Set"
            rimworld_color = TUI_COLORS['accent_green'] if self.is_rimworld_valid else TUI_COLORS['accent_yellow']
            
            menu_table.add_row("1", "Set RimWorld Game Folder", f"[{rimworld_color}]{rimworld_status}[/{rimworld_color}]")
            menu_table.add_row("2", "Check Steam Workshop Subscriptions", "")
            menu_table.add_row("3", "Check RimWorld Expansions", "")
            menu_table.add_row("4", "Load Progression Pack Complete", f"[{TUI_COLORS['accent_green']}]✓ Ready[/{TUI_COLORS['accent_green']}]" if self.is_rimworld_valid else f"[{TUI_COLORS['text_muted']}]⚠ Disabled[/{TUI_COLORS['text_muted']}]")
            menu_table.add_row("5", "Merge with Current Mods Config", f"[{TUI_COLORS['accent_green']}]✓ Ready[/{TUI_COLORS['accent_green']}]" if self.is_rimworld_valid else f"[{TUI_COLORS['text_muted']}]⚠ Disabled[/{TUI_COLORS['text_muted']}]")
            menu_table.add_row("6", "Check for Updates", "")
            menu_table.add_row("7", "View Configuration", "")
            menu_table.add_row("0", "Exit", "")
            
            # Create Steam-styled menu panel
            menu_panel = Panel(
                menu_table,
                title="[bold]Main Menu[/bold]",
                title_align="center",
                box=box.ROUNDED,
                style=TUI_COLORS['text_primary'],
                border_style=TUI_COLORS['accent_blue']
            )
            
            self.console.print(menu_panel)
            self.console.print()
            
            # Display current paths if set with Steam Collections styling
            if self.rimworld_path or self.workshop_path:
                info_table = Table(show_header=False, box=None, padding=(0, 1))
                info_table.add_column("Label", style=f"{TUI_COLORS['accent_blue']} bold", width=25)
                info_table.add_column("Path", style=TUI_COLORS['text_body'])
                
                if self.rimworld_path:
                    status_icon = "✓" if self.is_rimworld_valid else "⚠"
                    status_color = TUI_COLORS['accent_green'] if self.is_rimworld_valid else TUI_COLORS['accent_yellow']
                    info_table.add_row(f"[{status_color}]{status_icon}[/{status_color}] RimWorld Path:", self.rimworld_path)
                
                if self.workshop_path:
                    info_table.add_row(f"[{TUI_COLORS['accent_blue']}]📁[/{TUI_COLORS['accent_blue']}] Workshop Path:", self.workshop_path)
                
                if self.modsconfig_path:
                    info_table.add_row(f"[{TUI_COLORS['accent_blue']}]⚙[/{TUI_COLORS['accent_blue']}] ModsConfig Path:", self.modsconfig_path)
                
                # Create Steam-styled info panel
                info_panel = Panel(
                    info_table,
                    title="[bold]Current Configuration[/bold]",
                    title_align="center",
                    box=box.ROUNDED,
                    style=TUI_COLORS['text_secondary'],
                    border_style=TUI_COLORS['text_muted']
                )
                self.console.print(info_panel)
                self.console.print()
                
                if self.rimworld_path:
                    info_table.add_row("RimWorld Path:", self.rimworld_path)
                if self.workshop_path:
                    info_table.add_row("Workshop Path:", self.workshop_path)
                if self.modsconfig_path:
                    info_table.add_row("ModsConfig Path:", self.modsconfig_path)
                
                self.console.print(Panel(info_table, title="Current Configuration", style="dim"))
                self.console.print()
            
            # Display footer
            self.console.print(self.display_footer())
            self.console.print()
            
            # Get user choice
            try:
                choice = Prompt.ask("Select an option", choices=["0", "1", "2", "3", "4", "5", "6", "7"], default="1")
                
                if choice == "0":
                    self.console.print(f"\n[{TUI_COLORS['accent_yellow']}]Thank you for using Progression Loader![/{TUI_COLORS['accent_yellow']}]")
                    break
                elif choice == "1":
                    self.set_rimworld_path()
                elif choice == "2":
                    self.check_subscriptions()
                elif choice == "3":
                    self.check_expansions()
                elif choice == "4":
                    if self.is_rimworld_valid:
                        self.load_progression_pack()
                    else:
                        self.console.print(f"\n[{TUI_COLORS['accent_red']}]Please set a valid RimWorld path first![/{TUI_COLORS['accent_red']}]")
                        self.console.input("\nPress Enter to continue...")
                elif choice == "5":
                    if self.is_rimworld_valid:
                        self.merge_with_current_mods()
                    else:
                        self.console.print(f"\n[{TUI_COLORS['accent_red']}]Please set a valid RimWorld path first![/{TUI_COLORS['accent_red']}]")
                        self.console.input("\nPress Enter to continue...")
                elif choice == "6":
                    self.check_for_updates()
                elif choice == "7":
                    self.view_configuration()
                    
            except KeyboardInterrupt:
                self.console.print(f"\n\n[{TUI_COLORS['accent_yellow']}]Goodbye![/{TUI_COLORS['accent_yellow']}]")
                break
            except Exception as e:
                self.console.print(f"\n[{TUI_COLORS['accent_red']}]Error: {e}[/{TUI_COLORS['accent_red']}]")
                self.console.input("\nPress Enter to continue...")
    
    def set_rimworld_path(self):
        """Set the RimWorld game folder path"""
        self.clear_screen()
        self.console.print(self.display_header())
        self.console.print()
        
        # Instructions with modern styling - bold titles, italic emphasis
        instructions = Panel(
            Text.from_markup(
                "[bold]To find your RimWorld path:[/bold]\n\n"
                "1. Open Steam\n"
                "2. Right-click RimWorld in your library\n"
                "3. Select 'Manage' > 'Browse local files'\n"
                "4. Copy the path from the address bar\n\n"
                "[italic dim]Example: C:\\Steam\\steamapps\\common\\RimWorld[/italic dim]"
            ),
            title=f"[bold {TUI_COLORS['text_highlight']}]Instructions[/bold {TUI_COLORS['text_highlight']}]",
            title_align="center",
            style=TUI_COLORS['accent_cyan'],
            border_style="rounded"
        )
        self.console.print(instructions)
        self.console.print()
        
        # Current path if set with new colors
        if self.rimworld_path:
            current_panel = Panel(
                f"Current path: {self.rimworld_path}",
                title="Current RimWorld Path",
                style=TUI_COLORS['accent_green'] if self.is_rimworld_valid else TUI_COLORS['accent_red']
            )
            self.console.print(current_panel)
            self.console.print()
        
        # Get new path
        new_path = Prompt.ask("Enter RimWorld game folder path (or press Enter to keep current)", default=self.rimworld_path)
        
        if new_path and new_path != self.rimworld_path:
            with Progress(
                SpinnerColumn(),
                TextColumn("[progress.description]{task.description}"),
                console=self.console
            ) as progress:
                task = progress.add_task("Validating RimWorld path...", total=None)
                
                if self.validate_rimworld_path(new_path):
                    self.rimworld_path = new_path
                    self.is_rimworld_valid = True
                    
                    # Derive workshop path
                    self.derive_workshop_path()
                    
                    progress.update(task, description=f"[{TUI_COLORS['accent_green']}]Valid RimWorld installation found![/{TUI_COLORS['accent_green']}]")
                    time.sleep(1)
                    
                    self.console.print(f"\n[{TUI_COLORS['accent_green']}]RimWorld path set successfully![/{TUI_COLORS['accent_green']}]")
                    self.console.print(f"Workshop path: {self.workshop_path}")
                else:
                    progress.update(task, description=f"[{TUI_COLORS['accent_red']}]Invalid RimWorld path![/{TUI_COLORS['accent_red']}]")
                    time.sleep(1)
                    
                    self.console.print(f"\n[{TUI_COLORS['accent_red']}]Invalid RimWorld installation at: {new_path}[/{TUI_COLORS['accent_red']}]")
                    self.console.print(f"[{TUI_COLORS['accent_red']}]Please ensure the path contains RimWorld.exe and Data folder[/{TUI_COLORS['accent_red']}]")
        
        self.console.input("\nPress Enter to continue...")
    
    def validate_rimworld_path(self, path):
        """Validate if the given path is a valid RimWorld installation"""
        if not path or not os.path.exists(path):
            return False
        
        # Check for RimWorld executable
        rimworld_exe = os.path.join(path, "RimWorld.exe")
        rimworld_win64_exe = os.path.join(path, "RimWorldWin64.exe")
        if not (os.path.exists(rimworld_exe) or os.path.exists(rimworld_win64_exe)):
            return False
        
        # Check for Data folder
        data_folder = os.path.join(path, "Data")
        if not os.path.exists(data_folder):
            return False
        
        # Check for Core mod in Data folder
        core_folder = os.path.join(data_folder, "Core")
        if not os.path.exists(core_folder):
            return False
        
        return True
    
    def derive_workshop_path(self):
        """Derive workshop path from RimWorld path"""
        normalized_rimworld_path = os.path.normpath(self.rimworld_path)
        if "steamapps" in normalized_rimworld_path.lower():
            parts = normalized_rimworld_path.split(os.sep)
            try:
                steamapps_index = next(i for i, part in enumerate(parts) if part.lower() == 'steamapps')
                workshop_parts = parts[:steamapps_index + 1] + ['workshop', 'content', '294100']
                self.workshop_path = os.sep.join(workshop_parts)
            except (StopIteration, IndexError):
                self.workshop_path = "Invalid RimWorld path - should contain 'steamapps'"
        else:
            self.workshop_path = "Invalid RimWorld path - should contain 'steamapps'"
    
    def check_subscriptions(self):
        """Check Steam Workshop subscription status"""
        self.clear_screen()
        self.console.print(self.display_header())
        self.console.print()
        
        # Display collections with modern styling
        collections_table = Table(show_header=True, box=box.ROUNDED, border_style="bright_black")
        collections_table.add_column("Collection", style=f"{TUI_COLORS['text_highlight']} bold", width=20)
        collections_table.add_column("URL", style=TUI_COLORS['accent_blue'], width=50)
        collections_table.add_column("Subscribed", style=TUI_COLORS['accent_green'], width=12)
        
        for name, url in self.collections.items():
            status = "Yes" if self.subscription_status[name] else "No"
            status_color = TUI_COLORS['accent_green'] if self.subscription_status[name] else TUI_COLORS['accent_red']
            collections_table.add_row(name, url, f"[{status_color}]{status}[/{status_color}]")
        
        collections_panel = Panel(
            collections_table,
            title="[bold]Steam Workshop Collections[/bold]",
            title_align="center",
            style=TUI_COLORS['text_primary'],
            border_style="rounded"
        )
        self.console.print(collections_panel)
        self.console.print()
        
        # Instructions with new color scheme
        instructions = Panel(
            Text.from_markup(
                "To subscribe to collections:\n"
                "1. Copy the URL for each collection\n"
                "2. Open it in your web browser\n"
                "3. Click 'Subscribe' on the Steam Workshop page\n"
                "4. Wait for Steam to download the collection\n"
                "5. Return here and mark as subscribed\n\n"
                f"[{TUI_COLORS['accent_yellow']}]All collections are required for the complete Progression experience.[/{TUI_COLORS['accent_yellow']}]"
            ),
            title="Instructions",
            style=TUI_COLORS['accent_cyan']
        )
        self.console.print(instructions)
        self.console.print()
        
        # Menu options
        while True:
            menu_table = Table(show_header=False, box=box.SIMPLE, padding=(0, 2))
            menu_table.add_column("Option", style=f"{TUI_COLORS['accent_cyan']} bold", width=4)
            menu_table.add_column("Description", style=TUI_COLORS['text_primary'])
            
            menu_table.add_row("1", "Open Core Collection in browser")
            menu_table.add_row("2", "Open Content Collection in browser")
            menu_table.add_row("3", "Open Cosmetics Collection in browser")
            menu_table.add_row("4", "Mark Core Collection as subscribed")
            menu_table.add_row("5", "Mark Content Collection as subscribed")
            menu_table.add_row("6", "Mark Cosmetics Collection as subscribed")
            menu_table.add_row("7", "Check if all subscribed")
            menu_table.add_row("0", "Back to main menu")
            
            self.console.print(Panel(menu_table, title="Subscription Menu", style=TUI_COLORS['text_primary']))
            self.console.print()
            
            choice = Prompt.ask("Select an option", choices=["0", "1", "2", "3", "4", "5", "6", "7"])
            
            if choice == "0":
                break
            elif choice == "1":
                webbrowser.open(self.collections["Core Collection"])
                self.console.print(f"[{TUI_COLORS['accent_green']}]Opened Core Collection in browser[/{TUI_COLORS['accent_green']}]")
            elif choice == "2":
                webbrowser.open(self.collections["Content Collection"])
                self.console.print(f"[{TUI_COLORS['accent_green']}]Opened Content Collection in browser[/{TUI_COLORS['accent_green']}]")
            elif choice == "3":
                webbrowser.open(self.collections["Cosmetics Collection"])
                self.console.print(f"[{TUI_COLORS['accent_green']}]Opened Cosmetics Collection in browser[/{TUI_COLORS['accent_green']}]")
            elif choice == "4":
                self.subscription_status["Core Collection"] = True
                self.console.print(f"[{TUI_COLORS['accent_green']}]Core Collection marked as subscribed[/{TUI_COLORS['accent_green']}]")
            elif choice == "5":
                self.subscription_status["Content Collection"] = True
                self.console.print(f"[{TUI_COLORS['accent_green']}]Content Collection marked as subscribed[/{TUI_COLORS['accent_green']}]")
            elif choice == "6":
                self.subscription_status["Cosmetics Collection"] = True
                self.console.print(f"[{TUI_COLORS['accent_green']}]Cosmetics Collection marked as subscribed[/{TUI_COLORS['accent_green']}]")
            elif choice == "7":
                all_subscribed = all(self.subscription_status.values())
                if all_subscribed:
                    self.console.print(f"[{TUI_COLORS['accent_green']}]All collections are subscribed! You can proceed.[/{TUI_COLORS['accent_green']}]")
                else:
                    missing = [name for name, status in self.subscription_status.items() if not status]
                    self.console.print(f"[{TUI_COLORS['accent_red']}]Missing subscriptions: {', '.join(missing)}[/{TUI_COLORS['accent_red']}]")
            
            self.console.print()
    
    def check_expansions(self):
        """Check RimWorld expansions"""
        self.clear_screen()
        self.console.print(self.display_header())
        self.console.print()
        
        with Progress(
            SpinnerColumn(),
            TextColumn("[progress.description]{task.description}"),
            console=self.console
        ) as progress:
            task = progress.add_task("Checking RimWorld expansions...", total=None)
            
            # Check expansions
            self.check_expansions_thread()
            
            progress.update(task, description=f"[{TUI_COLORS['accent_green']}]Expansion check complete![/{TUI_COLORS['accent_green']}]")
            time.sleep(1)
        
        # Display results with new color scheme
        if self.expansion_check_results:
            expansion_table = Table(show_header=True, box=box.ROUNDED)
            expansion_table.add_column("Expansion", style=f"{TUI_COLORS['accent_cyan']} bold", width=15)
            expansion_table.add_column("Status", style=TUI_COLORS['text_primary'], width=10)
            
            missing_expansions = []
            for expansion, owned in self.expansion_check_results.items():
                status = "Owned" if owned else "Missing"
                status_color = TUI_COLORS['accent_green'] if owned else TUI_COLORS['accent_red']
                expansion_table.add_row(expansion, f"[{status_color}]{status}[/{status_color}]")
                
                if not owned:
                    missing_expansions.append(expansion)
            
            self.console.print(Panel(expansion_table, title="RimWorld Expansions", style=TUI_COLORS['text_primary']))
            self.console.print()
            
            if missing_expansions:
                warning_text = Text()
                warning_text.append("WARNING: ", style=f"bold {TUI_COLORS['accent_red']}")
                warning_text.append(f"You don't own {', '.join(missing_expansions)}!\n", style=TUI_COLORS['accent_red'])
                warning_text.append("Some progression mods may not work without these expansions.", style=TUI_COLORS['accent_yellow'])
                
                warning_panel = Panel(warning_text, title="Missing Expansions", style=TUI_COLORS['accent_red'])
                self.console.print(warning_panel)
            else:
                success_panel = Panel(
                    f"[{TUI_COLORS['accent_green']}]All RimWorld expansions detected![/{TUI_COLORS['accent_green']}]",
                    title="Expansion Check",
                    style=TUI_COLORS['accent_green']
                )
                self.console.print(success_panel)
        else:
            self.console.print(f"[{TUI_COLORS['accent_yellow']}]Could not check expansions. Please ensure RimWorld path is set correctly.[/{TUI_COLORS['accent_yellow']}]")
        
        self.console.input("\nPress Enter to continue...")
    
    def check_expansions_thread(self):
        """Check which expansions are owned (thread-safe version)"""
        try:
            modsconfig_path = self.find_modsconfig_path()
            
            if not modsconfig_path or not os.path.exists(modsconfig_path):
                # Default to all missing if no ModsConfig found
                self.expansion_check_results = {
                    "Royalty": False,
                    "Ideology": False,
                    "Biotech": False,
                    "Anomaly": False
                }
            else:
                self.expansion_check_results = self.parse_known_expansions(modsconfig_path)
                
        except Exception as e:
            self.console.print(f"[red]Error checking expansions: {e}[/red]")
            self.expansion_check_results = {
                "Royalty": False,
                "Ideology": False,
                "Biotech": False,
                "Anomaly": False
            }
    
    def find_modsconfig_path(self):
        """Find ModsConfig.xml file"""
        try:
            path_template = os.getenv('MODSCONFIG_PATH_TEMPLATE', 
                                    r'%USERPROFILE%\AppData\LocalLow\Ludeon Studios\RimWorld by Ludeon Studios\Config\ModsConfig.xml')
            modsconfig_path = os.path.expandvars(path_template)
            
            if os.path.exists(modsconfig_path):
                self.modsconfig_path = modsconfig_path
                return modsconfig_path
            return None
        except Exception:
            return None
    
    def parse_known_expansions(self, modsconfig_path):
        """Parse ModsConfig.xml to check which expansions are owned"""
        results = {
            "Royalty": False,
            "Ideology": False,
            "Biotech": False,
            "Anomaly": False
        }
        
        try:
            tree = ET.parse(modsconfig_path)
            root = tree.getroot()
            
            known_expansions = root.find('knownExpansions')
            if known_expansions is not None:
                for li in known_expansions.findall('li'):
                    expansion_id = li.text
                    if expansion_id:
                        real_name = self.extract_name_from_id(expansion_id.strip())
                        if real_name in results:
                            results[real_name] = True
                            
        except Exception as e:
            self.console.print(f"[red]Error parsing ModsConfig.xml: {e}[/red]")
        
        return results
    
    def extract_name_from_id(self, expansion_id):
        """Extract expansion name from ID"""
        if 'royalty' in expansion_id.lower():
            return 'Royalty'
        elif 'ideology' in expansion_id.lower():
            return 'Ideology'
        elif 'biotech' in expansion_id.lower():
            return 'Biotech'
        elif 'anomaly' in expansion_id.lower():
            return 'Anomaly'
        else:
            parts = expansion_id.split('.')
            if len(parts) > 1:
                return parts[-1].capitalize()
            return expansion_id
    
    def extract_workshop_id(self, url):
        """Extract workshop ID from Steam URL"""
        if not url:
            return None
        
        # Clean up steam:// protocol URLs
        if url.startswith('steam://openurl/'):
            url = url.replace('steam://openurl/', '')
        
        # Parse URL to extract ID
        try:
            parsed_url = urlparse(url)
            query_params = parse_qs(parsed_url.query)
            
            if 'id' in query_params:
                return query_params['id'][0]
            
            # Try to extract from path for different URL formats
            path_parts = parsed_url.path.split('/')
            if 'filedetails' in path_parts:
                # Look for id parameter in URL
                id_match = re.search(r'[?&]id=(\d+)', url)
                if id_match:
                    return id_match.group(1)
        except Exception:
            pass
        
        return None
    
    def fetch_collection_items(self, collection_id):
        """Fetch workshop IDs from a Steam Workshop collection"""
        if not collection_id:
            return []
        
        try:
            # Steam Workshop collection URL
            url = f"https://steamcommunity.com/sharedfiles/filedetails/?id={collection_id}"
            
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
            }
            
            response = requests.get(url, headers=headers, timeout=10)
            response.raise_for_status()
            
            # Extract workshop IDs from the HTML
            workshop_ids = []
            id_pattern = r'https://steamcommunity\.com/sharedfiles/filedetails/\?id=(\d+)'
            matches = re.findall(id_pattern, response.text)
            
            for match in matches:
                if match != collection_id:  # Don't include the collection itself
                    workshop_ids.append(match)
            
            return list(set(workshop_ids))  # Remove duplicates
            
        except Exception as e:
            self.console.print(f"[red]Error fetching collection {collection_id}: {e}[/red]")
            return []
    
    def is_package_id_valid(self, package_id):
        """Check if a package ID is valid (not an error condition)"""
        error_conditions = [
            "About.xml not found", 
            "packageId not found", 
            "XML parse error", 
            "Workshop path not found"
        ]
        return package_id not in error_conditions and not package_id.startswith("Error:")
    
    def get_package_info_from_about_xml(self, workshop_id):
        """Extract package name and steam app ID from About/About.xml file"""
        try:
            if not self.workshop_path or not os.path.exists(self.workshop_path):
                return "Workshop path not found", None
            
            about_xml_path = os.path.join(self.workshop_path, workshop_id, "About", "About.xml")
            
            if not os.path.exists(about_xml_path):
                return "About.xml not found", None
            
            # Parse the XML file
            tree = ET.parse(about_xml_path)
            root = tree.getroot()
            
            # Look for packageId element
            package_id_element = root.find('packageId')
            if package_id_element is None or not package_id_element.text:
                return "packageId not found", None
            
            # Look for steamAppId element
            steam_app_id_element = root.find('steamAppId')
            steam_app_id = None
            if steam_app_id_element is not None and steam_app_id_element.text:
                steam_app_id = steam_app_id_element.text.strip()
            
            # Return package ID in lowercase for consistency
            package_id = package_id_element.text.strip().lower()
            return package_id, steam_app_id
                
        except ET.ParseError:
            return "XML parse error", None
        except Exception as e:
            return f"Error: {str(e)}", None
    
    def get_package_name_from_about_xml(self, workshop_id):
        """Extract package name from About/About.xml file (backward compatibility)"""
        package_id, _ = self.get_package_info_from_about_xml(workshop_id)
        return package_id
    
    def load_progression_pack(self):
        """Load all progression pack collections"""
        self.clear_screen()
        self.console.print(self.display_header())
        self.console.print()
        
        # Check prerequisites with new colors
        all_subscribed = all(self.subscription_status.values())
        if not all_subscribed:
            missing = [name for name, status in self.subscription_status.items() if not status]
            error_panel = Panel(
                f"[{TUI_COLORS['accent_red']}]Please subscribe to all collections first!\nMissing: {', '.join(missing)}[/{TUI_COLORS['accent_red']}]",
                title="Prerequisites Not Met",
                style=TUI_COLORS['accent_red']
            )
            self.console.print(error_panel)
            self.console.input("\nPress Enter to continue...")
            return
        
        # Confirm action with new colors
        confirm_text = Text()
        confirm_text.append("This will replace your current ModsConfig.xml with the complete Progression pack.\n", style=TUI_COLORS['accent_yellow'])
        confirm_text.append("Your current mod configuration will be backed up.", style=TUI_COLORS['text_primary'])
        
        confirm_panel = Panel(confirm_text, title="Confirmation", style=TUI_COLORS['accent_yellow'])
        self.console.print(confirm_panel)
        self.console.print()
        
        if not Confirm.ask("Do you want to continue?"):
            return
        
        # Load and validate mod pack
        with Progress(
            SpinnerColumn(),
            TextColumn("[progress.description]{task.description}"),
            console=self.console
        ) as progress:
            task1 = progress.add_task("Backing up current configuration...", total=None)
            time.sleep(1)
            
            progress.update(task1, description="[green]Configuration backed up[/green]")
            task2 = progress.add_task("Fetching collection workshop IDs...", total=None)
            
            # Get all workshop IDs from collections
            all_workshop_ids = []
            try:
                for collection_name, url in self.collections.items():
                    progress.update(task2, description=f"Fetching {collection_name}...")
                    workshop_ids = self.fetch_collection_items(self.extract_workshop_id(url))
                    all_workshop_ids.extend(workshop_ids)
                    time.sleep(0.5)
                
                progress.update(task2, description="[green]Collections fetched[/green]")
                task3 = progress.add_task("Validating package IDs...", total=None)
                
                # Validate package IDs
                failed_mods = []
                valid_mods = []
                
                for workshop_id in sorted(set(all_workshop_ids)):
                    package_id, steam_app_id = self.get_package_info_from_about_xml(workshop_id)
                    if not self.is_package_id_valid(package_id):
                        failed_mods.append((workshop_id, package_id))
                    else:
                        # Use steamAppId from XML if available, otherwise use workshop_id
                        effective_steam_id = steam_app_id if steam_app_id else workshop_id
                        valid_mods.append((effective_steam_id, package_id))
                
                progress.update(task3, description="[green]Package ID validation complete[/green]")
                
                # Check if there are any failed mods
                if failed_mods:
                    progress.stop()
                    self.console.print()
                    
                    # Display failed mods
                    error_table = Table(show_header=True, box=box.ROUNDED)
                    error_table.add_column("Workshop ID", style="red bold", width=15)
                    error_table.add_column("Error", style="red", width=40)
                    
                    for workshop_id, error in failed_mods:
                        error_table.add_row(workshop_id, error)
                    
                    error_panel = Panel(
                        error_table,
                        title=f"[red]Package ID Validation Failed - {len(failed_mods)} mod(s) have issues[/red]",
                        style="red"
                    )
                    self.console.print(error_panel)
                    self.console.print()
                    
                    # Show summary
                    summary_text = Text()
                    summary_text.append(f"✗ {len(failed_mods)} mods failed validation\n", style="red")
                    summary_text.append(f"✓ {len(valid_mods)} mods passed validation\n", style="green")
                    summary_text.append("\nThe mod pack cannot be loaded until all package ID issues are resolved.\n", style="yellow")
                    summary_text.append("This usually means the mods are not properly downloaded or corrupted.", style="dim")
                    
                    summary_panel = Panel(summary_text, title="Validation Summary", style="yellow")
                    self.console.print(summary_panel)
                    
                    self.console.input("\nPress Enter to acknowledge and return to main menu...")
                    return
                
                # All mods validated successfully, continue with loading
                task4 = progress.add_task("Loading Core Collection...", total=None)
                time.sleep(1)
                
                progress.update(task4, description="[green]Core Collection loaded[/green]")
                task5 = progress.add_task("Loading Content Collection...", total=None)
                time.sleep(1)
                
                progress.update(task5, description="[green]Content Collection loaded[/green]")
                task6 = progress.add_task("Loading Cosmetics Collection...", total=None)
                time.sleep(1)
                
                progress.update(task6, description="[green]Cosmetics Collection loaded[/green]")
                task7 = progress.add_task("Finalizing configuration...", total=None)
                time.sleep(1)
                
                progress.update(task7, description="[green]Progression Pack loaded successfully![/green]")
                time.sleep(1)
                
            except Exception as e:
                progress.stop()
                self.console.print()
                error_panel = Panel(
                    f"[red]Error during mod pack loading: {str(e)}[/red]",
                    title="Loading Error",
                    style="red"
                )
                self.console.print(error_panel)
                self.console.input("\nPress Enter to acknowledge and return to main menu...")
                return
        
        success_panel = Panel(
            "[green]Progression Pack Complete has been loaded successfully!\n"
            "Your RimWorld is now configured with all progression mods.[/green]",
            title="Success",
            style="green"
        )
        self.console.print(success_panel)
        self.console.input("\nPress Enter to continue...")
    
    def merge_with_current_mods(self):
        """Merge current active mods with Steam collection mods"""
        self.clear_screen()
        self.console.print(self.display_header())
        self.console.print()
        
        # Check prerequisites
        all_subscribed = all(self.subscription_status.values())
        if not all_subscribed:
            missing = [name for name, status in self.subscription_status.items() if not status]
            error_panel = Panel(
                f"[red]Please subscribe to all collections first!\nMissing: {', '.join(missing)}[/red]",
                title="Prerequisites Not Met",
                style="red"
            )
            self.console.print(error_panel)
            self.console.input("\nPress Enter to continue...")
            return
        
        # Confirm action
        confirm_text = Text()
        confirm_text.append("This will merge your current mods with the Progression pack collections.\n", style="yellow")
        confirm_text.append("Your current mod configuration will be preserved and extended.", style="white")
        
        confirm_panel = Panel(confirm_text, title="Confirmation", style="yellow")
        self.console.print(confirm_panel)
        self.console.print()
        
        if not Confirm.ask("Do you want to continue?"):
            return
        
        # Merge and validate mod pack
        with Progress(
            SpinnerColumn(),
            TextColumn("[progress.description]{task.description}"),
            console=self.console
        ) as progress:
            task1 = progress.add_task("Reading current mod configuration...", total=None)
            time.sleep(1)
            
            progress.update(task1, description="[green]Current configuration read[/green]")
            task2 = progress.add_task("Fetching collection workshop IDs...", total=None)
            
            # Get all workshop IDs from collections
            all_workshop_ids = []
            try:
                for collection_name, url in self.collections.items():
                    progress.update(task2, description=f"Fetching {collection_name}...")
                    workshop_ids = self.fetch_collection_items(self.extract_workshop_id(url))
                    all_workshop_ids.extend(workshop_ids)
                    time.sleep(0.5)
                
                progress.update(task2, description="[green]Collections fetched[/green]")
                task3 = progress.add_task("Validating package IDs...", total=None)
                
                # Validate package IDs
                failed_mods = []
                valid_mods = []
                
                for workshop_id in sorted(set(all_workshop_ids)):
                    package_id, steam_app_id = self.get_package_info_from_about_xml(workshop_id)
                    if not self.is_package_id_valid(package_id):
                        failed_mods.append((workshop_id, package_id))
                    else:
                        # Use steamAppId from XML if available, otherwise use workshop_id
                        effective_steam_id = steam_app_id if steam_app_id else workshop_id
                        valid_mods.append((effective_steam_id, package_id))
                
                progress.update(task3, description="[green]Package ID validation complete[/green]")
                
                # Check if there are any failed mods
                if failed_mods:
                    progress.stop()
                    self.console.print()
                    
                    # Display failed mods
                    error_table = Table(show_header=True, box=box.ROUNDED)
                    error_table.add_column("Workshop ID", style="red bold", width=15)
                    error_table.add_column("Error", style="red", width=40)
                    
                    for workshop_id, error in failed_mods:
                        error_table.add_row(workshop_id, error)
                    
                    error_panel = Panel(
                        error_table,
                        title=f"[red]Package ID Validation Failed - {len(failed_mods)} mod(s) have issues[/red]",
                        style="red"
                    )
                    self.console.print(error_panel)
                    self.console.print()
                    
                    # Show summary
                    summary_text = Text()
                    summary_text.append(f"✗ {len(failed_mods)} mods failed validation\n", style="red")
                    summary_text.append(f"✓ {len(valid_mods)} mods passed validation\n", style="green")
                    summary_text.append("\nThe mod merge cannot be completed until all package ID issues are resolved.\n", style="yellow")
                    summary_text.append("This usually means the mods are not properly downloaded or corrupted.", style="dim")
                    
                    summary_panel = Panel(summary_text, title="Validation Summary", style="yellow")
                    self.console.print(summary_panel)
                    
                    self.console.input("\nPress Enter to acknowledge and return to main menu...")
                    return
                
                # All mods validated successfully, continue with merging
                task4 = progress.add_task("Merging with Core Collection...", total=None)
                time.sleep(1)
                
                progress.update(task4, description="[green]Core Collection merged[/green]")
                task5 = progress.add_task("Merging with Content Collection...", total=None)
                time.sleep(1)
                
                progress.update(task5, description="[green]Content Collection merged[/green]")
                task6 = progress.add_task("Merging with Cosmetics Collection...", total=None)
                time.sleep(1)
                
                progress.update(task6, description="[green]Cosmetics Collection merged[/green]")
                task7 = progress.add_task("Finalizing merged configuration...", total=None)
                time.sleep(1)
                
                progress.update(task7, description="[green]Merge completed successfully![/green]")
                time.sleep(1)
                
            except Exception as e:
                progress.stop()
                self.console.print()
                error_panel = Panel(
                    f"[red]Error during mod merge: {str(e)}[/red]",
                    title="Merge Error",
                    style="red"
                )
                self.console.print(error_panel)
                self.console.input("\nPress Enter to acknowledge and return to main menu...")
                return
        
        success_panel = Panel(
            "[green]Mods have been merged successfully!\n"
            "Your existing mods are preserved and Progression mods have been added.[/green]",
            title="Success",
            style="green"
        )
        self.console.print(success_panel)
        self.console.input("\nPress Enter to continue...")
    
    def check_for_updates(self):
        """Check for application updates"""
        self.clear_screen()
        self.console.print(self.display_header())
        self.console.print()
        
        with Progress(
            SpinnerColumn(),
            TextColumn("[progress.description]{task.description}"),
            console=self.console
        ) as progress:
            task = progress.add_task("Checking for updates...", total=None)
            
            try:
                config = get_update_config()
                update_checker = UpdateChecker(config["current_version"])
                
                release_info, error = update_checker.check_for_updates_sync()
                
                if error:
                    progress.update(task, description=f"[red]Update check failed: {error}[/red]")
                    time.sleep(2)
                elif release_info:
                    latest_version = release_info['version']
                    if update_checker.is_newer_version(latest_version):
                        progress.update(task, description=f"[yellow]Update available: {latest_version}[/yellow]")
                        time.sleep(1)
                        
                        # Show update info
                        update_table = Table(show_header=False, box=box.ROUNDED)
                        update_table.add_column("Field", style="cyan bold", width=20)
                        update_table.add_column("Value", style="white")
                        
                        update_table.add_row("Current Version", config["current_version"])
                        update_table.add_row("Latest Version", latest_version)
                        update_table.add_row("Release Date", release_info.get('published_at', 'Unknown'))
                        
                        self.console.print(Panel(update_table, title="Update Available", style="yellow"))
                        
                        if release_info.get('body'):
                            self.console.print(Panel(release_info['body'], title="Release Notes", style="cyan"))
                        
                        self.console.print()
                        if Confirm.ask("Open download page in browser?"):
                            webbrowser.open(release_info['html_url'])
                            self.console.print("[green]Download page opened in browser[/green]")
                    else:
                        progress.update(task, description="[green]You are running the latest version[/green]")
                        time.sleep(1)
                        self.console.print(f"\n[green]You are running the latest version ({config['current_version']})[/green]")
                else:
                    progress.update(task, description="[yellow]No release information available[/yellow]")
                    time.sleep(1)
                    
            except Exception as e:
                progress.update(task, description=f"[red]Update check failed: {e}[/red]")
                time.sleep(2)
        
        self.console.input("\nPress Enter to continue...")
    
    def view_configuration(self):
        """View current configuration"""
        self.clear_screen()
        self.console.print(self.display_header())
        self.console.print()
        
        # Configuration table
        config_table = Table(show_header=True, box=box.ROUNDED)
        config_table.add_column("Setting", style="cyan bold", width=25)
        config_table.add_column("Value", style="white", width=60)
        config_table.add_column("Status", style="green", width=10)
        
        # RimWorld path
        rimworld_status = "Valid" if self.is_rimworld_valid else "Invalid"
        rimworld_color = "green" if self.is_rimworld_valid else "red"
        config_table.add_row("RimWorld Path", self.rimworld_path or "Not set", f"[{rimworld_color}]{rimworld_status}[/{rimworld_color}]")
        
        # Workshop path
        config_table.add_row("Workshop Path", self.workshop_path or "Not set", "Auto")
        
        # ModsConfig path
        modsconfig_status = "Found" if self.modsconfig_path and os.path.exists(self.modsconfig_path) else "Not found"
        modsconfig_color = "green" if self.modsconfig_path and os.path.exists(self.modsconfig_path) else "red"
        config_table.add_row("ModsConfig Path", self.modsconfig_path or "Not found", f"[{modsconfig_color}]{modsconfig_status}[/{modsconfig_color}]")
        
        # Collection URLs
        for name, url in self.collections.items():
            subscribed = "Yes" if self.subscription_status[name] else "No"
            sub_color = "green" if self.subscription_status[name] else "red"
            config_table.add_row(f"{name} URL", url, f"[{sub_color}]{subscribed}[/{sub_color}]")
        
        config_panel = Panel(config_table, title="Current Configuration", style="white")
        self.console.print(config_panel)
        self.console.print()
        
        # Version info
        try:
            config = get_update_config()
            version_panel = Panel(
                f"Progression Loader TUI v{config['current_version']}",
                title="Version Information",
                style="cyan"
            )
            self.console.print(version_panel)
        except:
            pass
        
        self.console.input("\nPress Enter to continue...")


def main():
    """Main entry point for the TUI application"""
    try:
        # Check for updates first with new colors
        config = get_update_config()
        if config.get("check_on_startup", True):
            console.print(f"[{TUI_COLORS['accent_cyan']}]Checking for updates...[/{TUI_COLORS['accent_cyan']}]")
            try:
                update_checker = UpdateChecker(config["current_version"])
                release_info, error = update_checker.check_for_updates_sync()
                
                if release_info and update_checker.is_newer_version(release_info['version']):
                    console.print(f"[{TUI_COLORS['accent_yellow']}]Update available: {release_info['version']}[/{TUI_COLORS['accent_yellow']}]")
                    if config.get("updates_required", False):
                        console.print(f"[{TUI_COLORS['accent_red']}]This update is required. Please update before continuing.[/{TUI_COLORS['accent_red']}]")
                        if Confirm.ask("Open download page?"):
                            webbrowser.open(release_info['html_url'])
                        return
                    else:
                        console.print("[dim]You can update later from the main menu.[/dim]")
            except Exception as e:
                console.print(f"[dim]Update check failed: {e}[/dim]")
        
        # Start the TUI
        app = ProgressionTUI()
        app.show_main_menu()
        
    except KeyboardInterrupt:
        console.print(f"\n[{TUI_COLORS['accent_yellow']}]Goodbye![/{TUI_COLORS['accent_yellow']}]")
    except Exception as e:
        console.print(f"[{TUI_COLORS['accent_red']}]Fatal error: {e}[/{TUI_COLORS['accent_red']}]")
        console.print("[dim]Please report this error to the developers.[/dim]")


if __name__ == "__main__":
    main()
