"""CLI command for retention cleanup.

Usage:
    python -m noteflow.cli.retention cleanup [--dry-run]
    python -m noteflow.cli.retention status
"""

import argparse
import asyncio
import sys
from collections.abc import Callable
from typing import cast

from rich.console import Console

from noteflow.application.services import RetentionService
from noteflow.config.settings import get_settings
from noteflow.domain.ports.unit_of_work import UnitOfWork
from noteflow.infrastructure.logging import configure_logging, get_logger
from noteflow.infrastructure.persistence.unit_of_work import create_uow_factory

configure_logging()
logger = get_logger(__name__)
console = Console()


async def _run_cleanup(dry_run: bool) -> int:
    """Execute retention cleanup.

    Args:
        dry_run: If True, report but don't delete.

    Returns:
        Exit code (0 for success, 1 for errors).
    """
    settings = get_settings()

    if not settings.retention_enabled and not dry_run:
        logger.warning(
            "Retention is disabled. Set NOTEFLOW_RETENTION_ENABLED=true or use --dry-run"
        )
        return 1

    uow_factory = cast(Callable[[], UnitOfWork], create_uow_factory(settings))
    service = RetentionService(
        uow_factory=uow_factory,
        retention_days=settings.retention_days,
        enabled=settings.retention_enabled,
    )

    logger.info(
        "Running retention cleanup (dry_run=%s, retention_days=%d, cutoff=%s)",
        dry_run,
        service.retention_days,
        service.cutoff_date.isoformat(),
    )

    report = await service.run_cleanup(dry_run=dry_run)

    console.print("\n[bold]Retention Cleanup Report:[/bold]")
    console.print(f"  Meetings checked: {report.meetings_checked}")
    console.print(f"  Meetings deleted: {report.meetings_deleted}")

    if report.errors:
        console.print(f"  [yellow]Errors: {len(report.errors)}[/yellow]")
        for err in report.errors:
            console.print(f"    - {err}")
        return 1

    logger.info(
        "Retention cleanup: checked=%d deleted=%d errors=%d",
        report.meetings_checked,
        report.meetings_deleted,
        len(report.errors),
    )
    return 0


async def _show_status() -> int:
    """Show retention status and pending deletions.

    Returns:
        Exit code (always 0).
    """
    settings = get_settings()

    uow_factory = cast(Callable[[], UnitOfWork], create_uow_factory(settings))
    service = RetentionService(
        uow_factory=uow_factory,
        retention_days=settings.retention_days,
        enabled=settings.retention_enabled,
    )

    expired = await service.find_expired_meetings()

    console.print("\n[bold]Retention Status:[/bold]")
    console.print(f"  Enabled: {settings.retention_enabled}")
    console.print(f"  Retention days: {settings.retention_days}")
    console.print(f"  Check interval: {settings.retention_check_interval_hours} hours")
    console.print(f"  Cutoff date: {service.cutoff_date.isoformat()}")
    console.print(f"  Meetings pending deletion: {len(expired)}")

    if expired:
        console.print("\n  [dim]Pending deletions:[/dim]")
        for meeting in expired[:10]:  # Show first 10
            console.print(f"    - {meeting.id}: {meeting.title} (ended: {meeting.ended_at})")
        if len(expired) > 10:
            console.print(f"    [dim]... and {len(expired) - 10} more[/dim]")

    return 0


def main() -> None:
    """Entry point for retention CLI."""
    parser = argparse.ArgumentParser(
        description="NoteFlow meeting retention management",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )

    subparsers = parser.add_subparsers(dest="command", help="Available commands")

    # cleanup command
    cleanup_parser = subparsers.add_parser("cleanup", help="Run retention cleanup")
    cleanup_parser.add_argument(
        "--dry-run",
        action="store_true",
        help="Report what would be deleted without deleting",
    )

    # status command
    subparsers.add_parser("status", help="Show retention status")

    args = parser.parse_args()

    if not args.command:
        parser.print_help()
        sys.exit(1)

    if args.command == "cleanup":
        exit_code = asyncio.run(_run_cleanup(dry_run=args.dry_run))
    elif args.command == "status":
        exit_code = asyncio.run(_show_status())
    else:
        parser.print_help()
        exit_code = 1

    sys.exit(exit_code)


if __name__ == "__main__":
    main()
