"""Owned weekly-reminder capabilities for the Telegram host."""

from __future__ import annotations

import sys
from contextlib import ExitStack
from pathlib import Path
from dataclasses import dataclass
from typing import TYPE_CHECKING, Protocol, override

from gateway.config import PlatformConfig
if TYPE_CHECKING:
    from checkin_cli.customer_coaching import CustomerRegistry

    from gateway.platforms.nutrition_coaching import NutritionCoachingCoordinator
    from gateway.platforms.nutrition_weekly_owner_model import WeeklyExplanationModel
    from gateway.platforms.nutrition_weekly_reminder_authority import (
        RegisteredWeeklyReminderCustomer,
    )
    from gateway.platforms.nutrition_weekly_reminder_bootstrap_config import (
        OwnedWeeklyReminderCustomers,
    )
    from gateway.platforms.nutrition_weekly_reminder_owner_factory import (
        WeeklyReminderProductionInput,
    )


class TelegramWeeklyRuntimeHost(Protocol):
    def _current_weekly_config(self) -> PlatformConfig | None: ...

    def _current_weekly_service_revoked(self) -> bool: ...

    def _current_weekly_candidate_digest(self) -> str | None: ...


@dataclass(frozen=True, slots=True)
class TelegramWeeklyHostError(RuntimeError):
    reason: str

    @override
    def __str__(self) -> str:
        return self.reason


@dataclass(frozen=True, slots=True)
class TelegramWeeklyCapabilities:
    ownership: OwnedWeeklyReminderCustomers
    customers: tuple[RegisteredWeeklyReminderCustomer, ...]


def open_telegram_weekly_capabilities(
    config: PlatformConfig,
    customers: tuple[RegisteredWeeklyReminderCustomer, ...] | None,
) -> TelegramWeeklyCapabilities:
    """Acquire configured or explicitly supplied reminder capabilities."""
    from gateway.platforms.nutrition_weekly_reminder_bootstrap_config import (
        new_owned_weekly_reminder_customers,
    )

    if customers is not None:
        ownership = new_owned_weekly_reminder_customers()
        for customer in customers:
            ownership.add_customer(customer)
        return TelegramWeeklyCapabilities(ownership, ownership.customers)

    from gateway.platforms.nutrition_weekly_reminder_bootstrap import (
        load_registered_weekly_reminder_customers,
    )

    with ExitStack() as transaction:
        ownership = load_registered_weekly_reminder_customers(config)
        try:
            sys.audit("nutricoach.weekly_reminder.caller_received_before_outer_enter")
        except BaseException:
            ownership.close()
            raise
        _ = transaction.enter_context(ownership)
        sys.audit("nutricoach.weekly_reminder.after_outer_enter")
        sys.audit("nutricoach.weekly_reminder.before_adapter_attribute_assignment")
        capabilities = TelegramWeeklyCapabilities(ownership, ownership.customers)
        sys.audit("nutricoach.weekly_reminder.after_adapter_attribute_assignment")
        sys.audit("nutricoach.weekly_reminder.before_outer_pop")
        transferred = transaction.pop_all()
        try:
            sys.audit("nutricoach.weekly_reminder.after_outer_pop")
        except BaseException:
            transferred.close()
            raise
        return capabilities


class TelegramWeeklyCapabilityMixin:
    """Expose lifecycle-owned weekly customer capabilities."""

    _weekly_platform_config: PlatformConfig | None = None
    _weekly_reminder_customers: tuple[RegisteredWeeklyReminderCustomer, ...] = ()
    _weekly_reminder_ownership: OwnedWeeklyReminderCustomers | None = None
    _weekly_operations_explanation_model: WeeklyExplanationModel | None = None

    def _get_nutrition_coaching(
        self,
    ) -> NutritionCoachingCoordinator | None:
        raise NotImplementedError

    def initialize_nutrition_coaching(
        self,
    ) -> NutritionCoachingCoordinator | None:
        """Initialize the coordinator under owned weekly capabilities."""
        return self._get_nutrition_coaching()

    def _open_weekly_capabilities(
        self,
        config: PlatformConfig,
        customers: tuple[RegisteredWeeklyReminderCustomer, ...] | None,
    ) -> None:
        capabilities = open_telegram_weekly_capabilities(config, customers)
        self._weekly_platform_config = config
        self._weekly_reminder_ownership = capabilities.ownership
        self._weekly_reminder_customers = capabilities.customers

    def _weekly_reminder_production_input(
        self,
        candidate_digest: str | None,
        registry: CustomerRegistry,
        registry_path: Path,
    ) -> WeeklyReminderProductionInput:
        from gateway.platforms.nutrition_weekly_reminder_owner_factory import (
            WeeklyReminderProductionInput,
        )

        config = self._weekly_platform_config
        if config is None:
            raise TelegramWeeklyHostError("Telegram weekly host config is unavailable")
        return WeeklyReminderProductionInput(
            config.extra, candidate_digest, registry, registry_path,
            self._weekly_reminder_customers,
        )

    @property
    def weekly_reminder_customers(
        self,
    ) -> tuple[RegisteredWeeklyReminderCustomer, ...]:
        return self._weekly_reminder_customers

    def close_weekly_reminder_capabilities(self) -> None:
        ownership = self._weekly_reminder_ownership
        if ownership is not None:
            ownership.close()
            self._weekly_reminder_ownership = None
        self._weekly_reminder_customers = ()
