"""Weekly scheduling, dispatch, and mutable-authority host seam."""

from __future__ import annotations

import json
from collections.abc import Mapping, Sequence
from datetime import date, datetime
from pathlib import Path
from typing import TYPE_CHECKING, ClassVar

from pydantic import BaseModel, ConfigDict, StrictBool

from gateway.config import PlatformConfig
from gateway.platforms.telegram_weekly_host_capabilities import (
    TelegramWeeklyHostError,
)

if TYPE_CHECKING:
    from checkin_cli.weekly_operations_schedule_host_models_r4 import (
        WeeklyOperationsSchedulePolicy,
    )
    from gateway.platforms.nutrition_weekly_dispatcher import (
        WeeklyOperationsCoordinator,
        WeeklyOperationsTask,
    )
    from gateway.platforms.nutrition_weekly_reminder import (
        TelegramReminderDelivered,
        TelegramReminderRejected,
    )
    from gateway.platforms.nutrition_weekly_reminder_authority import (
        WeeklyOperationsTickSnapshot,
    )
    from gateway.platforms.telegram_edit_transport import TelegramEditOutcome
    from gateway.platforms.telegram_weekly_reminder import (
        WeeklyReminderCoordinator,
        WeeklyReminderTask,
    )
    from gateway.platforms.nutrition_weekly_owner_model import (
        JsonValue,
        WeeklyExplanationModel,
    )


class _WeeklyToggle(BaseModel):
    model_config: ClassVar[ConfigDict] = ConfigDict(extra="ignore", strict=True)
    enabled: StrictBool = False


class _NutritionToggle(BaseModel):
    model_config: ClassVar[ConfigDict] = ConfigDict(extra="ignore", strict=True)
    weekly_operations: _WeeklyToggle | None = None


class _ToggleEnvelope(BaseModel):
    model_config: ClassVar[ConfigDict] = ConfigDict(extra="ignore", strict=True)
    nutrition_coaching: _NutritionToggle | None = None


class TelegramWeeklyDispatchMixin:
    """Host the enabled dispatcher without growing the legacy adapter."""

    _weekly_platform_config: PlatformConfig | None = None
    _task26_candidate_digest: str | None = None
    _task26_service_revoked: bool | None = None
    _weekly_operations_explanation_model: WeeklyExplanationModel | None = None

    def _current_weekly_config(self) -> PlatformConfig | None:
        return self._weekly_platform_config

    def _current_weekly_service_revoked(self) -> bool:
        revoked = self._task26_service_revoked
        if revoked is None:
            raise TelegramWeeklyHostError(
                "Telegram weekly revocation state was not injected"
            )
        return revoked

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

    async def send_weekly_reminder(
        self, chat_id: str, topic_id: str | None, text: str,
    ) -> TelegramReminderDelivered | TelegramReminderRejected:
        _ = chat_id, topic_id, text
        raise NotImplementedError

    async def edit_weekly_topic59_outcome(
        self, chat_id: str, message_id: str, text: str,
    ) -> TelegramEditOutcome:
        _ = chat_id, message_id, text
        raise NotImplementedError

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

    async def _send_activation_completion_notices(
        self,
        profile_root: Path,
        coordinator: WeeklyOperationsCoordinator,
        *,
        kst_date: date,
    ) -> tuple[str, ...]:
        _ = profile_root, coordinator, kst_date
        raise NotImplementedError

    def _weekly_operations_schedule_policy(
        self,
    ) -> WeeklyOperationsSchedulePolicy | None:
        """Avoid importing profile scheduling while weekly operations is OFF."""
        config = self._current_weekly_config()
        if config is None:
            return None
        encoded = json.dumps(
            config.extra, sort_keys=True, separators=(",", ":"),
        )
        envelope = _ToggleEnvelope.model_validate_json(encoded)
        nutrition = envelope.nutrition_coaching
        if (
            nutrition is None
            or nutrition.weekly_operations is None
            or not nutrition.weekly_operations.enabled
        ):
            return None
        from gateway.platforms.telegram_weekly_reminder import (
            configured_weekly_schedule_policy,
        )

        return configured_weekly_schedule_policy(encoded)

    async def _send_weekly_operations_task(
        self,
        coordinator: WeeklyReminderCoordinator,
        task: WeeklyReminderTask,
        *,
        local_now: datetime,
    ) -> str | None:
        from gateway.platforms.telegram_weekly_reminder import (
            send_weekly_operations_task,
        )

        return await send_weekly_operations_task(
            self, coordinator, task, local_now=local_now,
        )

    async def _dispatch_weekly_operations_tick(
        self,
        coordinator: WeeklyOperationsCoordinator,
        tasks: Sequence[WeeklyOperationsTask],
        *,
        local_now: datetime,
    ) -> tuple[str, ...]:
        """Dispatch enabled work before generic provider work."""
        from gateway.platforms.nutrition_weekly_dispatcher import (
            dispatch_weekly_operations_tick,
        )

        return await dispatch_weekly_operations_tick(
            self, coordinator, tasks, local_now=local_now,
        )

    async def _run_weekly_operations_dispatch(
        self,
        tasks: Sequence[WeeklyOperationsTask],
        local_now: datetime,
    ) -> tuple[str, ...]:
        from gateway.platforms.nutrition_weekly_dispatcher import (
            WeeklyOperationsCoordinator,
        )

        coordinator = self._get_nutrition_coaching()
        if not isinstance(coordinator, WeeklyOperationsCoordinator):
            return ("weekly operations coordinator contract unavailable",)
        failures = list(
            await self._dispatch_weekly_operations_tick(
                coordinator, tasks, local_now=local_now,
            )
        )
        failures.extend(
            await self._send_activation_completion_notices(
                coordinator.profile_root,
                coordinator,
                kst_date=local_now.date(),
            )
        )
        return tuple(failures)

    def generate_weekly_explanation(
        self, request: Mapping[str, JsonValue],
    ) -> Mapping[str, JsonValue]:
        """Invoke only an explicitly installed weekly explanation model."""
        model = self._weekly_operations_explanation_model
        if model is None:
            raise OSError("weekly explanation provider is unavailable")
        return model.generate(request)

    def weekly_operations_authority_current(
        self, snapshot: WeeklyOperationsTickSnapshot,
    ) -> bool:
        """Reparse mutable host pins immediately before provider authority."""
        config = self._current_weekly_config()
        if config is None:
            raise TelegramWeeklyHostError("Telegram weekly config was not injected")
        if self._current_weekly_service_revoked():
            return False
        from gateway.platforms.nutrition_weekly_operations_config import (
            WeeklyOperationsAuthorityError,
            WeeklyOperationsConfigError,
        )
        from gateway.platforms.telegram_weekly_reminder import (
            configured_weekly_authority,
        )

        try:
            authority = configured_weekly_authority(
                json.dumps(
                    config.extra, sort_keys=True, separators=(",", ":"),
                ),
            )
        except (
            TypeError,
            ValueError,
            WeeklyOperationsAuthorityError,
            WeeklyOperationsConfigError,
        ):
            return False
        if authority is None:
            return False
        config, receipt = authority
        return (
            self._current_weekly_candidate_digest()
            == snapshot.runtime.candidate_digest
            and config == snapshot.config
            and receipt == snapshot.receipt
        )
