"""Typed weekly scheduling values shared by the schedule ledger host."""

from __future__ import annotations

import re
from collections.abc import Iterator, Mapping
from dataclasses import dataclass, field
from datetime import date, datetime, time
from typing import Final, Literal, override

ReceiptValue = str | int | bool | None
TaskKind = Literal["daily", "weekly", "monthly", "reminder", "cutoff"]
_TERMINAL_STATES: Final = frozenset(
    {"unknown", "known_failure", "sent_audited", "abandoned"}
)
_VALID_DIGEST: Final = re.compile(r"[0-9a-f]{64}")


class CustomerScheduleError(ValueError):
    """Raised when schedule state is corrupt, incomplete, or unsafe."""


@dataclass(frozen=True, slots=True)
class NonResponseReviewCandidate:
    """A deterministic operator-review signal; never a delivery instruction."""

    correlation_id: str
    customer_key: str
    missing_window: date
    reminder_reservation_id: str
    response_window_ends_at: datetime


@dataclass(frozen=True, slots=True)
class CustomerScheduleTask:
    customer_key: str
    kind: TaskKind
    kst_day: date


@dataclass(frozen=True, slots=True)
class WeeklyOperationsSchedulePolicy:
    """Exact KST evaluator policy for separately authorized customers."""

    enabled_customer_keys: frozenset[str]
    reminder_time: time = time(20)
    cutoff_time: time = time(23)

    def __post_init__(self) -> None:
        if self.reminder_time != time(20) or self.cutoff_time != time(23):
            raise CustomerScheduleError("weekly operations schedule is invalid")


@dataclass(frozen=True, slots=True)
class ApprovedReminderScheduleEvidence:
    """Pinned approval evidence required before projecting reminder work."""

    policy_digest: str
    config_digest: str

    def __post_init__(self) -> None:
        if any(
            _VALID_DIGEST.fullmatch(value) is None
            for value in (self.policy_digest, self.config_digest)
        ):
            raise CustomerScheduleError("reminder schedule evidence is invalid")


@dataclass(frozen=True, slots=True)
class WeeklyReminderReservationAuthority:
    """Every immutable provider-admission pin persisted with an ON reminder."""

    authority_digest: str
    customer_identity_digest: str
    candidate_digest: str
    canonical_registry_digest: str
    canonical_binding_digest: str
    sidecar_authority_digest: str
    sidecar_history_digest: str
    ledger_authority_digest: str
    owner_digest: str
    consent_digest: str
    feature_epoch: str
    route_digest: str
    canonical_sequence: int
    canonical_digest: str

    def __post_init__(self) -> None:
        digests = (
            self.authority_digest,
            self.customer_identity_digest,
            self.candidate_digest,
            self.canonical_registry_digest,
            self.canonical_binding_digest,
            self.sidecar_authority_digest,
            self.sidecar_history_digest,
            self.ledger_authority_digest,
            self.owner_digest,
            self.consent_digest,
            self.route_digest,
            self.canonical_digest,
        )
        if any(_VALID_DIGEST.fullmatch(value) is None for value in digests):
            raise CustomerScheduleError("weekly reminder authority is invalid")
        if self.canonical_sequence < 0 or not self.feature_epoch:
            raise CustomerScheduleError("weekly reminder authority pin is invalid")


@dataclass(frozen=True, slots=True)
class ScheduledDeliveryReceipt(Mapping[str, ReceiptValue]):
    """Bounded view of one immutable scheduled-delivery reservation."""

    reservation_id: str
    schedule_key: str
    customer_key: str
    kind: TaskKind
    kst_day: date
    state: str
    body_digest: str
    template_digest: str
    destination_digest: str
    registry_digest: str
    config_digest: str
    weekly_authority_digest: str | None = None
    weekly_customer_identity_digest: str | None = None
    weekly_candidate_digest: str | None = None
    weekly_canonical_registry_digest: str | None = None
    weekly_canonical_binding_digest: str | None = None
    weekly_sidecar_authority_digest: str | None = None
    weekly_sidecar_history_digest: str | None = None
    weekly_ledger_authority_digest: str | None = None
    weekly_owner_digest: str | None = None
    weekly_consent_digest: str | None = None
    weekly_feature_epoch: str | None = None
    weekly_route_digest: str | None = None
    weekly_canonical_sequence: int | None = None
    weekly_canonical_digest: str | None = None
    provider_receipt: str | None = None
    message_id: str | None = None
    reason: str | None = None
    legacy_claim_digest: str | None = None
    append_sequence: int = 0
    provider_authority: bool = field(default=False, compare=False, repr=False)

    @override
    def __getitem__(self, key: str) -> ReceiptValue:
        if key == "kst_day":
            return self.kst_day.isoformat()
        if key in {"kind", "task_kind"}:
            return self.kind
        if key == "destination":
            return self.destination_digest
        if key == "body":
            return self.body_digest
        try:
            return self.to_dict()[key]
        except KeyError:
            raise KeyError(key) from None

    @override
    def __iter__(self) -> Iterator[str]:
        return iter(self.to_dict())

    @override
    def __len__(self) -> int:
        return len(self.to_dict())

    def to_dict(self) -> dict[str, ReceiptValue]:
        return {
            "schema_version": 1,
            "reservation_id": self.reservation_id,
            "schedule_key": self.schedule_key,
            "customer_key": self.customer_key,
            "kind": self.kind,
            "task_kind": self.kind,
            "kst_day": self.kst_day.isoformat(),
            "state": self.state,
            "body_digest": self.body_digest,
            "template_digest": self.template_digest,
            "destination_digest": self.destination_digest,
            "registry_digest": self.registry_digest,
            "config_digest": self.config_digest,
            "weekly_authority_digest": self.weekly_authority_digest,
            "weekly_customer_identity_digest": self.weekly_customer_identity_digest,
            "weekly_candidate_digest": self.weekly_candidate_digest,
            "weekly_canonical_registry_digest": self.weekly_canonical_registry_digest,
            "weekly_canonical_binding_digest": self.weekly_canonical_binding_digest,
            "weekly_sidecar_authority_digest": self.weekly_sidecar_authority_digest,
            "weekly_sidecar_history_digest": self.weekly_sidecar_history_digest,
            "weekly_ledger_authority_digest": self.weekly_ledger_authority_digest,
            "weekly_owner_digest": self.weekly_owner_digest,
            "weekly_consent_digest": self.weekly_consent_digest,
            "weekly_feature_epoch": self.weekly_feature_epoch,
            "weekly_route_digest": self.weekly_route_digest,
            "weekly_canonical_sequence": self.weekly_canonical_sequence,
            "weekly_canonical_digest": self.weekly_canonical_digest,
            "provider_receipt": self.provider_receipt,
            "message_id": self.message_id,
            "reason": self.reason,
            "legacy_claim_digest": self.legacy_claim_digest,
            "append_sequence": self.append_sequence,
        }

    def __bool__(self) -> bool:
        return self.state not in _TERMINAL_STATES or self.state == "sent_audited"
