"""Sealed Todo7 authority receipt for one weekly owner-draft summary."""

from __future__ import annotations

import hashlib
import json
from dataclasses import dataclass
from typing import Final

from .weekly_operations import WeeklyOperationsConflict, WeeklyOperationsInputError
from .weekly_operations_customer_authority import CanonicalCheckinCustomerAuthority
from .weekly_operations_store import WeeklyOperationsStore
from .weekly_operations_summary import build_weekly_operations_summary
from .weekly_operations_summary_types import WeeklyOperationsSummary

_SCHEMA: Final = "nutricoach-bound-weekly-summary-owner-draft-v1"


class _BindingSeal:
    __slots__: Final = ()


_SEAL: Final = _BindingSeal()


@dataclass(frozen=True, slots=True, init=False)
class BoundWeeklySummaryForOwnerDraft:
    """Exact summary plus live canonical and sidecar authority capabilities."""

    summary: WeeklyOperationsSummary
    summary_digest: str
    authority_digest: str
    customer_identity_digest: str
    _canonical: CanonicalCheckinCustomerAuthority
    _sidecar: WeeklyOperationsStore
    _seal: _BindingSeal

    def __init__(
        self,
        summary: WeeklyOperationsSummary,
        summary_digest: str,
        authority_digest: str,
        customer_identity_digest: str,
        canonical: CanonicalCheckinCustomerAuthority,
        sidecar: WeeklyOperationsStore,
        seal: _BindingSeal,
    ) -> None:
        object.__setattr__(self, "summary", summary)
        object.__setattr__(self, "summary_digest", summary_digest)
        object.__setattr__(self, "authority_digest", authority_digest)
        object.__setattr__(self, "customer_identity_digest", customer_identity_digest)
        object.__setattr__(self, "_canonical", canonical)
        object.__setattr__(self, "_sidecar", sidecar)
        object.__setattr__(self, "_seal", seal)

    def verify(self) -> bool:
        """Re-run Todo7 through the retained registered capabilities."""
        if self._seal is not _SEAL:
            return False
        try:
            rebuilt = build_weekly_operations_summary(
                self._canonical, self._sidecar, self.summary.starts_on,
            )
            expected = _binding_values(self._canonical, self._sidecar, rebuilt)
        except (OSError, WeeklyOperationsConflict, WeeklyOperationsInputError):
            return False
        return (
            rebuilt == self.summary
            and rebuilt.to_json() == self.summary.to_json()
            and expected == (
                self.summary_digest,
                self.authority_digest,
                self.customer_identity_digest,
            )
        )


def bind_weekly_summary_for_owner_draft(
    canonical: CanonicalCheckinCustomerAuthority,
    sidecar: WeeklyOperationsStore,
    expected: WeeklyOperationsSummary,
) -> BoundWeeklySummaryForOwnerDraft:
    """Issue a receipt only after an exact authority-backed Todo7 rebuild."""
    rebuilt = build_weekly_operations_summary(canonical, sidecar, expected.starts_on)
    if rebuilt != expected or rebuilt.to_json() != expected.to_json():
        raise WeeklyOperationsConflict("owner-draft summary disagrees with Todo7 authority")
    summary_digest, authority_digest, customer_digest = _binding_values(
        canonical, sidecar, rebuilt,
    )
    return BoundWeeklySummaryForOwnerDraft(
        rebuilt, summary_digest, authority_digest, customer_digest,
        canonical, sidecar, _SEAL,
    )


def _binding_values(
    canonical: CanonicalCheckinCustomerAuthority,
    sidecar: WeeklyOperationsStore,
    summary: WeeklyOperationsSummary,
) -> tuple[str, str, str]:
    canonical.verify()
    sidecar.authority.verify()
    customer_digest = str(canonical.customer_identity_digest)
    if customer_digest != str(sidecar.customer_identity_digest):
        raise WeeklyOperationsConflict("owner-draft customer authority disagrees")
    summary_digest = hashlib.sha256(summary.to_json().encode()).hexdigest()
    payload = (
        _SCHEMA, customer_digest, summary_digest, canonical.binding_digest,
        canonical.registry_authority_binding_digest, sidecar.authority_binding_digest,
    )
    encoded = json.dumps(payload, separators=(",", ":")).encode()
    return summary_digest, hashlib.sha256(encoded).hexdigest(), customer_digest
