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

"""
Configuration module - Contains configuration loading, saving, and wizard functions
"""

import os
import sys
import json
import shutil
import time
import threading
import msvcrt
from datetime import datetime

# Import from utils module
from .utils import (
    print_colored, print_step, print_ok, print_warn, print_error, print_done,
    print_banner_and_version, display_phase_banner, display_phase_summary,
    check_write_permissions, is_cloud_synced_location, get_disk_space,
    is_calibre_running, get_library_book_count, verify_library_path,
    prompt_manual_library_path, get_last_calibre_library, SCRIPT_VERSION,
    KFXKEYEXTRACTOR_VERSION
)


CONFIG_FILE = "key_finder_config.json"

# Module-level tracker so callers can see which file was actually loaded.
# Set by load_config() on every successful load.
_last_loaded_path: str | None = None


def load_config() -> dict | None:
    """Load unified configuration from JSON file
    
    Priority Logic:
    1. If user configured 'always_use_appdata', use AppData config
    2. If script directory is writable, prefer script directory config
    3. Otherwise, fall back to AppData config
    
    After a successful load, the path is stored in the module-level
    variable _last_loaded_path so callers can display it to the user.
    """
    global _last_loaded_path
    # Go up two directories from code/modules/config.py to get to project root
    script_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    user_home = os.path.expanduser("~")
    
    # Define paths
    script_config_path = os.path.join(script_dir, CONFIG_FILE)
    fallback_base = os.path.join(user_home, "AppData", "Local", "Kindle_Key_Finder")
    fallback_config_path = os.path.join(fallback_base, CONFIG_FILE)
    
    # Check if script directory is writable
    can_write_script_dir, _ = check_write_permissions(script_dir)
    
    # Priority 1: If script directory is writable AND has a config, use it
    if can_write_script_dir and os.path.exists(script_config_path):
        try:
            with open(script_config_path, 'r') as f:
                config = json.load(f)
            
            # Check if user has forced AppData usage
            if config.get('always_use_appdata', False):
                # User wants AppData - check if AppData config exists
                if os.path.exists(fallback_config_path):
                    try:
                        with open(fallback_config_path, 'r') as f:
                            appdata_config = json.load(f)
                        _last_loaded_path = fallback_config_path
                        return appdata_config
                    except Exception as e:
                        print_warn(f"Failed to load AppData config: {e}")
                        _last_loaded_path = script_config_path
                        return config
            
            _last_loaded_path = script_config_path
            return config
        except Exception as e:
            print_warn(f"Failed to load configuration from script directory: {e}")
    
    # Priority 2: Check AppData location
    if os.path.exists(fallback_config_path):
        try:
            with open(fallback_config_path, 'r') as f:
                config = json.load(f)
            
            # If we found AppData config but script directory is now writable,
            # check if user forced AppData usage
            if can_write_script_dir and not config.get('always_use_appdata', False):
                # Script directory is writable and user didn't force AppData
                # This means user likely moved from cloud to local folder
                # We should prefer the local folder now
                print_warn("Found config in AppData, but script directory is now writable")
                print_warn("Preferring local directory - AppData config will be migrated on next save")
            
            _last_loaded_path = fallback_config_path
            return config
        except Exception as e:
            print_warn(f"Failed to load configuration from AppData: {e}")
    
    # Priority 3: Check script directory as last resort (even if not writable)
    if os.path.exists(script_config_path):
        try:
            with open(script_config_path, 'r') as f:
                config = json.load(f)
            _last_loaded_path = script_config_path
            return config
        except Exception as e:
            print_warn(f"Failed to load configuration from script directory: {e}")
    
    _last_loaded_path = None
    return None


def save_config(config):
    """Save unified configuration to JSON file"""
    # Go up two directories from code/modules/config.py to get to project root
    script_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    user_home = os.path.expanduser("~")
    
    can_write, error = check_write_permissions(script_dir)
    
    if can_write:
        config_path = os.path.join(script_dir, CONFIG_FILE)
    else:
        fallback_base = os.path.join(user_home, "AppData", "Local", "Kindle_Key_Finder")
        config_path = os.path.join(fallback_base, CONFIG_FILE)
    
    try:
        os.makedirs(os.path.dirname(config_path), exist_ok=True)
        
        config['script_version'] = SCRIPT_VERSION
        config['kfxkeyextractor_version'] = KFXKEYEXTRACTOR_VERSION
        config['last_updated'] = datetime.now().isoformat()

        # Preserve debug flags from the existing saved config so that a wizard
        # run does not reset them. The wizard builds a fresh dict with no debug
        # keys, so we must carry the on-disk value over before falling back to
        # the False default.
        # debug_force_alt_method: Forces the entire script into primary ALT mode
        #   (uses KFXArchiver282.exe for all books instead of KFXKeyExtractor28)
        # debug_force_alt_retry: Injects a fake Phase 1 failure on one book,
        #   triggering the Phase 1b/3b fallback retry path for testing
        existing = load_config()
        if 'debug_force_alt_method' not in config:
            config['debug_force_alt_method'] = (existing or {}).get('debug_force_alt_method', False)
        if 'debug_force_alt_retry' not in config:
            config['debug_force_alt_retry'] = (existing or {}).get('debug_force_alt_retry', False)
        
        with open(config_path, 'w') as f:
            json.dump(config, f, indent=2)
        
        print_ok(f"Configuration saved to: {config_path}")
        return True
    except Exception as e:
        print_error(f"Failed to save configuration: {e}")
        return False


