from __future__ import annotations

from typing import Any

from pydantic import BaseModel, Field

from .dossier_session_models import DossierReviewSessionRecord


class WorkflowReviewPolicyViolationItem(BaseModel):
    """Single policy violation or hard guardrail failure."""

    code: str
    message: str
    severity: str = "medium"
    field_name: str | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewEscalationTargetItem(BaseModel):
    """Single escalation target selected by policy evaluation."""

    agent_code: str
    reason: str | None = None
    priority: str = "medium"
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewPolicyCheckResult(BaseModel):
    """Policy evaluation result used for workflow/session/finding/assignment guardrails."""

    scope: str
    allowed: bool = True
    risk_level: str = "low"
    risk_score: int = 0
    requires_escalation: bool = False
    requires_manual_review: bool = False
    circuit_breaker_triggered: bool = False
    violations: list[WorkflowReviewPolicyViolationItem] = Field(default_factory=list)
    warnings: list[str] = Field(default_factory=list)
    escalation_targets: list[WorkflowReviewEscalationTargetItem] = Field(
        default_factory=list
    )
    applied_rules: list[str] = Field(default_factory=list)
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewTriggerSummary(BaseModel):
    """Compact trigger metadata used to explain why a workflow run was started."""

    trigger_source: str | None = None
    trigger_mode: str | None = None
    trigger_reason: str | None = None
    initiated_by_employee_code: str | None = None
    lead_reviewer_employee_code: str | None = None
    lead_agent_code: str | None = None
    project_code: str | None = None
    dossier_scope: str | None = None
    assigned_departments: list[str] = Field(default_factory=list)
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewPolicySummary(BaseModel):
    """Compact summary of workflow policy outcome for response payloads."""

    total_checks: int = 0
    allowed_checks: int = 0
    blocked_checks: int = 0
    escalation_count: int = 0
    manual_review_count: int = 0
    circuit_breaker_count: int = 0
    highest_risk_level: str = "low"
    scopes_requiring_attention: list[str] = Field(default_factory=list)
    warnings: list[str] = Field(default_factory=list)
    applied_rules: list[str] = Field(default_factory=list)
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowOperationalStateSnapshot(BaseModel):
    """Lightweight operational twin snapshot attached to a workflow run summary."""

    generated_at: str | None = None
    source: str | None = None
    used_fallback: bool = False
    total_projects: int = 0
    open_risks: int = 0
    blocked_items_count: int = 0
    backlog_items_count: int = 0
    active_review_sessions: int = 0
    available_sources: list[str] = Field(default_factory=list)
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewNextActionItem(BaseModel):
    """Machine-readable next action emitted after workflow automation.

    Metadata may optionally carry richer projection hints such as finding_code,
    project_code, assignment_id, review_id, post_close_source, replay_scope,
    or trigger context without changing the public schema contract.
    """

    scope: str
    target_type: str
    target_id: str | None = None
    department_code: str | None = None
    owner_employee_code: str | None = None
    title: str
    action_type: str
    priority: str = "medium"
    reason: str | None = None
    status: str = "pending"
    execution_channel: str | None = None
    trigger_at: str | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewFindingSummary(BaseModel):
    """Summary for one persisted finding and any generated assignment."""

    finding_id: str
    finding_code: str
    status: str
    responsible_department_code: str
    assignment_id: str | None = None
    assignment_status: str | None = None
    employee_action_count: int = 0


class WorkflowReviewEmployeeLogSummary(BaseModel):
    """Summary for one employee work log session touched by the workflow."""

    employee_code: str
    work_log_session_id: str
    status: str
    action_count: int
    project_code: str
    shift_date: str


class WorkflowReviewStepOutcome(BaseModel):
    """Machine-readable lifecycle outcome for one workflow step."""

    step: str
    executed: bool = False
    succeeded: bool = False
    requires_manual_intervention: bool = False
    blocked: bool = False
    target_type: str | None = None
    target_id: str | None = None
    target_code: str | None = None
    status: str | None = None
    reason: str | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewRunSummary(BaseModel):
    """Structured response summarizing the persisted proactive review workflow."""

    review: DossierReviewSessionRecord
    finding_summaries: list[WorkflowReviewFindingSummary] = Field(default_factory=list)
    employee_log_summaries: list[WorkflowReviewEmployeeLogSummary] = Field(
        default_factory=list
    )
    created_snapshot_ids: list[str] = Field(default_factory=list)
    next_actions: list[WorkflowReviewNextActionItem] = Field(default_factory=list)
    policy_checks: list[WorkflowReviewPolicyCheckResult] = Field(default_factory=list)
    lifecycle_outcomes: list[WorkflowReviewStepOutcome] = Field(default_factory=list)
    correlation_id: str | None = None
    run_id: str | None = None
    automation_status: str = "completed"
    requires_manual_intervention: bool = False
    resumable_from_step: str | None = None
    close_executed: bool = False
    assigned_findings_count: int = 0
    submitted_findings_count: int = 0
    verified_findings_count: int = 0
    escalated_findings_count: int = 0
    manual_follow_up_count: int = 0
    blocked_reasons: list[str] = Field(default_factory=list)
    review_action_count: int = 0
    operational_state_snapshot: (
        WorkflowOperationalStateSnapshot | dict[str, Any] | None
    ) = None
    policy_summary: WorkflowReviewPolicySummary | dict[str, Any] = Field(
        default_factory=WorkflowReviewPolicySummary
    )
    trigger_summary: WorkflowReviewTriggerSummary | dict[str, Any] = Field(
        default_factory=WorkflowReviewTriggerSummary
    )
    post_close_actions: list[WorkflowReviewNextActionItem] = Field(default_factory=list)
    message: str


WorkflowReviewRunSummary.model_rebuild()
WorkflowReviewStepOutcome.model_rebuild()
