"""Resource gating for controlled V2 pilot production."""

from __future__ import annotations

from dataclasses import dataclass
from enum import StrEnum

from autoshorts.claims.fact_gate import validate_claims_for_candidate
from autoshorts.compliance.ai_disclosure import AIDisclosureReview, validate_ai_disclosure_review
from autoshorts.strategy.spine_v2 import AIDisclosureDecision, ReviewPackageV2, VideoCandidateV2


class ResourceCostTier(StrEnum):
    TEXT_REASONING = "text_reasoning"
    DETERMINISTIC_PREVIEW = "deterministic_preview"
    AI_STYLEFRAME = "ai_styleframe"
    WAN_FINAL_RENDER = "wan_final_render"
    PUBLISHING = "publishing"


class RenderApprovalState(StrEnum):
    DRAFT = "draft"
    READY_FOR_REVIEW = "ready_for_review"
    APPROVED_FOR_ASSET_PLANNING = "approved_for_asset_planning"
    APPROVED_FOR_STYLEFRAME = "approved_for_styleframe"
    APPROVED_FOR_PREVIEW_RENDER = "approved_for_preview_render"
    APPROVED_FOR_FINAL_RENDER = "approved_for_final_render"
    RENDERED_FOR_REVIEW = "rendered_for_review"
    APPROVED_FOR_MANUAL_POSTING = "approved_for_manual_posting"
    BLOCKED = "blocked"


@dataclass(frozen=True)
class MediaGenerationGate:
    candidate_id: str
    version: str
    script_hash: str
    requested_resource_tier: ResourceCostTier
    approval_state: RenderApprovalState
    allowed: bool
    reason: str

    def to_dict(self) -> dict[str, object]:
        return {
            "candidate_id": self.candidate_id,
            "version": self.version,
            "script_hash": self.script_hash,
            "requested_resource_tier": self.requested_resource_tier.value,
            "approval_state": self.approval_state.value,
            "allowed": self.allowed,
            "reason": self.reason,
        }


def _blocked(candidate: VideoCandidateV2, package: ReviewPackageV2, tier: ResourceCostTier, state: RenderApprovalState, reason: str) -> MediaGenerationGate:
    return MediaGenerationGate(candidate.candidate_id, candidate.version, package.script_hash, tier, state, False, reason)


def _allowed(candidate: VideoCandidateV2, package: ReviewPackageV2, tier: ResourceCostTier, state: RenderApprovalState, reason: str) -> MediaGenerationGate:
    return MediaGenerationGate(candidate.candidate_id, candidate.version, package.script_hash, tier, state, True, reason)


def evaluate_media_generation_gate(
    *,
    candidate: VideoCandidateV2,
    review_package: ReviewPackageV2,
    requested_resource_tier: ResourceCostTier,
    approval_state: RenderApprovalState,
    approved_candidate_id: str,
    approved_version: str,
    approved_script_hash: str,
    ai_disclosure_review: AIDisclosureReview | None = None,
) -> MediaGenerationGate:
    if requested_resource_tier == ResourceCostTier.PUBLISHING:
        return _blocked(candidate, review_package, requested_resource_tier, approval_state, "Publishing is disabled in this workflow.")

    if approved_candidate_id != candidate.candidate_id:
        return _blocked(candidate, review_package, requested_resource_tier, approval_state, "candidate_id mismatch")
    if approved_version != candidate.version:
        return _blocked(candidate, review_package, requested_resource_tier, approval_state, "version mismatch")
    if approved_script_hash != review_package.script_hash:
        return _blocked(candidate, review_package, requested_resource_tier, approval_state, "script_hash mismatch")

    if candidate.ai_disclosure_required == AIDisclosureDecision.UNCLEAR:
        return _blocked(candidate, review_package, requested_resource_tier, approval_state, "AI disclosure is unclear")
    if ai_disclosure_review is not None:
        disclosure_result = validate_ai_disclosure_review(ai_disclosure_review)
        if not disclosure_result.is_valid:
            return _blocked(candidate, review_package, requested_resource_tier, approval_state, "AI disclosure blocks rendering: " + "; ".join(disclosure_result.errors))

    claim_result = validate_claims_for_candidate(candidate)
    if not claim_result.is_valid:
        return _blocked(candidate, review_package, requested_resource_tier, approval_state, "Claim Gate blocks rendering: " + "; ".join(claim_result.errors))

    if requested_resource_tier == ResourceCostTier.TEXT_REASONING:
        return _allowed(candidate, review_package, requested_resource_tier, approval_state, "TEXT_REASONING is always allowed after identity/hash checks.")
    if requested_resource_tier == ResourceCostTier.DETERMINISTIC_PREVIEW:
        if approval_state in {
            RenderApprovalState.READY_FOR_REVIEW,
            RenderApprovalState.APPROVED_FOR_ASSET_PLANNING,
            RenderApprovalState.APPROVED_FOR_STYLEFRAME,
            RenderApprovalState.APPROVED_FOR_PREVIEW_RENDER,
            RenderApprovalState.APPROVED_FOR_FINAL_RENDER,
            RenderApprovalState.RENDERED_FOR_REVIEW,
        }:
            return _allowed(candidate, review_package, requested_resource_tier, approval_state, "Deterministic preview allowed from READY_FOR_REVIEW onward.")
        return _blocked(candidate, review_package, requested_resource_tier, approval_state, "DETERMINISTIC_PREVIEW requires READY_FOR_REVIEW or later")
    if requested_resource_tier == ResourceCostTier.AI_STYLEFRAME:
        if approval_state in {RenderApprovalState.APPROVED_FOR_STYLEFRAME, RenderApprovalState.APPROVED_FOR_FINAL_RENDER}:
            return _allowed(candidate, review_package, requested_resource_tier, approval_state, "AI styleframe allowed by explicit styleframe approval.")
        return _blocked(candidate, review_package, requested_resource_tier, approval_state, "AI_STYLEFRAME requires APPROVED_FOR_STYLEFRAME")
    if requested_resource_tier == ResourceCostTier.WAN_FINAL_RENDER:
        if approval_state == RenderApprovalState.APPROVED_FOR_FINAL_RENDER:
            return _allowed(candidate, review_package, requested_resource_tier, approval_state, "WAN final render allowed by explicit final-render approval.")
        return _blocked(candidate, review_package, requested_resource_tier, approval_state, "WAN_FINAL_RENDER requires APPROVED_FOR_FINAL_RENDER")
    return _blocked(candidate, review_package, requested_resource_tier, approval_state, "Unknown resource tier")