def check_config_version(config):
    """Check if config version matches current script version"""
    config_version = config.get('script_version', 'Unknown')
    is_valid = (config_version == SCRIPT_VERSION)
    return is_valid, config_version, SCRIPT_VERSION


def delete_config():
    """Delete configuration file"""
    # Go up two directories from code/modules/config.py to get to project root
    script_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    config_path = os.path.join(script_dir, CONFIG_FILE)
    
    try:
        if os.path.exists(config_path):
            os.remove(config_path)
            print_ok("Configuration deleted")
            return True
        return False
    except Exception as e:
        print_error(f"Failed to delete configuration: {e}")
        return False


def display_config_summary(config):
    """Display configuration summary in table format"""
    print_step("Current Configuration:")
    print()
    
    print("┌─────────────────────────────┬──────────────────────────────────────────────────────────────────────────┐")
    print("│ Setting                     │ Value                                                                    │")
    print("├─────────────────────────────┼──────────────────────────────────────────────────────────────────────────┤")
    
    # Kindle Content Path
    content_path = config.get('kindle_content_path', 'Not set')
    if len(content_path) > 72:
        content_path = content_path[:69] + "..."
    print(f"│ Kindle Content Path         │ {content_path:<72} │")
    
    # Always Use APPDATA
    always_appdata = "Yes (forced)" if config.get('always_use_appdata', False) else "No (auto-detect)"
    print(f"│ Always Use APPDATA          │ {always_appdata:<72} │")

    # Extracted Books Path (alternate method output folder)
    extracted_books_path = config.get('extracted_books_path', 'Not configured')
    if len(extracted_books_path) > 72:
        extracted_books_path = extracted_books_path[:69] + "..."
    print(f"│ Extracted Books Path        │ {extracted_books_path:<72} │")

    # Key Extraction Mode
    force_alt = config.get('debug_force_alt_method', False)
    extraction_mode = "Mode B - KFXArchiver Only" if force_alt else "Mode A - Auto (KFXKeyExtractor + KFXArchiver fallback)"
    print(f"│ Key Extraction Mode         │ {extraction_mode:<72} │")

    # Hide Sensitive Info
    hide_sensitive = "Yes" if config.get('hide_sensitive_info', False) else "No"
    print(f"│ Hide Sensitive Info         │ {hide_sensitive:<72} │")
    
    # Fetch Book Titles
    fetch_titles = "Yes" if config.get('fetch_book_titles', False) else "No"
    print(f"│ Fetch Book Titles           │ {fetch_titles:<72} │")
    
    # Clear Screen Between Phases
    clear_screen = "Yes" if config.get('clear_screen_between_phases', False) else "No"
    print(f"│ Clear Screen Between Phases │ {clear_screen:<72} │")
    
    # Skip Phase Pauses
    skip_pauses = "Yes" if config.get('skip_phase_pauses', False) else "No"
    print(f"│ Skip Phase Pauses           │ {skip_pauses:<72} │")
    
    # Auto-Launch Kindle
    auto_launch = "Yes" if config.get('auto_launch_kindle', False) else "No"
    print(f"│ Auto-Launch Kindle          │ {auto_launch:<72} │")
    
    # Raw Debug Logs
    raw_logs = "Yes" if config.get('enable_raw_logs', False) else "No"
    print(f"│ Raw Debug Logs              │ {raw_logs:<72} │")
    
    # Calibre Import section
    if 'calibre_import' in config:
        cal = config['calibre_import']
        calibre_status = "Enabled" if cal.get('enabled') else "Disabled"
        print(f"│ Calibre Import              │ {calibre_status:<72} │")
        
        if cal.get('enabled'):
            lib_path = cal.get('library_path', 'Not set')
            book_count = get_library_book_count(lib_path) if lib_path != 'Not set' else None
            
            if book_count is not None:
                display_path = f"{lib_path} ({book_count} books)"
            else:
                display_path = f"{lib_path} (Unknown books)"
            
            if len(display_path) > 72:
                display_path = display_path[:69] + "..."
            print(f"│   Library Path              │ {display_path:<72} │")
            
            convert_epub = "Yes" if cal.get('convert_to_epub', False) else "No"
            print(f"│   Convert to EPUB           │ {convert_epub:<72} │")

            kfx_zip_raw = cal.get('kfx_zip_mode', 'delete_kfx_zip')
            kfx_zip_display = {
                'delete_kfx_zip': 'Delete KFX-ZIP after import',
                'keep': 'Keep KFX-ZIP files',
                'convert_all': 'Convert all to EPUB'
            }.get(kfx_zip_raw, kfx_zip_raw)
            print(f"│   KFX-ZIP Mode              │ {kfx_zip_display:<72} │")

            src_mgmt_raw = cal.get('source_file_management', 'delete_originals')
            src_mgmt_display = {
                'delete_originals': 'Delete originals after import',
                'keep_both': 'Keep both files'
            }.get(src_mgmt_raw, src_mgmt_raw)
            print(f"│   Source File Mgmt          │ {src_mgmt_display:<72} │")

            gen_pdf = cal.get('generate_pdf_for_comics', False)
            gen_pdf_display = "Yes - EPUB + PDF for Comics/Manga" if gen_pdf else "No - EPUB Only"
            print(f"│   Generate PDF (Comics)     │ {gen_pdf_display:<72} │")
    else:
        print(f"│ Calibre Import              │ {'Not configured':<72} │")
    
    print("└─────────────────────────────┴──────────────────────────────────────────────────────────────────────────┘")
    print()


