"""Command-line interface for gworkspace-mcp."""

import asyncio
import sys
from pathlib import Path

import click
from dotenv import load_dotenv

from gworkspace_mcp.__version__ import __version__

# Load environment files in priority order (later files override earlier)
# 1. User config directory (lowest priority)
# 2. Project .env
# 3. Project .env.local (highest priority)
_user_env = Path.home() / ".gworkspace-mcp" / ".env"
_env_file = Path(".env")
_env_local = Path(".env.local")

if _user_env.exists():
    load_dotenv(_user_env, override=True)
if _env_file.exists():
    load_dotenv(_env_file, override=True)
if _env_local.exists():
    load_dotenv(_env_local, override=True)


@click.group()
@click.version_option(version=__version__)
def main() -> None:
    """Google Workspace MCP Server - Connect Claude to Google Workspace APIs.

    This tool provides 66 tools across:
    - Gmail (search, read, send, organize)
    - Calendar (events, availability)
    - Drive (files, folders, search)
    - Docs (read, create, edit)
    - Tasks (lists, tasks, management)
    """
    pass


def _add_to_gitignore(entry: str) -> bool:
    """Add an entry to .gitignore if not already present.

    Args:
        entry: The pattern to add (e.g., ".gworkspace-mcp/")

    Returns:
        True if entry was added, False if already present or no .gitignore
    """
    gitignore_path = Path(".gitignore")

    # Read existing content
    existing_lines: list[str] = []
    if gitignore_path.exists():
        existing_lines = gitignore_path.read_text().splitlines()

    # Check if entry already exists
    if entry in existing_lines or entry.rstrip("/") in existing_lines:
        return False

    # Add entry
    with open(gitignore_path, "a") as f:
        # Add newline if file doesn't end with one
        if existing_lines and existing_lines[-1]:
            f.write("\n")
        f.write(f"\n# gworkspace-mcp OAuth tokens (project-level)\n{entry}\n")

    return True


@main.command()
@click.option("--client-id", envvar="GOOGLE_OAUTH_CLIENT_ID", help="Google OAuth client ID")
@click.option(
    "--client-secret", envvar="GOOGLE_OAUTH_CLIENT_SECRET", help="Google OAuth client secret"
)
def setup(client_id: str | None, client_secret: str | None) -> None:
    """Set up Google Workspace OAuth authentication.

    This will:
    1. Open browser for OAuth2 consent flow
    2. Store refresh tokens at ./.gworkspace-mcp/tokens.json (PROJECT-LEVEL)
    3. Validate API access

    Note: Run this command from your project directory. Each project needs
    its own authentication for isolation.

    Requires:
    - GOOGLE_OAUTH_CLIENT_ID environment variable or --client-id option
    - GOOGLE_OAUTH_CLIENT_SECRET environment variable or --client-secret option
    """
    from gworkspace_mcp.auth import OAuthManager

    manager = OAuthManager()

    # Check if already authenticated
    if manager.has_valid_tokens():
        click.echo("✓ Already authenticated!")
        click.echo(f"Token stored at: {manager.token_path}")
        click.echo("")

        if not click.confirm("Re-authenticate?"):
            return

    # Validate credentials
    if not client_id or not client_secret:
        click.echo("❌ Error: OAuth client credentials required")
        click.echo("")
        click.echo("Set environment variables:")
        click.echo("  export GOOGLE_OAUTH_CLIENT_ID='your-client-id'")
        click.echo(
            "  export GOOGLE_OAUTH_CLIENT_SECRET='your-client-secret'"
        )  # pragma: allowlist secret  # noqa: E501
        click.echo("")
        click.echo("Or pass as options:")
        click.echo("  workspace setup --client-id=... --client-secret=...")
        sys.exit(1)

    # Run authentication
    click.echo("Starting OAuth authentication flow...")
    click.echo("Browser will open for Google consent...")
    click.echo("")

    try:
        asyncio.run(
            manager.authenticate(
                client_id=client_id,
                client_secret=client_secret,
            )
        )
        click.echo("✓ Authentication successful!")
        click.echo(f"Token stored at: {manager.token_path}")

        # Add .gworkspace-mcp/ to .gitignore
        if _add_to_gitignore(".gworkspace-mcp/"):
            click.echo("✓ Added .gworkspace-mcp/ to .gitignore")

        click.echo("")
        click.echo("Run 'gworkspace-mcp doctor' to verify setup.")
    except Exception as e:
        click.echo(f"❌ Authentication failed: {e}")
        sys.exit(1)


@main.command()
def mcp() -> None:
    """Start the MCP server for Claude Desktop integration.

    Starts the stdio MCP server that provides 66 tools across:
    - Gmail (18 tools): Search, send, organize, labels
    - Calendar (10 tools): Events, calendars, availability
    - Drive (17 tools): Files, folders, sharing, search
    - Docs (11 tools): Create, edit, comment management
    - Tasks (10 tools): Task lists and task management

    Authentication is required before starting the server.
    Run 'gworkspace-mcp setup' if not already authenticated.

    This command is typically invoked by Claude Desktop via the MCP protocol.
    """
    from gworkspace_mcp.auth import OAuthManager, TokenStatus
    from gworkspace_mcp.server import main as server_main

    # Check authentication status
    manager = OAuthManager()
    status, _ = manager.get_status()

    if status == TokenStatus.MISSING:
        click.echo("❌ Not authenticated. Run 'gworkspace-mcp setup' first.")
        sys.exit(1)

    if status == TokenStatus.INVALID:
        click.echo("❌ Token file corrupted. Run 'gworkspace-mcp setup' to re-authenticate.")
        sys.exit(1)

    # Start the MCP server (runs indefinitely)
    try:
        click.echo("Starting Google Workspace MCP server...", err=True)
        click.echo("Server provides 66 tools for Claude Desktop", err=True)
        click.echo("", err=True)
        server_main()
    except KeyboardInterrupt:
        click.echo("\nServer stopped.", err=True)
    except Exception as e:
        click.echo(f"❌ Server error: {e}", err=True)
        sys.exit(1)


