"""Handle installation events — created, deleted, suspend, unsuspend."""

from __future__ import annotations

import logging

from specwright import analytics

from . import fire_and_forget
from .onboarding import onboard_repos

logger = logging.getLogger(__name__)


def _get_app_state():
    """Import app and return its state. Returns None if unavailable."""
    try:
        from specwright.main import app

        return app.state
    except Exception:
        return None


async def on_installation(client, payload: dict, *, _app_state=None) -> None:
    """Handle a GitHub App installation event.

    Args:
        client: GitHubClient instance (scoped to the installation).
        payload: The webhook payload.
        _app_state: Injected app state (for testing). Falls back to main app.
    """
    action = payload.get("action", "")
    installation = payload.get("installation", {})
    installation_id = installation.get("id", 0)
    account = installation.get("account", {})
    org_login = account.get("login", "")
    org_id = account.get("id", 0)
    app_id = str(installation.get("app_id", ""))

    logger.info(
        "installation event: action=%s org=%s installation_id=%s",
        action,
        org_login,
        installation_id,
    )

    state = _app_state or _get_app_state()
    if state is None:
        logger.warning("Could not access app state for installation event")
        return

    registry = getattr(state, "registry", None)
    if registry is None:
        logger.info("No registry available — skipping installation event")
        return

    if action == "created":
        await registry.upsert_installation(
            installation_id=installation_id,
            org_login=org_login,
            org_id=org_id,
            app_id=app_id,
        )
        logger.info("Registered installation %s for %s", installation_id, org_login)

        analytics.group("organization", org_login, {"installation_id": installation_id})
        analytics.track(
            "app_installed",
            properties={"org": org_login, "installation_id": installation_id},
            groups={"organization": org_login},
        )

        # Schedule background indexing
        indexer = getattr(state, "indexer", None)
        search_index = getattr(state, "search_index", None)
        embed_client = getattr(state, "embed_client", None)

        if indexer is not None and search_index is not None:
            indexer.schedule_org_index(
                installation_id=installation_id,
                org_login=org_login,
                client=client,
                search_index=search_index,
                embed_client=embed_client,
                registry=registry,
            )
            logger.info("Scheduled background indexing for %s", org_login)

        # Schedule background onboarding (repos are already in the payload)
        repos = payload.get("repositories", [])
        if repos:
            fire_and_forget(onboard_repos(client, repos))

    elif action == "deleted":
        await registry.mark_removed(installation_id)
        logger.info("Marked installation %s as removed", installation_id)

        analytics.track(
            "app_uninstalled",
            properties={"org": org_login, "installation_id": installation_id},
            groups={"organization": org_login},
        )

    elif action == "suspend":
        await registry.mark_suspended(installation_id)
        logger.info("Marked installation %s as suspended", installation_id)

    elif action == "unsuspend":
        await registry.mark_unsuspended(installation_id)
        logger.info("Marked installation %s as unsuspended", installation_id)