def prompt_config_action_with_timer(config):
    """Display config and timer with interrupt capability"""
    print_step("Configuration Found")
    print("--------------------------------------------------")
    display_config_summary(config)
    
    # Validate Calibre library path if Calibre import is enabled
    if 'calibre_import' in config and config['calibre_import'].get('enabled', False):
        lib_path = config['calibre_import'].get('library_path')
        if lib_path:
            print_step("Validating saved Calibre library path...")
            valid, error, book_count = verify_library_path(lib_path)
            
            if not valid:
                print()
                print_error("SAVED LIBRARY PATH IS INVALID!")
                print(f"  Path: {lib_path}")
                print(f"  Error: {error}")
                print()
                print_warn("The saved Calibre library path is no longer valid.")
                print()
                print("Options:")
                print("  [R] Reconfigure - Update library path")
                print("  [D] Disable - Turn off Calibre import")
                print("  [Q] Quit - Exit script")
                print()
                
                while True:
                    choice = input("Your choice (R/D/Q): ").strip().upper()
                    if choice == 'R':
                        print()
                        return 'reconfigure'
                    elif choice == 'D':
                        print()
                        print_step("Disabling Calibre import...")
                        config['calibre_import']['enabled'] = False
                        save_config(config)
                        print_ok("Calibre import disabled")
                        print()
                        return 'use'
                    elif choice == 'Q':
                        print()
                        return 'quit'
                    else:
                        print_error("Invalid choice. Please enter R, D, or Q.")
            else:
                if book_count is not None:
                    print_ok(f"Library path validated: {book_count} books found")
                else:
                    print_ok("Library path validated")
                print()
    
    skip_pauses = config.get('skip_phase_pauses', False)
    countdown_seconds = 3 if skip_pauses else 5
    
    print(f"Press any key to show options, or wait {countdown_seconds} seconds to use saved configuration...")
    print()
    
    timer_cancelled = threading.Event()
    user_interrupted = threading.Event()
    countdown_active = True
    
    def countdown_timer():
        nonlocal countdown_active
        for i in range(countdown_seconds, 0, -1):
            if timer_cancelled.is_set() or user_interrupted.is_set():
                countdown_active = False
                return
            print(f"\rCountdown: {i} seconds... ", end='', flush=True)
            time.sleep(1)
        countdown_active = False
        if not user_interrupted.is_set():
            print("\r" + " " * 50 + "\r", end='', flush=True)
            print_ok("Auto-proceeding with saved configuration")
            timer_cancelled.set()
    
    timer_thread = threading.Thread(target=countdown_timer, daemon=True)
    timer_thread.start()
    
    while countdown_active:
        if msvcrt.kbhit():
            msvcrt.getch()
            user_interrupted.set()
            timer_cancelled.set()
            print("\r" + " " * 50 + "\r", end='', flush=True)
            break
        time.sleep(0.05)
    
    if not user_interrupted.is_set():
        return 'use'
    
    print()
    print_step("Configuration Options:")
    print("  [U] Use saved configuration")
    print("  [R] Reconfigure settings")
    print("  [D] Delete saved config and reconfigure")
    print("  [Q] Quit script")
    print()
    
    while True:
        choice = input("Your choice (U/R/D/Q): ").strip().upper()
        if choice == 'U':
            print()
            return 'use'
        elif choice == 'R':
            print()
            return 'reconfigure'
        elif choice == 'D':
            print()
            delete_config()
            return 'reconfigure'
        elif choice == 'Q':
            print()
            return 'quit'
        else:
            print_error("Invalid choice. Please enter U, R, D, or Q.")


