from importlib.resources import files
from typing import Optional

import typer
from alembic import command
from alembic.config import Config

from vdash.config import Settings

app = typer.Typer(help="Database migration commands.")


def _resolve_db_url(db_url: Optional[str]) -> str:
    if db_url:
        return db_url
    return Settings.get_db_url()


def _alembic_config(db_url: str) -> Config:
    migrations_path = files("vdash").joinpath("migrations")
    cfg = Config()
    cfg.set_main_option("script_location", str(migrations_path))
    cfg.set_main_option("sqlalchemy.url", db_url)
    return cfg


@app.command()
def upgrade(
    revision: str = typer.Argument("head", help="Target revision, default is head."),
    db_url: Optional[str] = typer.Option(
        None,
        "--db-url",
        envvar="MDASH_DB_URL",
        help="Database URL, defaults to Settings().db_url.",
    ),
) -> None:
    cfg = _alembic_config(_resolve_db_url(db_url))
    command.upgrade(cfg, revision)


@app.command()
def downgrade(
    revision: str = typer.Argument("-1", help="Target revision, default is -1."),
    db_url: Optional[str] = typer.Option(
        None,
        "--db-url",
        envvar="MDASH_DB_URL",
        help="Database URL, defaults to Settings().db_url.",
    ),
) -> None:
    cfg = _alembic_config(_resolve_db_url(db_url))
    command.downgrade(cfg, revision)


@app.command()
def revision(
    message: str = typer.Option(..., "--message", "-m", help="Revision message."),
    autogenerate: bool = typer.Option(
        False,
        "--autogenerate",
        help="Populate revision script based on model changes.",
    ),
    db_url: Optional[str] = typer.Option(
        None,
        "--db-url",
        envvar="MDASH_DB_URL",
        help="Database URL, defaults to Settings().db_url.",
    ),
) -> None:
    cfg = _alembic_config(_resolve_db_url(db_url))
    command.revision(cfg, message=message, autogenerate=autogenerate)


@app.command()
def current(
    db_url: Optional[str] = typer.Option(
        None,
        "--db-url",
        envvar="MDASH_DB_URL",
        help="Database URL, defaults to Settings().db_url.",
    ),
) -> None:
    cfg = _alembic_config(_resolve_db_url(db_url))
    command.current(cfg)


@app.command()
def history(
    verbose: bool = typer.Option(False, "--verbose", help="Show detailed output."),
    db_url: Optional[str] = typer.Option(
        None,
        "--db-url",
        envvar="MDASH_DB_URL",
        help="Database URL, defaults to Settings().db_url.",
    ),
) -> None:
    cfg = _alembic_config(_resolve_db_url(db_url))
    command.history(cfg, verbose=verbose)
