"""Command-line interface for punmunch."""

import argparse
import sys
from pathlib import Path
from typing import List, Optional, TextIO

from . import __version__
from .exceptions import PunmunchError
from .unmunch import Punmunch
from .expander import ExpansionOptions


def read_words_from_stdin() -> List[str]:
    """Read words from stdin, one per line."""
    words = []
    try:
        for line in sys.stdin:
            word = line.strip()
            if word:  # Skip empty lines
                words.append(word)
    except KeyboardInterrupt:
        sys.stderr.write("\nInterrupted by user\n")
        sys.exit(1)
    return words


def write_words_to_stdout(words: List[str]) -> None:
    """Write words to stdout, one per line."""
    try:
        for word in words:
            print(word)
    except KeyboardInterrupt:
        sys.stderr.write("\nInterrupted by user\n")
        sys.exit(1)
    except BrokenPipeError:
        # Handle broken pipe gracefully (e.g., when piping to head)
        sys.stderr.close()
        sys.exit(0)


def main() -> None:
    """Main entry point for the punmunch command-line tool."""
    parser = argparse.ArgumentParser(
        description="Punmunch - Python implementation of hunspell's unmunch tool",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # Expand entire dictionary
  punmunch de.aff de.dic > expanded_words.txt
  
  # Expand specific words (--expand mode)
  echo -e "Haus\\nAuto" | punmunch --expand de.aff
  
  # Expand with dictionary validation
  echo -e "Haus\\nAuto" | punmunch --expand de.aff de.dic
  
  # Deep expansion for maximum coverage
  echo -e "Haus\\nAuto" | punmunch --expand --deep de.aff

  # Find base words and expand from those
  echo -e "Häuser\\nAutos" | punmunch --expand --find-base de.aff de.dic

  # Balanced expansion
  punmunch --balanced de.aff de.dic > expanded_words.txt

  # Show statistics
  punmunch --stats de.aff de.dic
        """
    )
    
    parser.add_argument(
        'affix_file',
        help='Hunspell affix file (.aff)'
    )
    
    parser.add_argument(
        'dictionary_file',
        nargs='?',
        help='Hunspell dictionary file (.dic). Optional for --expand mode.'
    )
    
    parser.add_argument(
        '--expand',
        action='store_true',
        help='Expand mode: read words from stdin and output all possible forms'
    )
    
    parser.add_argument(
        '--stats',
        action='store_true',
        help='Show statistics about the affix file and dictionary'
    )
    
    parser.add_argument(
        '--version',
        action='version',
        version=f'punmunch {__version__}'
    )
    
    parser.add_argument(
        '--validate',
        action='store_true',
        help='In expand mode, only output forms that would be valid dictionary words'
    )

    parser.add_argument(
        '--find-base',
        action='store_true',
        help='In expand mode, find base words first then expand from those (requires dictionary)'
    )
    
    expansion_group = parser.add_mutually_exclusive_group()
    expansion_group.add_argument(
        '--deep',
        action='store_true',
        help='Use deep expansion with maximum morphological coverage (slower but more complete)'
    )
    
    expansion_group.add_argument(
        '--balanced',
        action='store_true',
        help='Use balanced expansion (good compromise between speed and completeness)'
    )
    
    args = parser.parse_args()
    
    # Validate arguments
    if not Path(args.affix_file).exists():
        sys.stderr.write(f"Error: Affix file '{args.affix_file}' not found\n")
        sys.exit(1)
    
    if args.dictionary_file and not Path(args.dictionary_file).exists():
        sys.stderr.write(f"Error: Dictionary file '{args.dictionary_file}' not found\n")
        sys.exit(1)
    
    if not args.expand and not args.dictionary_file:
        sys.stderr.write("Error: Dictionary file is required unless using --expand mode\n")
        sys.exit(1)

    if args.find_base and not args.expand:
        sys.stderr.write("Error: --find-base can only be used with --expand mode\n")
        sys.exit(1)

    if args.find_base and not args.dictionary_file:
        sys.stderr.write("Error: --find-base requires a dictionary file\n")
        sys.exit(1)
    
    try:
        # Determine expansion options
        if args.deep:
            expansion_options = ExpansionOptions.deep()
        elif args.balanced:
            expansion_options = ExpansionOptions.balanced()
        else:
            expansion_options = ExpansionOptions.conservative()
        
        # Initialize punmunch with expansion options
        punmunch = Punmunch(expansion_options)
        
        # Load affix file
        sys.stderr.write(f"Loading affix file: {args.affix_file}\n")
        punmunch.load_affix_file(args.affix_file)
        
        # Load dictionary if provided
        if args.dictionary_file:
            sys.stderr.write(f"Loading dictionary: {args.dictionary_file}\n")
            punmunch.load_dictionary(args.dictionary_file)
        
        # Show statistics if requested
        if args.stats:
            stats = punmunch.get_statistics()
            sys.stderr.write("\nStatistics:\n")
            sys.stderr.write(f"  Flag type: {stats['flag_type']}\n")
            sys.stderr.write(f"  Encoding: {stats['encoding']}\n")
            sys.stderr.write(f"  Dictionary words: {stats['word_count']}\n")
            sys.stderr.write(f"  Prefix flags: {stats['prefix_flags']}\n")
            sys.stderr.write(f"  Suffix flags: {stats['suffix_flags']}\n")
            sys.stderr.write(f"  Total prefix rules: {stats['total_prefix_rules']}\n")
            sys.stderr.write(f"  Total suffix rules: {stats['total_suffix_rules']}\n")
            sys.stderr.write(f"  Expansion mode: {stats['expansion_mode']}\n")
            sys.stderr.write(f"  Max recursion depth: {stats['max_recursion_depth']}\n")
            sys.stderr.write(f"  Process intermediate flags: {stats['process_intermediate_flags']}\n")
            sys.stderr.write(f"  Extensive cross products: {stats['extensive_cross_products']}\n")
            
            if not args.expand:
                return
        
        if args.expand:
            # Expand mode: read words from stdin
            sys.stderr.write("Reading words from stdin...\n")
            words = read_words_from_stdin()
            
            if not words:
                sys.stderr.write("No words provided on stdin\n")
                return
            
            sys.stderr.write(f"Expanding {len(words)} words...\n")
            
            # Expand words
            use_dictionary = args.dictionary_file is not None and args.validate
            find_base = args.find_base
            expanded = punmunch.expand_words(words, use_dictionary=use_dictionary, find_base=find_base)
            
            sys.stderr.write(f"Generated {len(expanded)} word forms\n")
            write_words_to_stdout(expanded)
            
        else:
            # Full unmunch mode: expand entire dictionary
            sys.stderr.write("Expanding entire dictionary...\n")
            expanded = punmunch.unmunch_all()
            
            sys.stderr.write(f"Generated {len(expanded)} word forms\n")
            write_words_to_stdout(expanded)
    
    except PunmunchError as e:
        sys.stderr.write(f"Error: {e}\n")
        sys.exit(1)
    except KeyboardInterrupt:
        sys.stderr.write("\nInterrupted by user\n")
        sys.exit(1)
    except Exception as e:
        sys.stderr.write(f"Unexpected error: {e}\n")
        sys.exit(1)


if __name__ == '__main__':
    main()