def validate_kindle_path(path: str) -> dict:
    """Validate Kindle content path for books and database"""
    result = {
        "books_found": 0,
        "db_found": False
    }
    
    try:
        if not os.path.exists(path):
            return result
        
        for root, dirs, files in os.walk(path):
            for file in files:
                if file.lower().endswith('.azw'):
                    result["books_found"] += 1
                if file.lower() == "book_asset.db":
                    result["db_found"] = True
        
        return result
        
    except Exception as e:
        print_warn(f"Error validating path: {e}")
        return result


def get_kindle_content_path(default_path, use_timer=False):
    """Prompt user to confirm or modify the Kindle content directory path"""
    import threading
    
    print_step("Kindle-4-PC Book's Path Configuration")
    print("--------------------------------------------------")
    print(f"Default path: {default_path}")
    print()
    
    if use_timer:
        print_warn("Press Enter to accept default immediately, or ANY KEY to Stop Timer")
        print("(Auto-proceeding with default in 5 seconds if no input...)")
    else:
        print("Press Enter to accept default, or start typing your NEW custom path below:")
    print()
    
    timer_cancelled = threading.Event()
    user_input_started = threading.Event()
    countdown_active = use_timer
    
    def countdown_timer():
        nonlocal countdown_active
        if not use_timer:
            return
        for i in range(5, 0, -1):
            if timer_cancelled.is_set() or user_input_started.is_set():
                countdown_active = False
                return
            print(f"\rCountdown: {i} seconds... ", end='', flush=True)
            time.sleep(1)
        countdown_active = False
        if not user_input_started.is_set():
            print("\r" + " " * 50 + "\r", end='', flush=True)
            print_ok("Auto-proceeding with default path")
            timer_cancelled.set()
    
    if use_timer:
        timer_thread = threading.Thread(target=countdown_timer, daemon=True)
        timer_thread.start()
    
    user_input = ""
    input_buffer = []
    
    while countdown_active or user_input_started.is_set() or not use_timer:
        if msvcrt.kbhit():
            char = msvcrt.getwche()
            
            if not user_input_started.is_set():
                user_input_started.set()
                if use_timer:
                    timer_cancelled.set()
                    print("\r" + " " * 50 + "\r", end='', flush=True)
                
                if char == '\r':
                    print()
                    user_input = ""
                    break
                else:
                    print("> ", end='', flush=True)
                    print(char, end='', flush=True)
                    input_buffer.append(char)
            else:
                if char == '\r':
                    print()
                    user_input = ''.join(input_buffer)
                    break
                elif char == '\b':
                    if input_buffer:
                        input_buffer.pop()
                        print(' \b', end='', flush=True)
                else:
                    input_buffer.append(char)
        elif not countdown_active and not user_input_started.is_set():
            if use_timer:
                break
        else:
            time.sleep(0.05)
    
    user_input = user_input.strip()
    
    if not user_input:
        content_path = default_path
    else:
        content_path = user_input.strip('"').strip("'")
        content_path = os.path.expandvars(content_path)
        content_path = os.path.normpath(content_path)
    
    if not os.path.exists(content_path):
        print_error(f"Path does not exist: {content_path}")
        print()
        retry = input("Would you like to try again? (y/n): ").lower()
        if retry == 'y':
            return get_kindle_content_path(default_path)
        else:
            raise FileNotFoundError(f"Kindle content directory not found: {content_path}")

    os.system('cls')
    print_step("Validating Kindle content path...")
    validation_result = validate_kindle_path(content_path)
    
    books_found = validation_result["books_found"]
    db_found = validation_result["db_found"]
    
    print()
    print("=" * 70)
    print_step("Path Validation Results:")
    print("=" * 70)
    print()
    
    if books_found > 0 and db_found:
        print_ok(f"✓ Found {books_found} book(s) (*.azw files)")
        print_ok(f"✓ Found Kindle database (book_asset.db)")
        print()
        print_colored("  This appears to be a valid Kindle for PC download folder.", 'green')
    elif books_found > 0 and not db_found:
        print_ok(f"✓ Found {books_found} book(s) (*.azw files)")
        print_warn(f"✗ Kindle database (book_asset.db) NOT found")
        print()
        print_colored("  This appears to be a custom folder for DeDRM purposes.", 'yellow')
    elif books_found == 0 and db_found:
        print_warn(f"✗ No books (*.azw files) found")
        print_ok(f"✓ Found Kindle database (book_asset.db)")
        print()
        print_colored("  This is a Kindle for PC folder but contains no downloaded books.", 'yellow')
    else:
        print_error(f"✗ No books (*.azw files) found")
        print_error(f"✗ Kindle database (book_asset.db) NOT found")
        print()
        print_colored("  This folder appears empty or is not a Kindle content folder.", 'red')
    
    print()
    print_colored("─" * 70, 'cyan')
    print_warn("IMPORTANT: Phase 1 (Key Extraction) Requirements")
    print_colored("─" * 70, 'cyan')
    print()
    
    if books_found == 0:
        print_error("⚠  Choosing this path will cause Phase 1 to fail with:")
        print_error("   'No books found in content directory!'")
        print()
        print("   You MUST download your books into this folder for the script to work.")
        print("   Or Re-enter and Choose a different path")
        print_warn(f"   Path {default_path}")
        print()
    else:
        print_ok(f"✓ Path contains {books_found} book(s) - Phase 1 should proceed normally")
        print()
    
    print("Options:")
    print("  [C] Confirm - Use this path and continue")
    print("  [R] Re-enter - Choose a different path")
    print("  [Q] Quit - Exit script")
    print()
    
    while True:
        choice = input("Your choice (C/R/Q): ").strip().upper()
        if choice == 'C':
            print()
            print_ok(f"Using path: {content_path}")
            print()
            return content_path
        elif choice == 'R':
            print()
            print_step("Re-entering path...")
            print()
            return get_kindle_content_path(default_path)
        elif choice == 'Q':
            print()
            print_warn("Script cancelled by user")
            sys.exit(0)
        else:
            print_error("Invalid choice. Please enter C, R, or Q.")


