"""Final advisory summary publication for the isolated preview."""

from __future__ import annotations

import logging
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from datetime import date

from checkin_cli.nutrition_onboarding_clarification_policy import (
    compile_clarification_policy,
)

from gateway.platforms.nutrition_onboarding_reconciliation import (
    NutritionOnboardingClarification,
    NutritionOnboardingReconciliation,
    NutritionOnboardingReconciler,
    ReconciliationError,
    ReconciliationUnavailable,
    render_authoritative_customer_summary,
)
from gateway.platforms.nutrition_onboarding_reconciliation_copy import (
    render_clarification_text,
)
from gateway.platforms.telegram_nutrition_onboarding_preview_types import (
    PreviewRoute,
)

logger = logging.getLogger(__name__)


@dataclass(frozen=True)
class PreviewCompletion:
    text: str
    phase: str
    clarifications: tuple[NutritionOnboardingClarification, ...] = ()


def log_clarification_receipt(
    route: PreviewRoute,
    *,
    message_id: str,
    field: str,
) -> None:
    logger.warning(
        "Nutrition onboarding preview clarification published: "
        "chat=%s topic=%s message_id=%s field=%s",
        route.chat_id,
        route.topic_id,
        message_id,
        field,
    )


async def send_preview_card(
    sender: Callable[
        [PreviewRoute, str, bool, str | None, str | None],
        Awaitable[object],
    ],
    route: PreviewRoute,
    text: str,
    force_reply: bool,
    reply_to_message_id: str | None,
    action: str | None,
) -> object | None:
    try:
        return await sender(
            route,
            text,
            force_reply,
            reply_to_message_id,
            action,
        )
    except Exception:
        logger.warning(
            "Nutrition preview flow publication failed",
            exc_info=True,
        )
        return None


async def reconcile_preview_answers(
    *,
    reconciler: NutritionOnboardingReconciler,
    answers: tuple[tuple[str, object], ...],
) -> NutritionOnboardingReconciliation | None:
    try:
        return await reconciler.reconcile(
            dict(answers),
            consent_granted=True,
        )
    except (
        ReconciliationError,
        ReconciliationUnavailable,
    ) as exc:
        logger.warning(
            "Nutrition preview advisory summary unavailable: %s",
            type(exc).__name__,
        )
        return None


def replace_answer(
    answers: tuple[tuple[str, object], ...],
    *,
    field: str,
    value: object,
) -> tuple[tuple[str, object], ...]:
    return tuple(
        (name, value if name == field else current)
        for name, current in answers
    )


async def build_preview_completion(
    *,
    reconciler: NutritionOnboardingReconciler,
    answers: tuple[tuple[str, object], ...],
    allow_clarifications: bool,
    reference_date: date,
) -> PreviewCompletion:
    policy = compile_clarification_policy(
        dict(answers),
        reference_date=reference_date,
    )
    await reconcile_preview_answers(
        reconciler=reconciler,
        answers=answers,
    )
    clarifications = tuple(
        NutritionOnboardingClarification(
            field=issue.field,
            kind="ambiguity",
            question_ko=issue.question_ko,
        )
        for issue in policy.issues
        if issue.issue_id in policy.visible_issue_ids
    )
    if clarifications:
        return PreviewCompletion(
            text=render_clarification_text(
                clarifications[0],
                index=1,
                total=len(clarifications),
            ),
            phase="clarifying",
            clarifications=clarifications,
        )
    return PreviewCompletion(
        text=(
            "입력 내용을 정리했어요\n\n"
            + render_authoritative_customer_summary(dict(answers))
            + "\n\n[PREVIEW] 입력값은 저장되지 않았습니다. "
            "버튼을 누르면 운영자 검토 단계가 어떻게 이어지는지 "
            "미리 보여드립니다."
        ),
        phase="confirming",
    )
