"""CLI entrypoints for the PIP platform."""
import asyncio
import sys

import click

from src.core.logging import configure_logging, get_logger
from src.infrastructure.cache.redis_cache import redis_cache
from src.infrastructure.config.settings import settings
from src.infrastructure.database.session import async_session_factory, engine
from src.infrastructure.messaging.rabbitmq import rabbitmq_client
from src.services.auth.auth_service import AuthService
from src.domain.entities import UserRole


@click.group()
def cli():
    """PIP platform CLI."""
    configure_logging()


@cli.command()
def run():
    """Start the API server."""
    import uvicorn
    uvicorn.run(
        "src.main:app",
        host="0.0.0.0",
        port=8000,
        reload=True if settings.DEBUG else False,
        log_level=settings.LOG_LEVEL.lower(),
    )


@cli.command()
def migrate_upgrade():
    """Apply database migrations."""
    from alembic.config import Config
    from alembic import command

    cfg = Config("alembic.ini")
    command.upgrade(cfg, "head")
    click.echo("Migrations applied.")


@cli.command()
def migrate_downgrade():
    """Roll back the last database migration."""
    from alembic.config import Config
    from alembic import command

    cfg = Config("alembic.ini")
    command.downgrade(cfg, "-1")
    click.echo("Rollback complete.")


@cli.command()
def migrate_revision():
    """Create a new database revision."""
    from alembic.config import Config
    from alembic import command

    message = click.prompt("Revision message")
    cfg = Config("alembic.ini")
    command.revision(cfg, autogenerate=True, message=message)
    click.echo("Revision created.")


@cli.command()
@click.option("--username", required=True)
@click.option("--password", required=True)
@click.option("--email", default=None)
@click.option("--role", default="admin", type=click.Choice([r.value for r in UserRole]))
def create_user(username: str, password: str, email: str | None, role: str):
    """Create a technical user."""
    asyncio.run(_create_user(username, password, email, role))


async def _create_user(username: str, password: str, email: str | None, role: str):
    async with async_session_factory() as session:
        service = AuthService(session)
        user = await service.register(
            username=username,
            password=password,
            email=email,
            role=UserRole(role),
        )
        click.echo(f"Created user '{user.username}' with role '{user.role.value}'.")


@cli.command()
def health():
    """Check platform health across services."""
    asyncio.run(_health())


async def _health():
    logger = get_logger("cli.health")
    async with engine.begin() as conn:
        await conn.run_sync(lambda s: None)
    click.echo("Database: OK")

    await redis_cache.connect()
    ok = await redis_cache.health_check()
    click.echo(f"Redis: {'OK' if ok else 'FAIL'}")
    await redis_cache.disconnect()

    await rabbitmq_client.connect()
    ok = await rabbitmq_client.health_check()
    click.echo(f"RabbitMQ: {'OK' if ok else 'FAIL'}")
    await rabbitmq_client.disconnect()

    await engine.dispose()


if __name__ == "__main__":
    cli()