def prompt_calibre_import_settings():
    """Prompt user for Calibre import settings"""
    config_progress = {}
    
    os.system('cls')
    print()
    print_banner_and_version()
    print("=" * 70)
    print_step("PRE-FLIGHT CONFIGURATION WIZARD")
    print("=" * 70)
    print()
    print_step("[8/8] Calibre Auto-Import")
    print("--------------------------------------------------")
    print()
    
    # Check if Calibre is running
    if not is_calibre_running():
        print_ok("Calibre not detected as Running - proceeding automatically")
        print()
    else:
        print_warn("IMPORTANT: Please close Calibre now before proceeding")
        print()
        print_step("Waiting for Calibre to close...")
        print("  (Script will automatically continue when Calibre closes)")
        print()
        
        while is_calibre_running():
            time.sleep(1)
        
        print_ok("Calibre has closed - continuing with configuration...")
        print()
    
    # Get library path
    last_library = get_last_calibre_library()
    
    if last_library:
        book_count = get_library_book_count(last_library)
        if book_count is not None:
            print_ok(f"Last used Calibre library: {last_library} ({book_count} books)")
        else:
            print_ok(f"Last used Calibre library: {last_library}")
        print()
        choice = input("Use this library? (Y/N) [Y]: ").strip().upper()
        if choice == '':
            choice = 'Y'
        
        if choice == 'Y':
            valid, error, book_count = verify_library_path(last_library)
            if valid:
                if book_count is not None:
                    print_ok(f"Library validated: {book_count} books found")
                else:
                    print_ok(f"Library validated: Unknown book count")
                print()
                library_path = last_library
            else:
                print_warn(f"Library path invalid: {error}")
                library_path = prompt_manual_library_path()
        else:
            library_path = prompt_manual_library_path()
    else:
        print_warn("Could not find Calibre configuration")
        library_path = prompt_manual_library_path()
    
    config_progress['library_path'] = library_path
    
    # Ask about EPUB conversion
    print_step("Imported eBook to EPUB Conversion")
    print("--------------------------------------------------")
    print()
    print("After importing ebooks, they can be automatically converted to EPUB format.")
    print()
    
    while True:
        convert_choice = input("Convert imported eBooks to EPUB? (Y/N) [Y]: ").strip().upper()
        if convert_choice == '':
            convert_choice = 'Y'
        if convert_choice in ['Y', 'N']:
            break
        print_error("Please enter Y or N")
    
    config_progress['convert_to_epub'] = (convert_choice == 'Y')
    
    # Build configuration
    config = {
        'enabled': True,
        'library_path': library_path,
        'convert_to_epub': convert_choice == 'Y',
        'kfx_zip_mode': 'convert_all',
        'source_file_management': 'keep_both'
    }
    
    return config


