"""Transition Reasoning v0 (RS-005) — domain objects.

The **Transition Planning Engine**: it answers „Was muss ich noch wissen, um vom
Ausgangszustand in den regulatorischen Zielzustand zu kommen?" — NOT „wie frage ich
das?". It therefore owns the **information gaps** (`TransitionQuestionRequest`), never
the rendered question text. Rendering (intent + subject -> sentence) is a separate,
swappable layer (RS-005.1 Question Generator) and is NOT part of this engine.

v0 consumes the Company Capability Profile (Phase 2A) as the „have" state and an
INJECTED list of `TargetRequirement` as the Execution-owned „required" side (no
required-capability data in product code — same discipline as 2A's EMPTY_MAPPING).

Welt-1-Grenze: a probable coverage (from a certification) is a hint, never „erfüllt";
it produces a confirmation request, not a verdict. Application/reasoning types, NOT
meta-model classes (freeze v1.0 untouched). Python 3.9 compatible (no `|` unions).
"""

from __future__ import annotations

from enum import Enum
from typing import List, Optional

from pydantic import BaseModel, Field


class TargetType(str, Enum):
    REGULATION = "regulation"
    CERTIFICATION = "certification"
    FRAMEWORK = "framework"


class CoverageStatus(str, Enum):
    ALREADY_COVERED = "already_covered"  # confirmed in the company profile
    PROBABLY_COVERED = "probably_covered"  # inferred (e.g. from a certification)
    NEEDS_CONFIRMATION = "needs_confirmation"  # only declared / weak signal
    MISSING = "missing"  # no signal
    NOT_APPLICABLE = "not_applicable"
    UNSUPPORTED = "unsupported"  # domain not yet in the corpus (future_corpus_needed)


class RequestPriority(str, Enum):
    HIGH = "high"
    MEDIUM = "medium"
    LOW = "low"


class InformationGain(str, Enum):
    HIGH = "high"
    MEDIUM = "medium"
    LOW = "low"


class TransitionGoal(BaseModel):
    target_id: str  # e.g. "CRA", "TISAX"
    target_type: TargetType = TargetType.REGULATION
    label: str = ""


class TransitionContext(BaseModel):
    company_id: str = ""
    known_certifications: List[str] = Field(default_factory=list)
    known_regulations: List[str] = Field(default_factory=list)
    target: TransitionGoal


# ── INJECTED (Execution-owned): what the target requires ───────────────────
class TargetRequirement(BaseModel):
    """One required capability for the target. In v0 injected; later resolved from
    `Obligation -> Control -> Required Capability` + `Control -> question_intent`."""

    capability_id: str  # MCAP-...
    question_intent: str = "verify_existence"  # passed through to the request, not rendered
    rationale: str = ""  # curated human text (e.g. why_asked / reviewable_claim) — surfaced as the request reason
    expected_evidence: List[str] = Field(default_factory=list)
    source_control_id: Optional[str] = None
    supports_obligations: List[str] = Field(default_factory=list)
    unsupported: bool = False  # domain not yet in the corpus


# ── the OWNED output: an information gap, NOT a question ───────────────────
class TransitionQuestionRequest(BaseModel):
    capability_id: str
    control_id: Optional[str] = None
    reason: str
    question_intent: str  # verify_existence / determine_duration / ... (rendered later)
    expected_evidence: List[str] = Field(default_factory=list)
    priority: RequestPriority
    information_gain: InformationGain


class CapabilityCoverage(BaseModel):
    capability_id: str
    status: CoverageStatus
    have_status: Optional[str] = None  # the 2A VerificationStatus that drove it


class TransitionSummary(BaseModel):
    headline: str = ""  # counts, NO percentage
    what_to_clarify: List[str] = Field(default_factory=list)  # capability_ids with a request
    already_covered: List[str] = Field(default_factory=list)
    probably_covered: List[str] = Field(default_factory=list)
    missing: List[str] = Field(default_factory=list)
    not_applicable: List[str] = Field(default_factory=list)
    unsupported: List[str] = Field(default_factory=list)


class TransitionAssessment(BaseModel):
    target_id: str
    coverage: List[CapabilityCoverage] = Field(default_factory=list)
    question_requests: List[TransitionQuestionRequest] = Field(default_factory=list)  # ranked
    summary: TransitionSummary
