"""
This module provides the Command Line Interface for File Vault.
It uses click to define commands for encrypting/decrypting files and folders,
and displaying the status of files in the current directory.
"""

import os
import pathlib
import time
import click

from filevault.core import engine, key_manager, file_detector


@click.group()
@click.version_option(version="1.0.0")
def main():
    """File Vault: Encrypt and decrypt files in place using AES-256-GCM."""
    pass


@main.command()
@click.argument('filename', type=click.Path(exists=False))
@click.option('--password', '-p', help='The password to use for encryption.')
def encrypt(filename, password):
    """Encrypt a single file in place."""
    path = pathlib.Path(filename)
    if not path.exists():
        click.echo(f"No file named {filename} in this folder.")
        return

    try:
        if not password:
            password = key_manager.prompt_encrypt_password()
        engine.encrypt_file(str(path), password)
        click.echo(f"Locked: {filename} (content encrypted in place)")
    except ValueError as e:
        msg = str(e)
        if "already encrypted" in msg:
            click.echo("Already encrypted — decrypt it first.")
        elif "not supported" in msg or "protected" in msg:
            click.echo(f"{filename} cannot be encrypted ({msg})")
        else:
            click.echo(f"Error: {msg}")
    except Exception as e:
        click.echo(f"An unexpected error occurred: {e}")


@main.command()
@click.argument('filename', type=click.Path(exists=False))
@click.option('--password', '-p', help='The password to use for decryption.')
def decrypt(filename, password):
    """Decrypt a single file in place."""
    path = pathlib.Path(filename)
    if not path.exists():
        click.echo(f"No file named {filename} in this folder.")
        return

    try:
        if not password:
            password = key_manager.prompt_decrypt_password()
        engine.decrypt_file(str(path), password)
        click.echo(f"Unlocked: {filename} (content restored in place)")
    except ValueError as e:
        msg = str(e)
        if "Wrong password" in msg:
            click.echo(f"Wrong password. {filename} was not modified.")
        elif "not encrypted" in msg:
            click.echo(f"{filename} is not encrypted.")
        else:
            click.echo(f"Error: {msg}")
    except Exception as e:
        click.echo(f"An unexpected error occurred: {e}")


@main.command(name="encrypt-folder")
def encrypt_folder():
    """Encrypt all supported files in the current folder."""
    cwd = os.getcwd()
    files_to_encrypt = []
    
    # Pre-scan for confirmation
    for item in pathlib.Path(cwd).iterdir():
        if item.is_file():
            supported, _ = file_detector.is_supported(str(item))
            if supported and not file_detector.is_encrypted(str(item)):
                files_to_encrypt.append(item)

    if not files_to_encrypt:
        click.echo("No eligible files found to encrypt in this folder.")
        return

    click.echo(f"Found {len(files_to_encrypt)} files to encrypt in this folder.")
    if not click.confirm("Continue?", default=False):
        click.echo("Aborted.")
        return

    password = key_manager.prompt_encrypt_password()
    results = engine.encrypt_folder(cwd, password)

    click.echo(f"Done. Encrypted: {len(results['encrypted'])} | Skipped: {len(results['skipped'])} | Errors: {len(results['errors'])}")
    if results['errors']:
        for filename, error in results['errors']:
            click.echo(f"  - {filename}: {error}")


@main.command(name="decrypt-folder")
def decrypt_folder():
    """Decrypt all encrypted files in the current folder."""
    cwd = os.getcwd()
    files_to_decrypt = []

    # Pre-scan for confirmation
    for item in pathlib.Path(cwd).iterdir():
        if item.is_file() and file_detector.is_encrypted(str(item)):
            files_to_decrypt.append(item)

    if not files_to_decrypt:
        click.echo("No encrypted files found in this folder.")
        return

    click.echo(f"Found {len(files_to_decrypt)} files to decrypt in this folder.")
    if not click.confirm("Continue?", default=False):
        click.echo("Aborted.")
        return

    password = key_manager.prompt_decrypt_password()
    results = engine.decrypt_folder(cwd, password)

    click.echo(f"Done. Decrypted: {len(results['decrypted'])} | Skipped: {len(results['skipped'])} | Errors: {len(results['errors'])}")
    if results['errors']:
        for filename, error in results['errors']:
            click.echo(f"  - {filename}: {error}")


@main.command()
def status():
    """Show the encryption status of files in the current folder."""
    cwd = os.getcwd()
    items = sorted(list(pathlib.Path(cwd).iterdir()))
    
    # Header
    header = f"{'Filename':<30} | {'Type':<8} | {'Status':<10} | {'Last Modified':<20}"
    click.echo(header)
    click.echo("-" * len(header))

    for item in items:
        if not item.is_file():
            continue

        filename = item.name
        if len(filename) > 30:
            filename = filename[:27] + "..."
        
        ext = item.suffix.lower() if item.suffix else "none"
        is_enc = file_detector.is_encrypted(str(item))
        status_text = "ENCRYPTED" if is_enc else "plaintext"
        
        mtime = os.path.getmtime(item)
        last_modified = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(mtime))

        click.echo(f"{filename:<30} | {ext:<8} | {status_text:<10} | {last_modified:<20}")


if __name__ == "__main__":
    main()
