"""Celery tasks for manual recruiter-triggered synchronization flows."""

import logging
from typing import Any

from celery import shared_task
from django.contrib.auth import get_user_model

User = get_user_model()

logger = logging.getLogger(__name__)


def _sync_character_from_esi(character_id: int) -> None:
    """Run the character ESI refresh synchronously inside this task."""

    from allianceauth.eveonline.tasks import update_character  # pylint: disable=import-outside-toplevel

    update_character(character_id)


def _sync_autogroups_for_user(user: User) -> None:
    """Re-evaluate Alliance Auth autogroups for one user."""

    from allianceauth.eveonline.autogroups.models import AutogroupsConfig  # pylint: disable=import-outside-toplevel

    AutogroupsConfig.objects.update_groups_for_user(user)


def _get_discord_service_hook() -> Any:
    """Return the Discord service hook instance or None."""

    from allianceauth import hooks  # pylint: disable=import-outside-toplevel

    for hook in hooks.get_hooks("services_hook"):
        service = hook() if callable(hook) else hook
        if getattr(service, "name", "") == "discord":
            return service

    return None


def _sync_discord_for_user(user: User) -> None:
    """Queue role and nickname updates for one user on Discord service."""

    service = _get_discord_service_hook()
    if service is None:
        logger.warning("Discord service hook not found. Skipping discord sync for user=%s", user)
        return

    service.update_groups(user)
    service.sync_nickname(user)


@shared_task(name="jaystools.sync_user_esi_and_discord")
def sync_user_esi_and_discord(user_pk: int, triggered_by_user_pk: int = None) -> dict:
    """Synchronize one user in strict order after recruiter request.

    Order:
    1) Refresh character from ESI
    2) Recompute autogroups
    3) Queue Discord role and nickname sync
    """

    user = User.objects.select_related("profile", "profile__main_character").get(pk=user_pk)
    main_character = user.profile.main_character
    if main_character is None:
        raise ValueError(f"User {user} has no main character configured")

    logger.info(
        "Starting manual user sync for user=%s main_character=%s triggered_by=%s",
        user,
        main_character.character_id,
        triggered_by_user_pk,
    )

    _sync_character_from_esi(main_character.character_id)
    _sync_autogroups_for_user(user)
    _sync_discord_for_user(user)

    logger.info("Completed manual user sync for user=%s", user)

    return {
        "user_pk": user_pk,
        "main_character_id": main_character.character_id,
        "triggered_by_user_pk": triggered_by_user_pk,
    }