def configure_pre_flight_wizard(user_home, TOTAL_STEPS):
    """Pre-Flight Configuration Wizard"""
    
    os.system('cls')
    print()
    print_banner_and_version()
    print("=" * 70)
    print_step("PRE-FLIGHT CONFIGURATION WIZARD")
    print("=" * 70)
    print()
    print("This wizard will guide you through configuring all script options.")
    print("You can change these settings later by deleting the config file.")
    print()
    
    config = {
        'script_version': SCRIPT_VERSION,
        'last_updated': datetime.now().isoformat()
    }
    
    # 1. Kindle Content Path
    print_step(f"[1/{TOTAL_STEPS}] Kindle Content Directory")
    print("--------------------------------------------------")
    default_content = os.path.join(user_home, "Documents", "My Kindle Content")
    print()
    
    config['kindle_content_path'] = get_kindle_content_path(default_content, use_timer=False)
    
    print()
    
    # Clear console
    os.system('cls')
    print()
    print_banner_and_version()
    print("=" * 70)
    print_step("PRE-FLIGHT CONFIGURATION WIZARD")
    print("=" * 70)
    print()
    print_ok(f"✓ [1/{TOTAL_STEPS}] Kindle Content Path: {config['kindle_content_path']}")
    print()
    
    # 2. Working Directory Preference
    print_step(f"[2/{TOTAL_STEPS}] Working Directory Preference")
    print("--------------------------------------------------")
    print()
    print("By default, the script automatically chooses the best working directory.")
    print()
    print(f"  APPDATA location: {os.path.join(user_home, 'AppData', 'Local', 'Kindle_Key_Finder')}")
    print()
    
    while True:
        choice = input("Always use APPDATA for working directory? (Y/N) [N]: ").strip().upper()
        if choice == '':
            choice = 'N'
        if choice in ['Y', 'N']:
            config['always_use_appdata'] = (choice == 'Y') # type: ignore
            print()
            if choice == 'Y':
                print_ok("✓ Will ALWAYS use APPDATA for keys, logs, and config")
            else:
                print_ok("✓ Will auto-detect best working directory")
            break
        print_error("Please enter Y or N")
    
    print()
    
    # 3. Hide Sensitive Information
    os.system('cls')
    print()
    print_banner_and_version()
    print("=" * 70)
    print_step("PRE-FLIGHT CONFIGURATION WIZARD")
    print("=" * 70)
    print()
    print_ok(f"✓ [1/{TOTAL_STEPS}] Kindle Content Path: {config['kindle_content_path']}")
    appdata_status = "Yes (forced)" if config['always_use_appdata'] else "No (auto-detect)"
    print_ok(f"✓ [2/{TOTAL_STEPS}] Always Use APPDATA: {appdata_status}")
    print()
    
    print_step(f"[3/{TOTAL_STEPS}] Privacy Settings")
    print("--------------------------------------------------")
    print("Hide sensitive information (DSN, tokens, keys) in console output?")
    print()
    
    while True:
        choice = input("Hide sensitive info? (Y/N) [Y]: ").strip().upper()
        if choice == '':
            choice = 'Y'
        if choice in ['Y', 'N']:
            config['hide_sensitive_info'] = (choice == 'Y') # type: ignore
            print()
            if choice == 'Y':
                print_ok("✓ Sensitive information will be hidden")
            else:
                print_ok("✓ Sensitive information will be shown")
            break
        print_error("Please enter Y or N")
    
    print()
    
    # 4. Fetch Book Titles
    os.system('cls')
    print()
    print_banner_and_version()
    print("=" * 70)
    print_step("PRE-FLIGHT CONFIGURATION WIZARD")
    print("=" * 70)
    print()
    print_ok(f"✓ [1/{TOTAL_STEPS}] Kindle Content Path: {config['kindle_content_path']}")
    hide_status = "Yes" if config['hide_sensitive_info'] else "No"
    print_ok(f"✓ [2/{TOTAL_STEPS}] Hide Sensitive Info: {hide_status}")
    print()
    
    print_step(f"[3/{TOTAL_STEPS}] Key Extraction Display Options")
    print("--------------------------------------------------")
    print("Fetch book titles from Amazon during key extraction?")
    print()
    print_warn("NOTE: This will significantly slow down the extraction process")
    print("  Recommended: No (faster extraction)")
    print()
    
    while True:
        choice = input("Fetch book titles during extraction? (Y/N) [N]: ").strip().upper()
        if choice == '':
            choice = 'N'
        if choice in ['Y', 'N']:
            config['fetch_book_titles'] = (choice == 'Y') # type: ignore
            print()
            if choice == 'Y':
                print_ok("✓ Book titles will be fetched (slower extraction)")
            else:
                print_ok("✓ Book titles will NOT be fetched (faster extraction)")
            break
        print_error("Please enter Y or N")
    
    print()
    
    # 5. Clear Screen Between Phases
    os.system('cls')
    print()
    print_banner_and_version()
    print("=" * 70)
    print_step("PRE-FLIGHT CONFIGURATION WIZARD")
    print("=" * 70)
    print()
    print_ok(f"✓ [1/{TOTAL_STEPS}] Kindle Content Path: {config['kindle_content_path']}")
    hide_status = "Yes" if config['hide_sensitive_info'] else "No"
    print_ok(f"✓ [2/{TOTAL_STEPS}] Hide Sensitive Info: {hide_status}")
    fetch_status = "Yes" if config['fetch_book_titles'] else "No"
    print_ok(f"✓ [3/{TOTAL_STEPS}] Fetch Book Titles: {fetch_status}")
    print()
    
    print_step(f"[4/{TOTAL_STEPS}] Display Options")
    print("--------------------------------------------------")
    print("Clear screen between each phase for cleaner output?")
    print()
    print("  N - Keep all output visible (Recommended)")
    print("  Y - Clear screen between phases")
    print()

    while True:
        choice = input("Clear screen between phases? (Y/N) [N]: ").strip().upper()
        if choice == '':
            choice = 'N'
        if choice in ['Y', 'N']:
            config['clear_screen_between_phases'] = (choice == 'Y') # type: ignore
            print()
            if choice == 'Y':
                print_ok("✓ Screen will be cleared between phases")
            else:
                print_ok("✓ Screen will NOT be cleared between phases (Recommended)")
            break
        print_error("Please enter Y or N")
    
    print()
    
    # 6. Skip Phase Pauses
    os.system('cls')
    print()
    print_banner_and_version()
    print("=" * 70)
    print_step("PRE-FLIGHT CONFIGURATION WIZARD")
    print("=" * 70)
    print()
    print_ok(f"✓ [1/{TOTAL_STEPS}] Kindle Content Path: {config['kindle_content_path']}")
    hide_status = "Yes" if config['hide_sensitive_info'] else "No"
    print_ok(f"✓ [2/{TOTAL_STEPS}] Hide Sensitive Info: {hide_status}")
    fetch_status = "Yes" if config['fetch_book_titles'] else "No"
    print_ok(f"✓ [3/{TOTAL_STEPS}] Fetch Book Titles: {fetch_status}")
    clear_status = "Yes" if config['clear_screen_between_phases'] else "No"
    print_ok(f"✓ [4/{TOTAL_STEPS}] Clear Screen Between Phases: {clear_status}")
    print()
    
    print_step(f"[5/{TOTAL_STEPS}] Phase Pause Settings")
    print("--------------------------------------------------")
    print("Skip countdown pauses between phases for faster execution?")
    print()
    
    while True:
        choice = input("Skip phase pauses? (Y/N) [N]: ").strip().upper()
        if choice == '':
            choice = 'N'
        if choice in ['Y', 'N']:
            config['skip_phase_pauses'] = (choice == 'Y') # type: ignore
            print()
            if choice == 'Y':
                print_ok("✓ Phase pauses will be skipped (faster execution)")
            else:
                print_ok("✓ Phase pauses will be shown (better visibility)")
            break
        print_error("Please enter Y or N")
    
    print()
    
    # 7. Auto-Launch Kindle
    os.system('cls')
    print()
    print_banner_and_version()
    print("=" * 70)
    print_step("PRE-FLIGHT CONFIGURATION WIZARD")
    print("=" * 70)
    print()
    print_ok(f"✓ [1/{TOTAL_STEPS}] Kindle Content Path: {config['kindle_content_path']}")
    hide_status = "Yes" if config['hide_sensitive_info'] else "No"
    print_ok(f"✓ [2/{TOTAL_STEPS}] Hide Sensitive Info: {hide_status}")
    fetch_status = "Yes" if config['fetch_book_titles'] else "No"
    print_ok(f"✓ [3/{TOTAL_STEPS}] Fetch Book Titles: {fetch_status}")
    clear_status = "Yes" if config['clear_screen_between_phases'] else "No"
    print_ok(f"✓ [4/{TOTAL_STEPS}] Clear Screen Between Phases: {clear_status}")
    skip_pauses_status = "Yes" if config['skip_phase_pauses'] else "No"
    print_ok(f"✓ [5/{TOTAL_STEPS}] Skip Phase Pauses: {skip_pauses_status}")
    print()

    print_step(f"[6/{TOTAL_STEPS}] Auto-Launch Kindle")
    print("--------------------------------------------------")
    print("Would you like to automatically launch Kindle.exe?")
    print()
    
    while True:
        choice = input("Enable Auto-Launch Kindle? (Y/N) [N]: ").strip().upper()
        if choice == '':
            choice = 'N'
        if choice in ['Y', 'N']:
            config['auto_launch_kindle'] = (choice == 'Y') # type: ignore
            print()
            break
        print_error("Please enter Y or N")
        print()
    
    # 8. Raw Debug Logs
    os.system('cls')
    print()
    print_banner_and_version()
    print("=" * 70)
    print_step("PRE-FLIGHT CONFIGURATION WIZARD")
    print("=" * 70)
    print()
    print_ok(f"✓ [1/{TOTAL_STEPS}] Kindle Content Path: {config['kindle_content_path']}")
    hide_status = "Yes" if config['hide_sensitive_info'] else "No"
    print_ok(f"✓ [2/{TOTAL_STEPS}] Hide Sensitive Info: {hide_status}")
    fetch_status = "Yes" if config['fetch_book_titles'] else "No"
    print_ok(f"✓ [3/{TOTAL_STEPS}] Fetch Book Titles: {fetch_status}")
    clear_status = "Yes" if config['clear_screen_between_phases'] else "No"
    print_ok(f"✓ [4/{TOTAL_STEPS}] Clear Screen Between Phases: {clear_status}")
    skip_pauses_status = "Yes" if config['skip_phase_pauses'] else "No"
    print_ok(f"✓ [5/{TOTAL_STEPS}] Skip Phase Pauses: {skip_pauses_status}")
    auto_launch_status = "Yes" if config['auto_launch_kindle'] else "No"
    print_ok(f"✓ [6/{TOTAL_STEPS}] Auto-Launch Kindle: {auto_launch_status}")
    print()

    print_step(f"[7/{TOTAL_STEPS}] Raw Debug Logs")
    print("--------------------------------------------------")
    print("Enable raw debug logs for complete subprocess output?")
    print()
    
    while True:
        choice = input("Enable raw debug logs? (Y/N) [Y]: ").strip().upper()
        if choice == '':
            choice = 'Y'
        if choice in ['Y', 'N']:
            config['enable_raw_logs'] = (choice == 'Y') # type: ignore
            print()
            if choice == 'Y':
                print_ok("✓ Raw debug logs will be enabled")
            else:
                print_ok("✓ Raw debug logs will be disabled")
            break
        print_error("Please enter Y or N")
    
    print()
    
    # 9. Calibre Import Settings
    os.system('cls')
    print()
    print_banner_and_version()
    print("=" * 70)
    print_step("PRE-FLIGHT CONFIGURATION WIZARD")
    print("=" * 70)
    print()
    print_ok(f"✓ [1/{TOTAL_STEPS}] Kindle Content Path: {config['kindle_content_path']}")
    hide_status = "Yes" if config['hide_sensitive_info'] else "No"
    print_ok(f"✓ [2/{TOTAL_STEPS}] Hide Sensitive Info: {hide_status}")
    fetch_status = "Yes" if config['fetch_book_titles'] else "No"
    print_ok(f"✓ [3/{TOTAL_STEPS}] Fetch Book Titles: {fetch_status}")
    clear_status = "Yes" if config['clear_screen_between_phases'] else "No"
    print_ok(f"✓ [4/{TOTAL_STEPS}] Clear Screen Between Phases: {clear_status}")
    skip_pauses_status = "Yes" if config['skip_phase_pauses'] else "No"
    print_ok(f"✓ [5/{TOTAL_STEPS}] Skip Phase Pauses: {skip_pauses_status}")
    auto_launch_status = "Yes" if config['auto_launch_kindle'] else "No"
    print_ok(f"✓ [6/{TOTAL_STEPS}] Auto-Launch Kindle: {auto_launch_status}")
    enable_raw_logs = "Yes" if config['enable_raw_logs'] else "No"
    print_ok(f"✓ [7/{TOTAL_STEPS}] Enable Raw Debug Logs: {enable_raw_logs}")
    print()
    
    print_step(f"[8/{TOTAL_STEPS}] Calibre Auto-Import")
    print("--------------------------------------------------")
    print("Enable automatic import of DeDRMed ebooks to Calibre?")
    print()
    
    while True:
        choice = input("Configure Calibre import now? (Y/N) [Y]: ").strip().upper()
        if choice == '':
            choice = 'Y'
        if choice in ['Y', 'N']:
            break
        print_error("Please enter Y or N")
    
    if choice == 'N':
        config['calibre_import'] = {'enabled': False} # type: ignore
        print()
        print_ok("✓ Calibre auto-import disabled")
        print()
    else:
        print()
        calibre_config = prompt_calibre_import_settings()
        if calibre_config:
            config['calibre_import'] = calibre_config # type: ignore
        else:
            config['calibre_import'] = {'enabled': False} # type: ignore
    
    # Final review
    while True:
        os.system('cls')
        print()
        print_banner_and_version()
        print("=" * 70)
        print_step("CONFIGURATION REVIEW")
        print("=" * 70)
        print()
        print("Please review your configuration before saving:")
        print()
        display_config_summary(config)
        
        print("Options:")
        print("  [Y] Yes, save and continue (recommended)")
        print("  [R] Reconfigure - Start over")
        print("  [Q] Quit without saving")
        print()
        
        review_choice = input("Your choice (Y/R/Q) [Y]: ").strip().upper()
        if review_choice == '':
            review_choice = 'Y'
        
        if review_choice == 'Y':
            print()
            print_step("Saving Configuration")
            print("--------------------------------------------------")
            save_config(config)
            print()
            
            print("=" * 70)
            print_done("PRE-FLIGHT CONFIGURATION COMPLETE")
            print("=" * 70)
            print()
            
            return config
        elif review_choice == 'R':
            print()
            print_step("Restarting configuration wizard...")
            print()
            return configure_pre_flight_wizard(user_home, TOTAL_STEPS)
        elif review_choice == 'Q':
            print()
            print_warn("Configuration cancelled - exiting without saving")
            sys.exit(0)
        else:
            print_error("Invalid choice. Please enter Y, R, or Q.")
