import os
from pathlib import Path

import click

from earthscale import EarthscaleClient, NotFoundError
from earthscale.v1.settings import EarthscaleSettings

_CLI_STATE_DIR = Path(click.get_app_dir("earthscale"))
_LAST_EMAIL_FILE = _CLI_STATE_DIR / "last_email"


def _get_last_email() -> str | None:
    try:
        return _LAST_EMAIL_FILE.read_text().strip() or None
    except FileNotFoundError:
        return None


def _save_last_email(email: str) -> None:
    _CLI_STATE_DIR.mkdir(parents=True, exist_ok=True)
    _LAST_EMAIL_FILE.write_text(email)


def _prompt_local_credentials_if_needed() -> None:
    """Prompt for email/password if running against local Supabase."""
    settings = EarthscaleSettings()
    is_local = "localhost" in settings.auth_url or "127.0.0.1" in settings.auth_url
    if not is_local:
        return
    if settings.email and settings.password:
        return
    click.echo("Local Supabase detected — please enter credentials.")
    last_email = _get_last_email()
    while True:
        email = click.prompt("Email", default=last_email)
        password = click.prompt("Password", hide_input=True)
        os.environ["EARTHSCALE_EMAIL"] = email
        os.environ["EARTHSCALE_PASSWORD"] = password
        try:
            client = EarthscaleClient(skip_version_check=True)
            client.login()
            _save_last_email(email)
            return
        except Exception as e:
            click.secho(
                f"Authentication failed: {e!s}. Please try again.",
                err=True,
                fg="red",
            )


@click.group()
def cli() -> None:
    """Earthscale command line tool."""
    pass


@cli.command(help="Add a dataset to Earthscale using only a name and a URL.")
@click.argument("url")
@click.option(
    "-n",
    "--name",
    required=True,
    help="Name of the dataset as it will appear in Earthscale.",
)
@click.option(
    "-t",
    "--type",
    type=click.Choice(["vector", "image", "zarr", "tile_server"]),
    default="vector",
    help="Type of dataset to add. Defaults to vector.",
)
@click.option(
    "-p",
    "--proxy",
    is_flag=True,
    help="Use the proxy server for authentication.",
)
def add(
    url: str,
    name: str,
    type: str,
    proxy: bool,
) -> None:
    _prompt_local_credentials_if_needed()
    with EarthscaleClient(use_proxy=proxy) as client:
        try:
            if type == "vector":
                response = client.add_vector_dataset(name=name, url=url)
            elif type == "image":
                response = client.add_image_dataset(name=name, url=url)
            elif type == "zarr":
                response = client.add_zarr_dataset(name=name, url=url)
            elif type == "tile_server":
                response = client.add_tile_server_dataset(name=name, url=url)
            else:
                raise ValueError(f"Unknown dataset type: {type}")

            click.secho(
                f"Successfully added {type} dataset '{name}' with ID:"
                f" {response.dataset_id}",
                fg="green",
            )
        except Exception as e:
            click.secho(f"Failed to add dataset: {e!s}", err=True, fg="red")
            raise click.Abort() from None


@cli.command(help="Delete a dataset from Earthscale.")
@click.argument("dataset_id")
@click.option(
    "--keep-in-maps",
    is_flag=True,
    help="Keep the dataset in maps instead of removing it.",
)
@click.option(
    "-p",
    "--proxy",
    is_flag=True,
    help="Use the proxy server for authentication.",
)
@click.option(
    "-y",
    "--yes",
    is_flag=True,
    help="Skip confirmation prompt.",
)
def delete(
    dataset_id: str,
    keep_in_maps: bool,
    proxy: bool,
    yes: bool,
) -> None:
    _prompt_local_credentials_if_needed()
    with EarthscaleClient(use_proxy=proxy) as client:
        try:
            # Fetch dataset info for confirmation
            try:
                dataset = client.get_dataset(dataset_id)
            except NotFoundError:
                dataset = client.get_dataset_version_by_id(dataset_id)

            if not yes:
                click.echo(f"  Name:       {dataset.name}")
                click.echo(f"  Dataset ID: {dataset.dataset_id}")
                click.echo(f"  Created:    {dataset.created_at}")
                if not click.confirm("Are you sure you want to delete this dataset?"):
                    raise click.Abort()

            response = client.delete_dataset(
                dataset_id=dataset_id,
                remove_from_maps=not keep_in_maps,
            )
            click.secho(
                f"Successfully deleted dataset {response.dataset_id}",
                fg="green",
            )
        except click.Abort:
            raise
        except Exception as e:
            click.secho(f"Failed to delete dataset: {e!s}", err=True, fg="red")
            raise click.Abort() from None


@cli.command(help="Authenticate with Earthscale.")
@click.option(
    "-p",
    "--proxy",
    is_flag=True,
    help="Use the proxy server for authentication.",
)
def authenticate(proxy: bool) -> None:
    client = EarthscaleClient(use_proxy=proxy)
    # This automatically saves credentials after login
    try:
        client.login()
        click.secho("Successfully authenticated with Earthscale.", fg="green")
    except Exception as e:
        click.secho(
            f"Failed to authenticate with Earthscale: {e!s}", err=True, fg="red"
        )
        raise click.Abort() from None


if __name__ == "__main__":
    cli()
