#!/usr/bin/env python3
"""
Command-line interface for managing the encrypted secrets store.

Usage:
    python -m secrets.cli init                      # Initialize new secrets store
    python -m secrets.cli set KEY VALUE             # Set a secret
    python -m secrets.cli get KEY                   # Get a secret
    python -m secrets.cli delete KEY                # Delete a secret
    python -m secrets.cli list                      # List all secret keys
    python -m secrets.cli change-password           # Change master password
    python -m secrets.cli export FILE               # Export encrypted backup
    python -m secrets.cli import FILE               # Import encrypted backup
    python -m secrets.cli migrate-from-env          # Migrate secrets from .env file
"""
import sys
import argparse
import getpass
from pathlib import Path

from .store import SecretsStore, SecretsStoreError, InvalidMasterPassword


def get_password(prompt: str = "Master password: ", confirm: bool = False) -> str:
    """
    Securely get password from user.

    Args:
        prompt: Password prompt
        confirm: If True, ask for confirmation

    Returns:
        Password string
    """
    password = getpass.getpass(prompt)

    if confirm:
        confirm_password = getpass.getpass("Confirm password: ")
        if password != confirm_password:
            print("Error: Passwords do not match", file=sys.stderr)
            sys.exit(1)

    return password


def cmd_init(args):
    """Initialize a new secrets store."""
    store = SecretsStore()

    if store.is_initialized:
        print("Error: Secrets store is already initialized", file=sys.stderr)
        print(f"Location: {store.secrets_file}", file=sys.stderr)
        sys.exit(1)

    password = get_password("Create master password: ", confirm=True)

    if len(password) < 8:
        print("Error: Password must be at least 8 characters", file=sys.stderr)
        sys.exit(1)

    store.initialize(password)
    print(f"Secrets store initialized at {store.secrets_file}")


def cmd_set(args):
    """Set a secret value."""
    store = SecretsStore()

    if not store.is_initialized:
        print("Error: Secrets store is not initialized. Run 'init' first.", file=sys.stderr)
        sys.exit(1)

    password = get_password()

    try:
        store.unlock(password)
    except InvalidMasterPassword:
        print("Error: Invalid master password", file=sys.stderr)
        sys.exit(1)

    store.set(args.key, args.value)
    print(f"✓ Secret '{args.key}' saved")


def cmd_get(args):
    """Get a secret value."""
    store = SecretsStore()

    if not store.is_initialized:
        print("Error: Secrets store is not initialized. Run 'init' first.", file=sys.stderr)
        sys.exit(1)

    password = get_password()

    try:
        store.unlock(password)
    except InvalidMasterPassword:
        print("Error: Invalid master password", file=sys.stderr)
        sys.exit(1)

    value = store.get(args.key)
    if value is None:
        print(f"Error: Secret '{args.key}' not found", file=sys.stderr)
        sys.exit(1)

    # Print to stdout (can be captured)
    print(value)


def cmd_delete(args):
    """Delete a secret."""
    store = SecretsStore()

    if not store.is_initialized:
        print("Error: Secrets store is not initialized. Run 'init' first.", file=sys.stderr)
        sys.exit(1)

    password = get_password()

    try:
        store.unlock(password)
    except InvalidMasterPassword:
        print("Error: Invalid master password", file=sys.stderr)
        sys.exit(1)

    if store.delete(args.key):
        print(f"✓ Secret '{args.key}' deleted")
    else:
        print(f"Error: Secret '{args.key}' not found", file=sys.stderr)
        sys.exit(1)


def cmd_list(args):
    """List all secret keys."""
    store = SecretsStore()

    if not store.is_initialized:
        print("Error: Secrets store is not initialized. Run 'init' first.", file=sys.stderr)
        sys.exit(1)

    password = get_password()

    try:
        store.unlock(password)
    except InvalidMasterPassword:
        print("Error: Invalid master password", file=sys.stderr)
        sys.exit(1)

    keys = store.list_keys()

    if not keys:
        print("No secrets stored")
    else:
        print(f"Stored secrets ({len(keys)}):")
        for key in sorted(keys):
            # Show key and value length for verification
            value = store.get(key)
            value_str = str(value)
            value_preview = value_str[:50] + "..." if len(value_str) > 50 else value_str
            print(f"  {key}: {value_preview}")


def cmd_change_password(args):
    """Change the master password."""
    store = SecretsStore()

    if not store.is_initialized:
        print("Error: Secrets store is not initialized. Run 'init' first.", file=sys.stderr)
        sys.exit(1)

    current_password = get_password("Current master password: ")
    new_password = get_password("New master password: ", confirm=True)

    if len(new_password) < 8:
        print("Error: Password must be at least 8 characters", file=sys.stderr)
        sys.exit(1)

    try:
        store.change_master_password(current_password, new_password)
    except InvalidMasterPassword:
        print("Error: Invalid current password", file=sys.stderr)
        sys.exit(1)


