"""Typed source selection for coordinator-hosted weekly owner drafts."""

from __future__ import annotations

import hashlib
from dataclasses import dataclass
from typing import Literal, Never, TypeAlias, assert_never, override

from checkin_cli.adaptive_nutrition import canonical_json
from checkin_cli.customer_reporting import CustomerWeeklyReviewSource
from checkin_cli.weekly_operations_grounding import GroundedWeeklyReviewSource

from .nutrition_weekly_owner_draft import grounded_weekly_source_is_reserved
from .nutrition_weekly_owner_storage import WeeklyOwnerStorageAuthority

WeeklyReviewSource: TypeAlias = CustomerWeeklyReviewSource | GroundedWeeklyReviewSource


@dataclass(frozen=True, slots=True)
class PreparedWeeklySource:
    source: WeeklyReviewSource
    text: str
    source_digest: str


@dataclass(frozen=True, slots=True)
class WeeklySourceAuthority:
    customer_key: str
    owner_key: tuple[str, str, str]
    storage: WeeklyOwnerStorageAuthority


@dataclass(frozen=True, slots=True)
class WeeklySourceRejected(Exception):
    error: Literal[
        "weekly_review_customer_mismatch",
        "weekly_review_source_invalid",
    ]

    @override
    def __str__(self) -> str:
        return self.error



@dataclass(frozen=True, slots=True)
class WeeklySourceVariantError(RuntimeError):
    @override
    def __str__(self) -> str:
        return "weekly review source variant is unreachable"


def _source_subject(source: WeeklyReviewSource) -> WeeklyReviewSource | None:
    return source


def _unreachable_source(_source: None) -> Never:
    raise WeeklySourceVariantError()

def prepare_weekly_source(
    source: WeeklyReviewSource,
    authority: WeeklySourceAuthority,
) -> PreparedWeeklySource:
    """Bind one finite weekly source to its customer and owner authority."""
    match _source_subject(source):
        case CustomerWeeklyReviewSource() as customer_source:
            if customer_source.customer_key != authority.customer_key:
                raise WeeklySourceRejected("weekly_review_customer_mismatch")
            text = customer_source.render_customer_body()
            projection = {
                "customer_key": customer_source.customer_key,
                "period_start": customer_source.period_start.isoformat(),
                "period_end": customer_source.period_end.isoformat(),
                "body": text,
            }
        case GroundedWeeklyReviewSource() as grounded:
            if not grounded.verify() or not grounded_weekly_source_is_reserved(
                authority.storage,
                grounded,
                authority.customer_key,
                authority.owner_key,
            ):
                raise WeeklySourceRejected("weekly_review_source_invalid")
            text = grounded.render_customer_body()
            projection = {"grounding_digest": grounded.facts.grounding_digest}
        case unreachable:
            assert_never(_unreachable_source(unreachable))
    encoded = canonical_json(projection).encode("utf-8")
    return PreparedWeeklySource(
        source,
        text,
        hashlib.sha256(encoded).hexdigest(),
    )


def grounded_source(
    prepared: PreparedWeeklySource,
) -> GroundedWeeklyReviewSource | None:
    """Narrow a prepared source for the grounded generation path."""
    match _source_subject(prepared.source):
        case CustomerWeeklyReviewSource():
            return None
        case GroundedWeeklyReviewSource() as source:
            return source
        case unreachable:
            assert_never(_unreachable_source(unreachable))
