"""Generate command implementation.

Generates secure BIP-39 mnemonics with multi-language support.
"""

import argparse

from sseed.bip39 import generate_mnemonic
from sseed.entropy import secure_delete_variable
from sseed.exceptions import MnemonicError
from sseed.languages import validate_language_code
from sseed.logging_config import get_logger
from sseed.validation import validate_mnemonic_checksum

from ..base import BaseCommand
from ..error_handling import handle_common_errors

# Define exit code locally to avoid circular import
EXIT_SUCCESS = 0

logger = get_logger(__name__)


class GenCommand(BaseCommand):
    """Generate a BIP-39 mnemonic (12-24 words) using secure entropy with multi-language support."""

    def __init__(self) -> None:
        super().__init__(
            name="gen",
            help_text="Generate a BIP-39 mnemonic (12-24 words) using secure entropy",
            description=(
                "Generate a cryptographically secure BIP-39 mnemonic with flexible word counts "
                "(12, 15, 18, 21, or 24 words) using system entropy. "
                "Supports all 9 BIP-39 languages."
            ),
        )

    def add_arguments(self, parser: argparse.ArgumentParser) -> None:
        """Add gen command arguments."""
        parser.add_argument(
            "-o",
            "--output",
            type=str,
            metavar="FILE",
            help="Output file (default: stdout)",
        )

        # NEW: Word count argument (pattern copied from BIP85)
        parser.add_argument(
            "-w",
            "--words",
            type=int,
            choices=[12, 15, 18, 21, 24],
            default=24,
            metavar="COUNT",
            help="Number of words in generated mnemonic (default: 24)",
        )

        # Add language support
        parser.add_argument(
            "-l",
            "--language",
            type=str,
            choices=["en", "es", "fr", "it", "pt", "cs", "zh-cn", "zh-tw", "ko"],
            default="en",
            metavar="LANG",
            help=(
                "Language for mnemonic generation (default: en/English). "
                "Choices: en(English), es(Spanish), fr(French), it(Italian), "
                "pt(Portuguese), cs(Czech), zh-cn(Chinese Simplified), "
                "zh-tw(Chinese Traditional), ko(Korean)"
            ),
        )

        # Custom entropy sources (mutually exclusive)
        entropy_group = parser.add_mutually_exclusive_group()
        entropy_group.add_argument(
            "--entropy-hex",
            type=str,
            metavar="HEX",
            help=(
                "Use custom entropy from hex string (with or without 0x prefix). "
                "WARNING: Only use if you understand cryptographic implications."
            ),
        )
        entropy_group.add_argument(
            "--entropy-dice",
            type=str,
            metavar="ROLLS",
            help=(
                "Use custom entropy from dice rolls (1-6). "
                "Supports formats: '1,2,3,4,5,6' or '1 2 3 4 5 6' or '123456'. "
                "WARNING: Only use if you understand cryptographic implications."
            ),
        )

        # Entropy quality and analysis options
        parser.add_argument(
            "--allow-weak",
            action="store_true",
            help="Allow custom entropy with quality score < 70 (NOT RECOMMENDED)",
        )
        parser.add_argument(
            "--force",
            action="store_true",
            help="Force operation despite security warnings (DANGEROUS)",
        )
        parser.add_argument(
            "--entropy-analysis",
            action="store_true",
            help="Show detailed entropy quality analysis",
        )

        self.add_entropy_display_argument(parser)

    @handle_common_errors("generation")
    def handle(
        self, args: argparse.Namespace
    ) -> (
        int
    ):  # pylint: disable=too-many-locals,too-many-branches,too-many-statements,too-many-nested-blocks
        """Handle the 'gen' command with custom entropy support.

        Args:
            args: Parsed command-line arguments.

        Returns:
            Exit code.
        """
        # Extract words early for backward compatibility
        words = getattr(
            args, "words", 24
        )  # Default to 24 words for backward compatibility

        # Initialize entropy_source to avoid unbound variable warning
        entropy_source = "unknown"

        logger.info(
            "Starting mnemonic generation (language: %s, words: %d)",
            args.language,
            words,
        )

        custom_entropy = None
        entropy_quality = None

        try:
            # Validate and get language information
            language_info = validate_language_code(args.language)
            logger.info(
                "Using language: %s (%s), generating %d words",
                language_info.name,
                language_info.code,
                words,
            )

            # Process custom entropy if provided (with backward compatibility)
            try:
                entropy_hex = args.entropy_hex
                # Check if it's a MagicMock (used in tests) and treat as None
                if str(type(entropy_hex).__name__) == "MagicMock":
                    entropy_hex = None
            except AttributeError:
                entropy_hex = None

            try:
                entropy_dice = args.entropy_dice
                # Check if it's a MagicMock (used in tests) and treat as None
                if str(type(entropy_dice).__name__) == "MagicMock":
                    entropy_dice = None
            except AttributeError:
                entropy_dice = None

            try:
                allow_weak = args.allow_weak
                # Check if it's a MagicMock (used in tests) and treat as False
                if str(type(allow_weak).__name__) == "MagicMock":
                    allow_weak = False
            except AttributeError:
                allow_weak = False

            try:
                force = args.force
                # Check if it's a MagicMock (used in tests) and treat as False
                if str(type(force).__name__) == "MagicMock":
                    force = False
            except AttributeError:
                force = False

            try:
                entropy_analysis = args.entropy_analysis
                # Check if it's a MagicMock (used in tests) and treat as False
                if str(type(entropy_analysis).__name__) == "MagicMock":
                    entropy_analysis = False
            except AttributeError:
                entropy_analysis = False

            if entropy_hex or entropy_dice:
                from sseed.bip39 import (  # pylint: disable=import-outside-toplevel
                    word_count_to_entropy_bytes,
                )
                from sseed.entropy import (  # pylint: disable=import-outside-toplevel
                    dice_to_entropy,
                    hex_to_entropy,
                    validate_entropy_quality,
                )
                from sseed.exceptions import (  # pylint: disable=import-outside-toplevel
                    EntropyError,
                    ValidationError,
                )

                required_bytes = word_count_to_entropy_bytes(words)

                try:
                    if entropy_hex:
                        print("⚠️  WARNING: Using custom hex entropy (NOT RECOMMENDED)")
                        # Get entropy without quality validation first
                        custom_entropy = hex_to_entropy(
                            entropy_hex, required_bytes, skip_quality_check=True
                        )
                        entropy_source = "hex"
                    elif entropy_dice:
                        print("⚠️  WARNING: Using custom dice entropy (NOT RECOMMENDED)")
                        # Get entropy without quality validation first
                        custom_entropy = dice_to_entropy(
                            entropy_dice, required_bytes, skip_quality_check=True
                        )
                        entropy_source = "dice"

                    # Validate entropy quality at CLI level
                    if custom_entropy is None:
                        raise RuntimeError(
                            "Custom entropy was not initialized properly"
                        )
                    entropy_quality = validate_entropy_quality(custom_entropy)

                    # Display quality analysis if requested
                    if entropy_analysis:
                        print("\n📊 Entropy Quality Analysis:")
                        print(f"   Quality Score: {entropy_quality.score}/100")
                        if entropy_quality.warnings:
                            print("   Warnings:")
                            for warning in entropy_quality.warnings:
                                print(f"     • {warning}")
                        if entropy_quality.recommendations:
                            print("   Recommendations:")
                            for rec in entropy_quality.recommendations:
                                print(f"     • {rec}")
                        print()

                    # Check quality and handle user consent
                    if not entropy_quality.is_acceptable:
                        quality_msg = (
                            f"❌ SECURITY WARNING: Entropy quality insufficient "
                            f"({entropy_quality.score}/100)"
                        )
                        print(quality_msg)

                        if entropy_quality.warnings:
                            print("   Issues detected:")
                            for warning in entropy_quality.warnings:
                                print(f"     • {warning}")

                        if not allow_weak:
                            print("   Use --allow-weak to override (NOT RECOMMENDED)")
                            return 1
                        if not force:
                            print(
                                "   Use --force to proceed despite warnings (DANGEROUS)"
                            )
                            return 1
                        print("   ⚠️  PROCEEDING WITH WEAK ENTROPY (DANGEROUS)")
                    else:
                        print(
                            "✅ Entropy quality acceptable "
                            f"({entropy_quality.score}/100)"
                        )

                except (EntropyError, ValidationError) as e:
                    print(f"❌ Custom entropy error: {e}")
                    return 1
                except Exception as e:  # pylint: disable=broad-exception-caught
                    print(f"❌ Unexpected error processing custom entropy: {e}")
                    logger.error("Custom entropy processing failed: %s", e)
                    return 1

            # Generate the mnemonic with custom or system entropy
            mnemonic = generate_mnemonic(language_info.bip_enum, words, custom_entropy)

            # Validate generated mnemonic checksum
            if not validate_mnemonic_checksum(mnemonic, language_info.bip_enum):
                raise MnemonicError(
                    f"Generated mnemonic failed checksum validation for {language_info.name}",
                    context={
                        "validation_type": "checksum",
                        "language": language_info.name,
                        "word_count": words,
                    },
                )

            # Prepare metadata display
            language_display = f"Language: {language_info.name} ({language_info.code})"
            word_count_display = f"Words: {words}"

            # Add entropy source info if custom entropy was used
            if custom_entropy is not None:
                entropy_display = f"Entropy: Custom ({entropy_source})"
                metadata_display = (
                    f"{language_display}, {word_count_display}, {entropy_display}"
                )
            else:
                metadata_display = f"{language_display}, {word_count_display}"

            # Output mnemonic
            if args.output:
                # Include metadata in file output
                output_content = f"# {metadata_display}\n{mnemonic}"
                self.handle_output(
                    output_content, args, success_message="Mnemonic written to: {file}"
                )

                # Handle entropy display after file is written
                entropy_info = self.handle_entropy_display(mnemonic, args, args.output)
                if entropy_info:
                    print(
                        f"Mnemonic with metadata and entropy written to: {args.output}"
                    )
                else:
                    print(f"Mnemonic with metadata written to: {args.output}")
            else:
                # Output to stdout
                print(mnemonic)
                print(f"# {metadata_display}")

                # Handle entropy display for stdout
                entropy_info = self.handle_entropy_display(mnemonic, args)
                if entropy_info:
                    print(entropy_info)
                logger.info(
                    "Mnemonic written to stdout: %d words in %s",
                    words,
                    language_info.name,
                )

            return EXIT_SUCCESS

        finally:
            # Securely delete sensitive variables from memory
            secure_delete_variable(
                mnemonic if "mnemonic" in locals() else "",
                custom_entropy if custom_entropy is not None else b"",
            )


# Backward compatibility wrapper
def handle_gen_command(args: argparse.Namespace) -> int:
    """Backward compatibility wrapper for original handle_gen_command."""
    return GenCommand().handle(args)
