"""KST reminder and cutoff projection for weekly operations."""

from __future__ import annotations

from collections.abc import Mapping
from datetime import date, datetime, timedelta
from zoneinfo import ZoneInfo

from .customer_coaching import CustomerRegistry
from .weekly_operations_schedule_host_models_r4 import (
    CustomerScheduleError,
    CustomerScheduleTask,
    WeeklyOperationsSchedulePolicy,
)

KST = ZoneInfo("Asia/Seoul")


def build_due_customer_tasks(
    registry: CustomerRegistry,
    now: datetime,
    *,
    missing_morning_checkins: Mapping[str, date] | None = None,
    reminder_evidence_present: bool = False,
    weekly_operations_policy: WeeklyOperationsSchedulePolicy | None = None,
) -> tuple[CustomerScheduleTask, ...]:
    """Return enabled due work after boundary evidence has been verified."""
    if now.tzinfo is None:
        raise CustomerScheduleError("schedule time must be timezone-aware")
    if (missing_morning_checkins is None) == reminder_evidence_present:
        raise CustomerScheduleError(
            "missing-checkin reminders require approved policy and config evidence"
        )
    local = now.astimezone(KST)
    local_day = local.date()
    local_time = local.time().replace(tzinfo=None)
    tasks: list[CustomerScheduleTask] = []
    for customer in registry.customers:
        spec = customer.spec
        pilot_start = spec.plan.starts_on
        pilot_end = pilot_start + timedelta(days=27)
        if (
            not spec.enabled
            or local_day < pilot_start
            or local_day > pilot_end
            or local_time < spec.schedule.daily_time
        ):
            continue
        tasks.append(CustomerScheduleTask(spec.customer_key, "daily", local_day))
        if local.weekday() == spec.schedule.weekly_weekday:
            tasks.append(CustomerScheduleTask(spec.customer_key, "weekly", local_day))
        if (
            weekly_operations_policy is not None
            and spec.customer_key in weekly_operations_policy.enabled_customer_keys
        ):
            if (
                weekly_operations_policy.reminder_time
                <= local_time
                < weekly_operations_policy.cutoff_time
            ):
                tasks.append(CustomerScheduleTask(spec.customer_key, "reminder", local_day))
            if local_time >= weekly_operations_policy.cutoff_time:
                tasks.append(CustomerScheduleTask(spec.customer_key, "cutoff", local_day))
        elif (
            missing_morning_checkins is not None
            and missing_morning_checkins.get(spec.customer_key) == local_day
        ):
            tasks.append(CustomerScheduleTask(spec.customer_key, "reminder", local_day))
    return tuple(tasks)