@main.command()
@click.option("--dry-run", is_flag=True, help="Show what would be migrated without making changes")
def migrate(dry_run: bool) -> None:
    """Run pending migrations.

    Migrations handle schema changes, directory renames, and configuration
    updates when upgrading between versions.

    Use --dry-run to preview what changes would be made without applying them.
    """
    from gworkspace_mcp.migrations import MigrationRunner

    runner = MigrationRunner()

    def progress(msg: str) -> None:
        click.echo(msg)

    runner.set_progress_callback(progress)

    pending = runner.get_pending_migrations()
    if not pending:
        click.echo("No pending migrations.")
        return

    click.echo(f"Found {len(pending)} pending migration(s):")
    for m in pending:
        click.echo(f"  - {m.id}: {m.description}")
    click.echo("")

    if dry_run:
        click.echo("Dry-run mode - showing what would happen:")
        click.echo("")

    applied = runner.run_all_pending(dry_run=dry_run)

    click.echo("")
    if dry_run:
        click.echo(f"Would apply {len(applied)} migration(s).")
    else:
        click.echo(f"Applied {len(applied)} migration(s).")


@main.command("migration-status")
def migration_status() -> None:
    """Show migration status.

    Displays the current schema version, applied migrations,
    and any pending migrations that need to be run.
    """
    from gworkspace_mcp.migrations import MigrationRunner

    runner = MigrationRunner()
    status = runner.get_status()

    click.echo("Migration Status:")
    click.echo(f"  Current version: {status['current_version']}")
    click.echo(f"  Total migrations: {status['total_migrations']}")
    click.echo(f"  Applied: {status['applied_count']}")
    click.echo(f"  Pending: {status['pending_count']}")
    click.echo("")

    if status["applied_migrations"]:
        click.echo("Applied migrations:")
        for m in status["applied_migrations"]:
            click.echo(f"  - {m['id']} (v{m['version']}) applied at {m['applied_at']}")
        click.echo("")

    if status["pending_migrations"]:
        click.echo("Pending migrations:")
        for m in status["pending_migrations"]:
            click.echo(f"  - {m['id']} (v{m['version']}): {m['description']}")
        click.echo("")
        click.echo("Run 'workspace migrate' to apply pending migrations.")
    else:
        click.echo("All migrations applied.")


@main.command()
def doctor() -> None:
    """Check installation and authentication status.

    Verifies:
    1. Python dependencies installed
    2. OAuth credentials configured
    3. Token validity

    Note: Authentication is PROJECT-LEVEL. Each project directory requires
    its own 'gworkspace-mcp setup' to authenticate.
    """
    from pathlib import Path

    from gworkspace_mcp.auth import OAuthManager, TokenStatus

    click.echo("Google Workspace MCP Status:")
    click.echo("")

    # Show current project context
    click.echo("Project:")
    click.echo(f"  Working directory: {Path.cwd()}")
    click.echo("")

    # Check dependencies
    click.echo("Dependencies:")
    try:
        import google.auth  # noqa: F401
        import google_auth_oauthlib  # noqa: F401

        click.echo("  ✓ google-auth installed")
        click.echo("  ✓ google-auth-oauthlib installed")
    except ImportError as e:
        click.echo(f"  ❌ Missing dependency: {e}")
        sys.exit(1)

    click.echo("")

    # Check authentication
    manager = OAuthManager()
    status, stored = manager.get_status()

    click.echo("Authentication:")
    click.echo(f"  Token file: {manager.token_path}")

    if status == TokenStatus.MISSING:
        click.echo("  ❌ Not authenticated")
        click.echo("")
        click.echo("Run 'gworkspace-mcp setup' FROM THIS DIRECTORY to authenticate.")
        click.echo("(Authentication is project-specific)")
        sys.exit(1)
    elif status == TokenStatus.INVALID:
        click.echo("  ❌ Token file corrupted")
        click.echo("")
        click.echo("Run 'gworkspace-mcp setup' to re-authenticate.")
        sys.exit(1)
    elif status == TokenStatus.EXPIRED:
        click.echo("  ⚠️  Token expired (can be refreshed)")
        click.echo("")
        click.echo("Run 'gworkspace-mcp setup' or token will refresh automatically on use.")
    elif status == TokenStatus.VALID:
        click.echo("  ✓ Authenticated")
        if stored:
            click.echo(
                f"  Token expires: {stored.token.expires_at.strftime('%Y-%m-%d %H:%M:%S UTC')}"
            )
            click.echo(f"  Scopes: {len(stored.token.scopes)} configured")

    click.echo("")

    if status in (TokenStatus.VALID, TokenStatus.EXPIRED):
        click.echo("✓ Ready to use!")
    else:
        click.echo("❌ Setup required. Run 'gworkspace-mcp setup' from this directory.")


if __name__ == "__main__":
    main()
