import json
from pathlib import Path
from typing import Annotated

import typer

from fernet_encrypt import cli
from fernet_encrypt.commands import (
    create_key,
    decrypt,
    decrypt_remote,
    encrypt,
    encrypt_remote,
    get_remote_keys,
    remote_login,
)
from fernet_encrypt.utils import KEY_PATH, api, logger


@cli.command(name="login", help=f"Sign up or Login to {api.REMOTE_API}")
def login():
    remote_login()


@cli.command(name="get-keys", help="Sync remote keys to fernet-encrypt local key storage")
def get_keys(
    stdout: Annotated[bool, typer.Option("--stdout", help="Output fetched keys as JSON to stdout")] = False,
):
    keys = get_remote_keys()

    if stdout:
        typer.echo(json.dumps(keys, indent=2))

    for key in keys:
        keyfile = KEY_PATH / f"{key['timestamp']}.key"
        with open(keyfile, "wb") as f:
            f.write(key["key"].encode("utf-8"))

        logger.debug(f"Created keyfile: {keyfile}")


@cli.command(name="create-local-key", help="Create a new local storage Fernet key")
def create_local_key():
    create_key()


@cli.command(name="encrypt-file", help="Encrypt a local file using local key storage or remote API keys")
def encrypt_file(
    input_file: Path = typer.Argument(default=..., exists=True, help="The input file to encrypt"),
    remote: Annotated[bool, typer.Option("--remote", help="Encrypt using the remote API")] = False,
):
    with open(input_file, "rb") as f:
        input_data = f.read()

    if remote:
        result = encrypt_remote(input_data, input_file.name)
    else:
        result = encrypt(input_data)

    typer.echo(result, nl=False)


@cli.command(name="decrypt-file", help="Decrypt a local file using local key storage or remote API keys")
def decrypt_file(
    input_file: Path = typer.Argument(default=..., exists=True, help="The input file to decrypt"),
    remote: Annotated[bool, typer.Option("--remote", help="Decrypt using the remote API")] = False,
):
    with open(input_file, "rb") as f:
        input_data = f.read()

    if remote:
        result = decrypt_remote(input_data, input_file.name)
    else:
        result = decrypt(input_data)

    typer.echo(result, nl=False)
