#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Simple UI module - Provides a tkinter-based GUI for selecting paths and running wizard
"""

import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os
import sys

# Add parent directory to path for imports (check both root and code/ subfolder)
script_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, script_dir)

# Check if code folder exists (for reorganized structure)
code_dir = os.path.join(script_dir, "code")
if os.path.exists(code_dir):
    sys.path.insert(0, code_dir)

from modules.utils import (  # type: ignore
    get_last_calibre_library, verify_library_path, SCRIPT_VERSION,
    is_cloud_synced_location, check_write_permissions
)


class GUIWizard(tk.Tk):
    """Full GUI-based wizard for configuration"""
    
    # Use module-level SCRIPT_VERSION
    script_version = SCRIPT_VERSION
    
    def __init__(self, existing_config=None):
        super().__init__()
        
        self.title("Kindle Key Finder - Configuration Wizard")
        self.geometry("700x600")
        self.resizable(False, False)
        
        # Default paths
        self.user_home = os.path.expanduser("~")
        self.default_kindle_path = os.path.join(self.user_home, "Documents", "My Kindle Content")
        # Project root is one level above the code/ subfolder that contains this file
        # script_dir resolves to .../Kindle_Key_Finder/code, so we go one level up
        _project_root = os.path.dirname(script_dir)
        self.default_extracted_books_path = os.path.join(_project_root, "Extracted_Books")

        # Check if the script is running from a cloud-synced folder or a non-writable location.
        # If so, we must redirect the Extracted_Books default to AppData so that decrypted
        # book files don't end up inside OneDrive/Google Drive/Dropbox and cause sync issues.
        _is_cloud, _cloud_service = is_cloud_synced_location(_project_root)
        _can_write, _ = check_write_permissions(_project_root)
        if _is_cloud or not _can_write:
            _appdata_local = os.environ.get(
                'LOCALAPPDATA',
                os.path.join(self.user_home, "AppData", "Local")
            )
            self.default_extracted_books_path = os.path.join(
                _appdata_local, "Kindle_Key_Finder", "Extracted_Books"
            )
            self._cloud_path_detected = True
            self._cloud_service = _cloud_service if _is_cloud else "Non-writable location"
        else:
            self._cloud_path_detected = False
            self._cloud_service = None

        # Configuration results
        self.config = {}
        self.wizard_complete = False
        self.canceled = False
        
        # Current wizard step
        self.current_step = 0
        self.total_steps = 12
        
        # Initialize tk variables with defaults so finish_wizard() never fails
        # even if the user exits before reaching the step that creates them
        self.kfx_zip_mode_var = tk.StringVar(value="delete_kfx_zip")
        self.source_file_management_var = tk.StringVar(value="delete_originals")
        self.extraction_mode_var = tk.StringVar(value="auto")
        self.generate_pdf_comics_var = tk.BooleanVar(value=False)
        
        # Load existing config values if provided (RECONFIGURE mode)
        self.existing_config = existing_config
        self._load_existing_config()
        
        # Style setup
        self.setup_styles()
        
        # Create main container
        self.container = ttk.Frame(self)
        self.container.pack(fill="both", expand=True)
        
        # Start wizard
        self.show_step()
        self.center_window()
    
    def _load_existing_config(self):
        """Load existing configuration values into wizard variables"""
        if not self.existing_config:
            return
        
        # Load all config values as instance variables for use in wizard steps
        # Step 1: Kindle path
        kindle_path = self.existing_config.get('kindle_content_path', self.default_kindle_path)
        if kindle_path:
            self.default_kindle_path = kindle_path

        # Step 2: Extracted Books Path (alternate method output folder)
        extracted_books_path = self.existing_config.get('extracted_books_path', self.default_extracted_books_path)
        if extracted_books_path:
            self.default_extracted_books_path = extracted_books_path

        # Step 3: Key Extraction Mode (auto vs KFXArchiver-only)
        force_alt = self.existing_config.get('debug_force_alt_method', False)
        self.extraction_mode_var = tk.StringVar(value="archiver_only" if force_alt else "auto")

        # Step 4: APPDATA preference
        self.appdata_var = tk.BooleanVar(value=self.existing_config.get('always_use_appdata', False))

        # Step 5: Privacy settings
        self.privacy_var = tk.BooleanVar(value=self.existing_config.get('hide_sensitive_info', False))

        # Step 6: Clear screen
        self.clear_screen_var = tk.BooleanVar(value=self.existing_config.get('clear_screen_between_phases', False))

        # Step 7: Skip pauses
        self.skip_pauses_var = tk.BooleanVar(value=self.existing_config.get('skip_phase_pauses', True))

        # Step 8: Auto-launch
        self.auto_launch_var = tk.BooleanVar(value=self.existing_config.get('auto_launch_kindle', False))

        # Step 9: Calibre import
        calibre_config = self.existing_config.get('calibre_import', {})
        self.calibre_enabled_var = tk.BooleanVar(value=calibre_config.get('enabled', True))
        self.calibre_path_var = tk.StringVar(value=calibre_config.get('library_path', ''))
        self.convert_epub_var = tk.BooleanVar(value=calibre_config.get('convert_to_epub', True))

        # Step 10: KFX-ZIP mode
        self.kfx_zip_mode_var = tk.StringVar(value=calibre_config.get('kfx_zip_mode', 'delete_kfx_zip'))

        # Step 11: Source file management
        self.source_file_management_var = tk.StringVar(value=calibre_config.get('source_file_management', 'delete_originals'))

        # Step 12: Generate PDF for comics / manga
        self.generate_pdf_comics_var = tk.BooleanVar(value=calibre_config.get('generate_pdf_for_comics', False))

    def setup_styles(self):
        """Setup custom styles"""
        style = ttk.Style()
        style.configure("Title.TLabel", font=("Arial", 16, "bold"))
        style.configure("Step.TLabel", font=("Arial", 12), foreground="#666")
        style.configure("Header.TLabel", font=("Arial", 11, "bold"))
        style.configure("Question.TLabel", font=("Arial", 10))
    
    def center_window(self):
        """Center the window on screen"""
        self.update_idletasks()
        width = self.winfo_width()
        height = self.winfo_height()
        x = (self.winfo_screenwidth() // 2) - (width // 2)
        y = (self.winfo_screenheight() // 2) - (height // 2)
        self.geometry(f'{width}x{height}+{x}+{y}')
    
    def clear_frame(self):
        """Clear all widgets from container"""
        for widget in self.container.winfo_children():
            widget.destroy()
    
    def show_step(self):
        """Display the current wizard step"""
        self.clear_frame()
        
        # Header with progress
        header = ttk.Frame(self.container, padding="20")
        header.pack(fill="x")
        
        ttk.Label(header, text=f"Configuration Wizard - Step {self.current_step + 1} of {self.total_steps}", 
                  style="Title.TLabel").pack()
        
        # Progress bar
        progress = ttk.Progressbar(header, mode='determinate', length=400)
        progress.pack(pady=10, fill="x")
        progress['value'] = ((self.current_step + 1) / self.total_steps) * 100
        
        # Content frame
        content = ttk.Frame(self.container, padding="20")
        content.pack(fill="both", expand=True)
        
        # Show appropriate step (adjust for conditional steps)
        if self.current_step == 0:
            self.step_kindle_path(content)
        elif self.current_step == 1:
            self.step_extracted_books_path(content)
        elif self.current_step == 2:
            self.step_extraction_mode(content)
        elif self.current_step == 3:
            self.step_appdata(content)
        elif self.current_step == 4:
            self.step_privacy(content)
        elif self.current_step == 5:
            self.step_clear_screen(content)
        elif self.current_step == 6:
            self.step_skip_pauses(content)
        elif self.current_step == 7:
            self.step_auto_launch(content)
        elif self.current_step == 8:
            self.step_calibre_import(content)
        elif self.current_step == 9:
            self.step_kfx_zip_mode(content)
        elif self.current_step == 10:
            # Only show step 11 (source file management) if EPUB conversion is enabled
            if self.convert_epub_var.get():
                self.step_source_file_management(content)
            else:
                # EPUB conversion disabled - skip remaining steps and finish
                self.finish_wizard()
                return
        elif self.current_step == 11:
            # Step 12: Generate PDF for comics (only reachable when EPUB conversion is on)
            self.step_generate_pdf_comics(content)
    
    def step_kindle_path(self, parent):
        """Step 1: Kindle path selection"""
        ttk.Label(parent, text="Kindle Books Location", style="Header.TLabel").pack(anchor="w", pady=(0, 10))
        
        ttk.Label(parent, text="Select the folder containing your Kindle books:").pack(anchor="w")
        
        path_frame = ttk.Frame(parent)
        path_frame.pack(fill="x", pady=10)
        
        self.kindle_path_var = tk.StringVar(value=self.default_kindle_path)
        ttk.Entry(path_frame, textvariable=self.kindle_path_var, width=50).pack(side="left", fill="x", expand=True)
        ttk.Button(path_frame, text="Browse...", command=self.browse_kindle).pack(side="left", padx=5)
        
        self.kindle_validation_label = ttk.Label(parent, text="", foreground="red")
        self.kindle_validation_label.pack(anchor="w")
        
        # Navigation
        self.wizard_navigation(parent, next_enabled=True, prev_enabled=False)
    
    def step_extracted_books_path(self, parent):
        """Step 2: Extracted Books output folder (alternate method)"""
        ttk.Label(parent, text="Extracted Books Output Folder", style="Header.TLabel").pack(anchor="w", pady=(0, 10))

        ttk.Label(parent, text="Folder where decrypted kfx-zip books will be saved.").pack(anchor="w")
        ttk.Label(parent, text="Used only when the Alternate Method - KFXArchive (KFXArchiver) is active.",
                  foreground="#555").pack(anchor="w", pady=(2, 0))
        ttk.Label(parent, text="The folder will be created automatically if it does not exist.",
                  foreground="#555").pack(anchor="w")

        # If the script is running from a cloud drive or non-writable location, show a notice
        # explaining why we redirected the default path to AppData.
        if getattr(self, '_cloud_path_detected', False):
            notice_frame = ttk.Frame(parent, padding=(0, 6, 0, 0))
            notice_frame.pack(fill="x")
            notice_bg = tk.Frame(notice_frame, bg="#fff3cd", relief="solid", bd=1)
            notice_bg.pack(fill="x")
            service_name = getattr(self, '_cloud_service', 'cloud drive') or 'cloud drive'
            tk.Label(
                notice_bg,
                text=f"  Cloud/restricted location detected: {service_name}",
                bg="#fff3cd", fg="#856404", font=("Arial", 9, "bold"), anchor="w"
            ).pack(fill="x", padx=4, pady=(4, 0))
            tk.Label(
                notice_bg,
                text="  Defaulted to AppData to avoid sync conflicts.",
                bg="#fff3cd", fg="#856404", font=("Arial", 9), anchor="w"
            ).pack(fill="x", padx=4)
            tk.Label(
                notice_bg,
                text="  The script uses the same AppData path at runtime - no action needed.",
                bg="#fff3cd", fg="#856404", font=("Arial", 9), anchor="w"
            ).pack(fill="x", padx=4, pady=(0, 4))

        path_frame = ttk.Frame(parent)
        path_frame.pack(fill="x", pady=10)

        if not hasattr(self, 'extracted_books_path_var'):
            self.extracted_books_path_var = tk.StringVar(value=self.default_extracted_books_path)
        ttk.Entry(path_frame, textvariable=self.extracted_books_path_var, width=50).pack(side="left", fill="x", expand=True)
        ttk.Button(path_frame, text="Browse...", command=self.browse_extracted_books).pack(side="left", padx=5)

        ttk.Label(parent, text=f"Default: {self.default_extracted_books_path}",
                  foreground="#888").pack(anchor="w")

        # Warning label shown when user browses to a cloud or non-writable folder
        self._extracted_books_warning_label = tk.Label(
            parent, text="", font=("Arial", 9), anchor="w", justify="left",
            wraplength=620
        )
        self._extracted_books_warning_label.pack(fill="x", pady=(4, 0))

        self.wizard_navigation(parent)

    def step_extraction_mode(self, parent):
        """Step 3: Key Extraction Mode"""
        ttk.Label(parent, text="Key Extraction Modes", style="Header.TLabel").pack(anchor="w", pady=(0, 10))

        ttk.Label(parent, text="The script has 2 methods of key extraction (KFXKeyExtractor & KFXArchiver).").pack(anchor="w")
        ttk.Label(parent, text="Please choose a method:").pack(anchor="w", pady=(2, 8))

        # Only set default if not already set
        if not hasattr(self, 'extraction_mode_var'):
            self.extraction_mode_var = tk.StringVar(value="auto")

        ttk.Radiobutton(parent, text="Mode A (Auto) - Recommended", variable=self.extraction_mode_var,
                       value="auto").pack(anchor="w", pady=(0, 2))
        ttk.Label(parent, text="    Uses KFXKeyExtractor first. If it fails to extract a key,",
                  foreground="#555").pack(anchor="w")
        ttk.Label(parent, text="    it will automatically retry using KFXArchiver.",
                  foreground="#555").pack(anchor="w")

        ttk.Separator(parent, orient="horizontal").pack(fill="x", pady=8)

        ttk.Radiobutton(parent, text="Mode B - KFXArchiver Only", variable=self.extraction_mode_var,
                       value="archiver_only").pack(anchor="w", pady=(0, 2))
        ttk.Label(parent, text="    Uses KFXArchiver for all books.",
                  foreground="#555").pack(anchor="w")
        ttk.Label(parent, text="    Note: Phase 2 (DeDRM Configuration) will be skipped.",
                  foreground="#888").pack(anchor="w")
        ttk.Label(parent, text="    Note: DeDRM Plugin is NOT required for this mode.",
                  foreground="#888").pack(anchor="w")
        ttk.Label(parent, text="          Only the KFX Input Plugin needs to be installed in Calibre.",
                  foreground="#888").pack(anchor="w")

        self.wizard_navigation(parent)

    def step_appdata(self, parent):
        """Step 4: APPDATA preference"""
        ttk.Label(parent, text="Working Directory Preference", style="Header.TLabel").pack(anchor="w", pady=(0, 10))
        
        ttk.Label(parent, text="Store keys, logs, and config in APPDATA folder?").pack(anchor="w")
        
        # Get the actual APPDATA path for Windows
        appdata_info = os.path.join(os.environ.get('LOCALAPPDATA', os.path.join(self.user_home, "AppData", "Local")), "Kindle_Key_Finder")
        ttk.Label(parent, text=f"APPDATA location: {appdata_info}").pack(anchor="w", pady=5)
        
        # Only set default if not already set
        if not hasattr(self, 'appdata_var'):
            self.appdata_var = tk.BooleanVar(value=False)
        ttk.Radiobutton(parent, text="Yes - Always use APPDATA", variable=self.appdata_var, 
                       value=True).pack(anchor="w", pady=2)
        ttk.Radiobutton(parent, text="No - Auto-detect best location (Recommended)", variable=self.appdata_var, 
                       value=False).pack(anchor="w", pady=2)
        
        self.wizard_navigation(parent)
    
    def step_privacy(self, parent):
        """Step 5: Privacy settings"""
        ttk.Label(parent, text="Privacy Settings", style="Header.TLabel").pack(anchor="w", pady=(0, 10))
        
        ttk.Label(parent, text="Hide sensitive information in console output?").pack(anchor="w")
        
        ttk.Label(parent, text="This includes DSN, tokens, and key data.").pack(anchor="w", pady=5)
        
        # Only set default if not already set
        if not hasattr(self, 'privacy_var'):
            self.privacy_var = tk.BooleanVar(value=False)
        ttk.Radiobutton(parent, text="Yes - Hide sensitive info", variable=self.privacy_var, 
                       value=True).pack(anchor="w", pady=2)
        ttk.Radiobutton(parent, text="No - Show all info (Recommended)", variable=self.privacy_var, 
                       value=False).pack(anchor="w", pady=2)
        
        self.wizard_navigation(parent)
    
    def step_clear_screen(self, parent):
        """Step 6: Clear screen between phases"""
        ttk.Label(parent, text="Display Options", style="Header.TLabel").pack(anchor="w", pady=(0, 10))
        
        ttk.Label(parent, text="Clear screen between each phase for cleaner output?").pack(anchor="w")
        
        # Only set default if not already set
        if not hasattr(self, 'clear_screen_var'):
            self.clear_screen_var = tk.BooleanVar(value=False)
        ttk.Radiobutton(parent, text="No - Keep all output (Recommended)", variable=self.clear_screen_var,
                       value=False).pack(anchor="w", pady=2)
        ttk.Radiobutton(parent, text="Yes - Clear screen between phases", variable=self.clear_screen_var,
                       value=True).pack(anchor="w", pady=2)
        
        self.wizard_navigation(parent)
    
    def step_skip_pauses(self, parent):
        """Step 7: Skip phase pauses"""
        ttk.Label(parent, text="Phase Pause Settings", style="Header.TLabel").pack(anchor="w", pady=(0, 10))
        
        ttk.Label(parent, text="Skip countdown pauses between phases for faster execution?").pack(anchor="w")
        
        # Only set default if not already set
        if not hasattr(self, 'skip_pauses_var'):
            self.skip_pauses_var = tk.BooleanVar(value=True)
        ttk.Radiobutton(parent, text="No - Show pauses for visibility", variable=self.skip_pauses_var, 
                       value=False).pack(anchor="w", pady=2)
        ttk.Radiobutton(parent, text="Yes - Skip pauses  (Recommended)", variable=self.skip_pauses_var, 
                       value=True).pack(anchor="w", pady=2)
        
        self.wizard_navigation(parent)
    
    def step_auto_launch(self, parent):
        """Step 8: Auto-launch Kindle"""
        ttk.Label(parent, text="Auto-Launch Kindle", style="Header.TLabel").pack(anchor="w", pady=(0, 10))
        
        ttk.Label(parent, text="Automatically launch Kindle.exe before extraction?").pack(anchor="w")
        
        ttk.Label(parent, text="The script will wait for Kindle to close before scanning books.").pack(anchor="w", pady=5)
        
        # Only set default if not already set
        if not hasattr(self, 'auto_launch_var'):
            self.auto_launch_var = tk.BooleanVar(value=False)
        ttk.Radiobutton(parent, text="No", variable=self.auto_launch_var, 
                       value=False).pack(anchor="w", pady=2)
        ttk.Radiobutton(parent, text="Yes - Auto-launch Kindle", variable=self.auto_launch_var, 
                       value=True).pack(anchor="w", pady=2)
        
        self.wizard_navigation(parent)
    
    def step_calibre_import(self, parent):
        """Step 9: Calibre import"""
        ttk.Label(parent, text="Calibre Auto-Import", style="Header.TLabel").pack(anchor="w", pady=(0, 10))
        
        ttk.Label(parent, text="Enable automatic ebook import to perform DeDRM.").pack(anchor="w")
        
        # Only set default if not already set
        if not hasattr(self, 'calibre_enabled_var'):
            self.calibre_enabled_var = tk.BooleanVar(value=True)
        ttk.Radiobutton(parent, text="No - Skip Calibre import", variable=self.calibre_enabled_var, 
                       value=False, command=self.toggle_calibre_options).pack(anchor="w", pady=2)
        ttk.Radiobutton(parent, text="Yes - Configure Calibre import (Recommended)", variable=self.calibre_enabled_var, 
                       value=True, command=self.toggle_calibre_options).pack(anchor="w", pady=2)
        
        # Calibre options frame
        self.calibre_frame = ttk.LabelFrame(parent, text="Calibre Options", padding="10")
        self.calibre_frame.pack(fill="x", pady=10)
        self.calibre_frame.pack_forget()  # Hidden by default
        
        ttk.Label(self.calibre_frame, text="Library Path:").pack(anchor="w")
        calibre_path_frame = ttk.Frame(self.calibre_frame)
        calibre_path_frame.pack(fill="x", pady=5)
        if not hasattr(self, 'calibre_path_var'):
            self.calibre_path_var = tk.StringVar()
            # Auto-detect Calibre library path
            auto_detected_path = get_last_calibre_library()
            if auto_detected_path:
                # Verify the auto-detected path is valid
                valid, error, book_count = verify_library_path(auto_detected_path)
                if valid:
                    self.calibre_path_var.set(auto_detected_path)
        
        ttk.Entry(calibre_path_frame, textvariable=self.calibre_path_var, width=40).pack(side="left", fill="x", expand=True)
        ttk.Button(calibre_path_frame, text="Browse...", command=self.browse_calibre).pack(side="left", padx=5)
        
        # Validation label for Calibre path
        self.calibre_validation_label = ttk.Label(self.calibre_frame, text="", foreground="red")
        self.calibre_validation_label.pack(anchor="w", pady=(5, 0))
        
        ttk.Label(self.calibre_frame, text="Convert imported books to EPUB?").pack(anchor="w", pady=(10, 0))
        if not hasattr(self, 'convert_epub_var'):
            self.convert_epub_var = tk.BooleanVar(value=True)
        ttk.Radiobutton(self.calibre_frame, text="No", variable=self.convert_epub_var, value=False,
                       command=self.update_calibre_navigation).pack(anchor="w")
        ttk.Radiobutton(self.calibre_frame, text="Yes - Convert to EPUB (Recommended)", variable=self.convert_epub_var, value=True,
                       command=self.update_calibre_navigation).pack(anchor="w")
        
        self.toggle_calibre_options()
        
        # Determine if this is the last step based on selections
        # If calibre is disabled OR convert to epub is disabled, this is the last step
        is_last_step = not self.calibre_enabled_var.get() or not self.convert_epub_var.get()
        self.wizard_navigation(parent, last_step=is_last_step)
    
    def update_calibre_navigation(self):
        """Update the navigation button when Calibre or EPUB settings change"""
        # Only update if we're on step 9 (calibre import, index 8)
        if self.current_step == 8:
            # Use after_idle to defer the update and avoid recursion
            self.after_idle(self._do_update_calibre_navigation)
    
    def _do_update_calibre_navigation(self):
        """Actually perform the navigation update (called via after_idle)"""
        is_last_step = not self.calibre_enabled_var.get() or not self.convert_epub_var.get()
        
        # Find the navigation frame and update the button
        for widget in self.container.winfo_children():
            if isinstance(widget, ttk.Frame):
                # Check if this is the nav frame by looking for the button
                for child in widget.winfo_children():
                    # Check both tk.Button and ttk.Button
                    if isinstance(child, (tk.Button, ttk.Button)):
                        # Get current button text to identify which button it is
                        # The rightmost button is our Next/Finish button
                        try:
                            btn_text = child.cget("text")
                            if "Next" in btn_text or "Finish" in btn_text or "Save" in btn_text:
                                # This is our button - update its command/text
                                if is_last_step:
                                    child.config(text="Finish & Save", command=self.finish_wizard)
                                else:
                                    child.config(text="Next >", command=self.next_step)
                                return
                        except:
                            pass
    
    def step_kfx_zip_mode(self, parent):
        """Step 10: KFX-ZIP file handling"""
        ttk.Label(parent, text="KFX-ZIP File Handling", style="Header.TLabel").pack(anchor="w", pady=(0, 10))
        
        ttk.Label(parent, text="KFX-ZIP files are usually the result of FAILED DeDRM attempts.").pack(anchor="w")
        
        # Only set default if not already set (to preserve selection when going back)
        # Note: _load_existing_config() may have already set this if reconfiguring
        if not hasattr(self, 'kfx_zip_mode_var'):
            self.kfx_zip_mode_var = tk.StringVar(value="delete_kfx_zip")
        
        ttk.Radiobutton(parent, text="Delete All KFX-ZIP Files (Recommended)", variable=self.kfx_zip_mode_var, 
                       value="delete_kfx_zip").pack(anchor="w", pady=2)
        ttk.Radiobutton(parent, text="Keep All KFX-ZIP Files", variable=self.kfx_zip_mode_var, 
                       value="keep").pack(anchor="w", pady=2)
        
        # Warning about keeping KFX-ZIP files
        ttk.Label(parent, text="WARNING: If you keep KFX-ZIP files and try to re-import the same book,", 
                  foreground="orange").pack(anchor="w", pady=(10, 0))
        ttk.Label(parent, text="Calibre will detect it as already imported and skip the DeDRM process.", 
                  foreground="orange").pack(anchor="w")
        
        self.wizard_navigation(parent)
    
    def step_source_file_management(self, parent):
        """Step 11: Source file management"""
        ttk.Label(parent, text="Source File Management", style="Header.TLabel").pack(anchor="w", pady=(0, 10))
        
        ttk.Label(parent, text="What to do with original files after DeDRM processing usually KFX format?").pack(anchor="w")
        
        # Only set default if not already set (to preserve selection when going back)
        # Note: _load_existing_config() may have already set this if reconfiguring
        if not hasattr(self, 'source_file_management_var'):
            self.source_file_management_var = tk.StringVar(value="delete_originals")
        ttk.Radiobutton(parent, text="Keep Both", variable=self.source_file_management_var, 
                       value="keep_both").pack(anchor="w", pady=2)
        ttk.Radiobutton(parent, text="Delete Originals (Recommended)", variable=self.source_file_management_var, 
                       value="delete_originals").pack(anchor="w", pady=2)

        # Step 11 is no longer the last step - step 12 (Generate PDF Comics) follows
        self.wizard_navigation(parent, last_step=False)

    def step_generate_pdf_comics(self, parent):
        """Step 12: Auto-convert Comics/Manga to PDF"""
        ttk.Label(parent, text="What are you DeDRMing?", style="Header.TLabel").pack(anchor="w", pady=(0, 6))
        ttk.Label(parent, text="* Only important if you have enabled Auto Convert (EPUB conversion).",
                  foreground="#555").pack(anchor="w", pady=(0, 10))

        if not hasattr(self, 'generate_pdf_comics_var'):
            self.generate_pdf_comics_var = tk.BooleanVar(value=False)

        ttk.Radiobutton(
            parent,
            text="A) Ebooks Only  (Convert KFX -> EPUB)",
            variable=self.generate_pdf_comics_var,
            value=False
        ).pack(anchor="w", pady=2)

        ttk.Radiobutton(
            parent,
            text="B) Also generate PDF for Comics / Manga / Magazine  (Convert KFX -> EPUB + PDF)",
            variable=self.generate_pdf_comics_var,
            value=True
        ).pack(anchor="w", pady=2)

        note_frame = tk.Frame(parent, bg="#e8f4fd", relief="solid", bd=1)
        note_frame.pack(fill="x", pady=(12, 0))
        tk.Label(note_frame, text="  Notes:", bg="#e8f4fd", fg="#0c5460",
                 font=("Arial", 9, "bold"), anchor="w").pack(fill="x", padx=4, pady=(6, 0))
        tk.Label(note_frame,
                 text="  - Ebooks Only: script will convert KFX to EPUB only.",
                 bg="#e8f4fd", fg="#0c5460", font=("Arial", 9), anchor="w").pack(fill="x", padx=4)
        tk.Label(note_frame,
                 text="  - Comics/Manga/Magazine: script will convert KFX to EPUB AND also generate a PDF",
                 bg="#e8f4fd", fg="#0c5460", font=("Arial", 9), anchor="w").pack(fill="x", padx=4)
        tk.Label(note_frame,
                 text="    for any book auto-detected as a comic, manga, or magazine.",
                 bg="#e8f4fd", fg="#0c5460", font=("Arial", 9), anchor="w").pack(fill="x", padx=4)
        tk.Label(note_frame,
                 text="  - Detection uses Kindle's book_asset.db. If that file is unavailable,",
                 bg="#e8f4fd", fg="#0c5460", font=("Arial", 9), anchor="w").pack(fill="x", padx=4)
        tk.Label(note_frame,
                 text="    all books default to EPUB only (no error is raised).",
                 bg="#e8f4fd", fg="#0c5460", font=("Arial", 9), anchor="w").pack(fill="x", padx=4, pady=(0, 6))

        self.wizard_navigation(parent, last_step=True)

    def toggle_calibre_options(self):
        """Show/hide calibre options based on enabled state"""
        if self.calibre_enabled_var.get():
            self.calibre_frame.pack(fill="x", pady=10)
        else:
            self.calibre_frame.pack_forget()
        
        # Update navigation when Calibre toggle changes
        self.update_calibre_navigation()
    
    def wizard_navigation(self, parent, next_enabled=True, prev_enabled=True, last_step=False):
        """Create navigation buttons"""
        # Footer with version and URL (pack first so it appears at bottom)
        footer_frame = ttk.Frame(self.container)
        footer_frame.pack(side="bottom", fill="x")
        
        # Divider line
        ttk.Separator(footer_frame, orient="horizontal").pack(side="top", fill="x")
        
        # Version and URL labels
        version_label = ttk.Label(footer_frame, text=f"v{self.script_version}", font=("Arial", 8), foreground="#999")
        version_label.pack(side="left", padx=5, pady=5)
        
        url_label = ttk.Label(footer_frame, text="Techy-Notes.com", font=("Arial", 8), foreground="#999")
        url_label.pack(side="right", padx=5, pady=5)
        
        # Navigation buttons (pack second so they appear above footer)
        nav_frame = ttk.Frame(self.container, padding="20")
        nav_frame.pack(side="bottom", fill="x")
        
        # Back button
        if prev_enabled:
            ttk.Button(nav_frame, text="< Back", command=self.prev_step).pack(side="left")
        else:
            ttk.Label(nav_frame, text="").pack(side="left")  # Spacer
        
        # Cancel button
        ttk.Button(nav_frame, text="Cancel", command=self.cancel).pack(side="right", padx=5)
        
        # Next/Finish button
        if last_step:
            ttk.Button(nav_frame, text="Finish & Save", command=self.finish_wizard).pack(side="right")
        else:
            ttk.Button(nav_frame, text="Next >", command=self.next_step).pack(side="right")
    
    def browse_kindle(self):
        """Browse for Kindle books folder"""
        path = filedialog.askdirectory(title="Select Kindle Books Location", 
                                       initialdir=self.default_kindle_path)
        if path:
            self.kindle_path_var.set(path)
            # Validate and show result
            if os.path.exists(path):
                azw_count = len([f for f in os.listdir(path) if f.lower().endswith('.azw')])
                if azw_count > 0:
                    self.kindle_validation_label.config(text=f"✓ Found {azw_count} .azw files", foreground="green")
                else:
                    self.kindle_validation_label.config(text="⚠ No .azw files found", foreground="orange")
    
    def browse_extracted_books(self):
        """Browse for Extracted Books output folder"""
        current = self.extracted_books_path_var.get().strip() if hasattr(self, 'extracted_books_path_var') else self.default_extracted_books_path
        initial = current if os.path.exists(current) else os.path.dirname(current)
        path = filedialog.askdirectory(title="Select Extracted Books Output Folder", initialdir=initial)
        if path:
            self.extracted_books_path_var.set(path)
            self._validate_extracted_books_path(path)

    def _validate_extracted_books_path(self, path):
        """Validate the extracted books path for cloud/write issues and update warning label"""
        # Only run if the warning label widget exists (it is created in step_extracted_books_path)
        if not hasattr(self, '_extracted_books_warning_label'):
            return

        is_cloud, cloud_service = is_cloud_synced_location(path)
        can_write, write_error = check_write_permissions(path) if os.path.exists(path) else (True, None)

        if is_cloud:
            service_name = cloud_service or "cloud drive"
            self._extracted_books_warning_label.config(
                text=(
                    f"  Cloud folder detected: {service_name}\n"
                    f"  Saving decrypted books here may cause sync conflicts or access errors.\n"
                    f"  Consider choosing a local folder outside {service_name}."
                ),
                foreground="#856404",
                background="#fff3cd",
                relief="solid",
                borderwidth=1,
                justify="left",
                anchor="w"
            )
        elif not can_write:
            self._extracted_books_warning_label.config(
                text=(
                    f"  Selected folder is not writable.\n"
                    f"  The script may not be able to save decrypted books here.\n"
                    f"  Consider choosing a different location."
                ),
                foreground="#721c24",
                background="#f8d7da",
                relief="solid",
                borderwidth=1,
                justify="left",
                anchor="w"
            )
        else:
            # Path is fine - clear any previous warning
            self._extracted_books_warning_label.config(
                text="",
                background=self.cget("bg"),
                relief="flat",
                borderwidth=0
            )

    def browse_calibre(self):
        """Browse for Calibre library"""
        path = filedialog.askdirectory(title="Select Calibre Library Location")
        if path:
            # Check for metadata.db
            if os.path.exists(os.path.join(path, "metadata.db")):
                self.calibre_path_var.set(path)
            else:
                messagebox.showwarning("Invalid Library", "This doesn't appear to be a valid Calibre library.")
    
    def next_step(self):
        """Go to next wizard step"""
        # Validate current step
        if self.current_step == 0:
            if not self.kindle_path_var.get().strip():
                messagebox.showerror("Error", "Please select a Kindle books location")
                return
            if not os.path.exists(self.kindle_path_var.get().strip()):
                messagebox.showerror("Error", "The selected path does not exist")
                return
        
        # Validate step 9 (Calibre import, index 8)
        if self.current_step == 8:
            if self.calibre_enabled_var.get():
                library_path = self.calibre_path_var.get().strip()
                if not library_path:
                    messagebox.showerror("Error", "Please enter a Calibre library path")
                    return
                
                valid, error, book_count = verify_library_path(library_path)
                if not valid:
                    messagebox.showerror("Error", f"Invalid Calibre library: {error}")
                    return
        
        self.current_step += 1
        self.show_step()
    
    def prev_step(self):
        """Go to previous wizard step"""
        self.current_step -= 1
        self.show_step()
    
    def cancel(self):
        """Cancel the wizard"""
        self.canceled = True
        self.destroy()
    
    def finish_wizard(self):
        """Complete the wizard and save configuration"""
        # Determine if EPUB conversion is enabled
        epub_enabled = self.calibre_enabled_var.get() and self.convert_epub_var.get()
        
        # If EPUB conversion is not enabled, always keep original files
        if not epub_enabled:
            source_file_management = "keep_both"
        else:
            # Only ask about source file management if EPUB conversion is enabled
            source_file_management = getattr(self, 'source_file_management_var', tk.StringVar(value="keep_both")).get()
        
        # Resolve extracted_books_path (use var if set, else fall back to default)
        extracted_books_path = self.default_extracted_books_path
        if hasattr(self, 'extracted_books_path_var'):
            val = self.extracted_books_path_var.get().strip()
            if val:
                extracted_books_path = val

        # Collect all settings
        # Step 3 selection: True = KFXArchiver-only (Mode B), False = Auto (Mode A)
        self.config = {
            'kindle_content_path': self.kindle_path_var.get().strip(),
            'extracted_books_path': extracted_books_path,
            'debug_force_alt_method': self.extraction_mode_var.get() == "archiver_only",
            'always_use_appdata': self.appdata_var.get(),
            'hide_sensitive_info': self.privacy_var.get(),
            'clear_screen_between_phases': self.clear_screen_var.get(),
            'skip_phase_pauses': self.skip_pauses_var.get(),
            'auto_launch_kindle': self.auto_launch_var.get(),
            'enable_raw_logs': True,
            'calibre_import': {
                'enabled': self.calibre_enabled_var.get(),
                'library_path': self.calibre_path_var.get().strip() if self.calibre_enabled_var.get() else "",
                'convert_to_epub': epub_enabled,
                'kfx_zip_mode': self.kfx_zip_mode_var.get(),
                'source_file_management': source_file_management,
                'generate_pdf_for_comics': self.generate_pdf_comics_var.get() if epub_enabled else False
            }
        }
        
        self.wizard_complete = True
        self.destroy()
    
    def get_config(self):
        """Return the configuration"""
        return self.config


class SimplePathSelector(tk.Tk):
    """Simple GUI for selecting Kindle and Calibre paths"""
    
    # Use module-level SCRIPT_VERSION from key_finder.py
    SCRIPT_VERSION = SCRIPT_VERSION
    
    def __init__(self):
        super().__init__()
        
        self.title("Kindle Key Finder")
        self.geometry("600x450")
        self.resizable(False, False)
        
        # Default paths
        self.user_home = os.path.expanduser("~")
        self.default_kindle_path = os.path.join(self.user_home, "Documents", "My Kindle Content")
        
        # Results
        self.kindle_path = ""
        self.calibre_path = ""
        self.use_gui_wizard = False
        self.config = None
        
        self.create_widgets()
        self.center_window()
    
    def center_window(self):
        """Center the window on screen"""
        self.update_idletasks()
        width = self.winfo_width()
        height = self.winfo_height()
        x = (self.winfo_screenwidth() // 2) - (width // 2)
        y = (self.winfo_screenheight() // 2) - (height // 2)
        self.geometry(f'{width}x{height}+{x}+{y}')
    
    def create_widgets(self):
        """Create GUI widgets"""
        # Setup styles
        style = ttk.Style()
        style.configure("Accent.TButton", font=("Arial", 11, "bold"))
        style.map("Accent.TButton", foreground=[('active', 'white')], background=[('active', '#0078D4')])
        
        # Title
        title_label = tk.Label(self, text="Kindle Key Finder", font=("Arial", 18, "bold"))
        title_label.pack(pady=20)
        
        # Subtitle
        tk.Label(self, text="Extract Kindle DRM keys for DeDRM", font=("Arial", 10), 
                fg="#666").pack(pady=(0, 20))
        
        # Main buttons frame
        button_frame = ttk.Frame(self, padding="30")
        button_frame.pack(fill="both", expand=True)
        
        # Quick Extract button
        quick_frame = ttk.LabelFrame(button_frame, text="Quick Start", padding="15")
        quick_frame.pack(fill="x", pady=5)
        ttk.Label(quick_frame, text="Select your Kindle books folder and extract keys immediately").pack()
        ttk.Button(quick_frame, text="Quick Extract", command=self.run_simple,
                  style="Accent.TButton").pack(pady=10)
        
        # Configuration Wizard button
        wizard_frame = ttk.LabelFrame(button_frame, text="Full Setup", padding="15")
        wizard_frame.pack(fill="x", pady=5)
        ttk.Label(wizard_frame, text="Configure all settings including Calibre import").pack()
        ttk.Button(wizard_frame, text="Configuration Wizard", command=self.run_gui_wizard,
                  style="Accent.TButton").pack(pady=10)
        
        # Quit button
        ttk.Button(self, text="Quit", command=self.quit_app).pack(side="bottom", pady=15)
        
        # Version label (bottom left)
        ttk.Label(self, text=f"v{self.SCRIPT_VERSION}", font=("Arial", 8), 
                 foreground="#999").pack(side="bottom", padx=5, pady=(0, 5), anchor="w")
    
    def run_simple(self):
        """Run simple mode with path selection"""
        # Ask for Kindle path
        path = filedialog.askdirectory(
            title="Select Kindle Books Location",
            initialdir=self.default_kindle_path
        )
        
        if not path:
            return
        
        # Validate path
        if not os.path.exists(path):
            messagebox.showerror("Error", "The selected path does not exist")
            return
        
        self.kindle_path = path
        self.destroy()
    
    def run_gui_wizard(self):
        """Run the GUI wizard"""
        self.use_gui_wizard = True
        self.destroy()
    
    def quit_app(self):
        """Quit the application"""
        self.kindle_path = None
        self.destroy()


def run_gui_wizard(existing_config=None):
    """Launch the full GUI wizard
    
    Args:
        existing_config: Optional dict of existing configuration values to pre-populate the wizard
    """
    app = GUIWizard(existing_config=existing_config)
    app.mainloop()
    
    if app.canceled:
        return None
    
    if app.wizard_complete:
        return app.get_config()
    
    return None


def select_paths():
    """
    Launch the simple UI and return selected paths
    Returns: (kindle_path, config) or (None, None) if cancelled
    """
    app = SimplePathSelector()
    app.mainloop()
    
    if app.kindle_path is None:
        return None, None
    
    if app.use_gui_wizard:
        # Run GUI wizard instead
        config = run_gui_wizard()
        if config:
            return config.get('kindle_content_path'), config
        return None, None
    
    # Simple mode - return path with basic config
    config = {
        'kindle_content_path': app.kindle_path,
        'calibre_import': {
            'enabled': False,
            'library_path': '',
            'convert_to_epub': False
        }
    }
    
    return app.kindle_path, config


# Standalone test - Launch directly in Configuration Wizard mode
if __name__ == "__main__":
    config = run_gui_wizard()
    if config:
        print(f"Configuration saved: {config}")
    else:
        print("Configuration wizard cancelled")