def cmd_export(args):
    """Export encrypted secrets to a backup file."""
    store = SecretsStore()

    if not store.is_initialized:
        print("Error: Secrets store is not initialized. Run 'init' first.", file=sys.stderr)
        sys.exit(1)

    output_path = Path(args.file)

    if output_path.exists() and not args.force:
        print(f"Error: File {output_path} already exists. Use --force to overwrite.", file=sys.stderr)
        sys.exit(1)

    try:
        store.export_encrypted(output_path)
    except SecretsStoreError as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_import(args):
    """Import encrypted secrets from a backup file."""
    store = SecretsStore()

    if not store.is_initialized:
        print("Error: Secrets store is not initialized. Run 'init' first.", file=sys.stderr)
        sys.exit(1)

    input_path = Path(args.file)

    if not input_path.exists():
        print(f"Error: File {input_path} does not exist", file=sys.stderr)
        sys.exit(1)

    password = get_password()

    try:
        store.import_encrypted(input_path, password)
    except InvalidMasterPassword:
        print("Error: Invalid master password or incompatible backup", file=sys.stderr)
        sys.exit(1)
    except SecretsStoreError as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_migrate_from_env(args):
    """Migrate secrets from .env file to encrypted store."""
    store = SecretsStore()

    if not store.is_initialized:
        print("Error: Secrets store is not initialized. Run 'init' first.", file=sys.stderr)
        sys.exit(1)

    # Look for .env file
    backend_root = Path(__file__).parent.parent.parent
    env_file = backend_root / ".env"

    if not env_file.exists():
        print(f"Error: .env file not found at {env_file}", file=sys.stderr)
        sys.exit(1)

    password = get_password()

    try:
        store.unlock(password)
    except InvalidMasterPassword:
        print("Error: Invalid master password", file=sys.stderr)
        sys.exit(1)

    # Parse .env file (simple parser - doesn't handle all edge cases)
    migrated = 0
    skipped = 0

    with open(env_file) as f:
        for line_num, line in enumerate(f, 1):
            line = line.strip()

            # Skip empty lines and comments
            if not line or line.startswith('#'):
                continue

            # Parse KEY=VALUE format
            if '=' not in line:
                print(f"Warning: Skipping invalid line {line_num}: {line}", file=sys.stderr)
                skipped += 1
                continue

            key, value = line.split('=', 1)
            key = key.strip()
            value = value.strip()

            # Remove quotes if present
            if value.startswith('"') and value.endswith('"'):
                value = value[1:-1]
            elif value.startswith("'") and value.endswith("'"):
                value = value[1:-1]

            # Check if key already exists
            existing = store.get(key)
            if existing is not None:
                print(f"Warning: Secret '{key}' already exists, skipping", file=sys.stderr)
                skipped += 1
                continue

            store.set(key, value)
            print(f"✓ Migrated: {key}")
            migrated += 1

    print(f"\nMigration complete: {migrated} secrets migrated, {skipped} skipped")

    if not args.keep_env:
        # Ask for confirmation before deleting .env
        confirm = input(f"\nDelete {env_file}? [y/N]: ").strip().lower()
        if confirm == 'y':
            env_file.unlink()
            print(f"✓ Deleted {env_file}")
        else:
            print(f"Kept {env_file} (consider deleting it manually)")


def main():
    """Main CLI entry point."""
    parser = argparse.ArgumentParser(
        description="Manage encrypted secrets store",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )

    subparsers = parser.add_subparsers(dest='command', help='Command to run')
    subparsers.required = True

    # init
    parser_init = subparsers.add_parser('init', help='Initialize new secrets store')
    parser_init.set_defaults(func=cmd_init)

    # set
    parser_set = subparsers.add_parser('set', help='Set a secret value')
    parser_set.add_argument('key', help='Secret key name')
    parser_set.add_argument('value', help='Secret value')
    parser_set.set_defaults(func=cmd_set)

    # get
    parser_get = subparsers.add_parser('get', help='Get a secret value')
    parser_get.add_argument('key', help='Secret key name')
    parser_get.set_defaults(func=cmd_get)

    # delete
    parser_delete = subparsers.add_parser('delete', help='Delete a secret')
    parser_delete.add_argument('key', help='Secret key name')
    parser_delete.set_defaults(func=cmd_delete)

    # list
    parser_list = subparsers.add_parser('list', help='List all secret keys')
    parser_list.set_defaults(func=cmd_list)

    # change-password
    parser_change = subparsers.add_parser('change-password', help='Change master password')
    parser_change.set_defaults(func=cmd_change_password)

    # export
    parser_export = subparsers.add_parser('export', help='Export encrypted backup')
    parser_export.add_argument('file', help='Output file path')
    parser_export.add_argument('--force', action='store_true', help='Overwrite existing file')
    parser_export.set_defaults(func=cmd_export)

    # import
    parser_import = subparsers.add_parser('import', help='Import encrypted backup')
    parser_import.add_argument('file', help='Input file path')
    parser_import.set_defaults(func=cmd_import)

    # migrate-from-env
    parser_migrate = subparsers.add_parser('migrate-from-env', help='Migrate from .env file')
    parser_migrate.add_argument('--keep-env', action='store_true', help='Keep .env file after migration')
    parser_migrate.set_defaults(func=cmd_migrate_from_env)

    args = parser.parse_args()

    try:
        args.func(args)
    except KeyboardInterrupt:
        print("\nAborted", file=sys.stderr)
        sys.exit(130)
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == '__main__':
    main()
