from __future__ import annotations

from typing import Any

from pydantic import BaseModel, Field, model_validator

from app.models.schema_constants import (
    DOSSIER_REVIEW_ASSIGNMENT_STATUSES,
    DOSSIER_REVIEW_DEPARTMENT_CODES,
    DOSSIER_REVIEW_SESSION_STATUSES,
)

from .dossier_finding_models import DossierReviewFindingCreateRequest


class WorkflowReviewEmployeeActionRequest(BaseModel):
    """Single employee activity emitted during a proactive dossier review run."""

    employee_code: str
    agent_code: str | None = None
    role_title: str | None = None
    agent_role: str | None = None
    department_code: str | None = Field(
        default=None,
        description=f"One of: {', '.join(DOSSIER_REVIEW_DEPARTMENT_CODES)}",
    )
    action: str
    status: str = "Đang xử lý"
    summary: str | None = None
    priority: str = "Trung bình"
    role_group: str | None = None
    next_priority: str | None = None
    progress_percent: int = Field(default=0, ge=0, le=100)
    completed_count: int = Field(default=0, ge=0)
    missing_count: int = Field(default=0, ge=0)
    findings: list[str] = Field(default_factory=list)
    missing_items: list[str] = Field(default_factory=list)
    notes: list[str] = Field(default_factory=list)
    ai_request: str | None = None
    ai_result: list[str] = Field(default_factory=list)
    action_timestamp: str | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewAssignmentRequest(BaseModel):
    """Structured assignment request for one dossier review finding."""

    assigned_department_code: str = Field(
        ...,
        description=f"One of: {', '.join(DOSSIER_REVIEW_DEPARTMENT_CODES)}",
    )
    assigned_employee_code: str | None = None
    assigned_by_employee_code: str | None = None
    status: str = Field(
        default="pending",
        description=f"One of: {', '.join(DOSSIER_REVIEW_ASSIGNMENT_STATUSES)}",
    )
    priority: str = "medium"
    due_date: str | None = None
    assignment_note: str | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewSubmissionRequest(BaseModel):
    """Structured supplement submission emitted during workflow automation."""

    submission_type: str = "document_bundle"
    submitted_by_employee_code: str | None = None
    submission_note: str | None = None
    attachment_count: int = Field(default=0, ge=0)
    submitted_payload: dict[str, Any] = Field(default_factory=dict)
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewSnapshotRequest(BaseModel):
    """Snapshot payload captured as part of an automated review run."""

    snapshot_type: str = "initial_baseline"
    captured_by_employee_code: str | None = None
    captured_by_agent_code: str | None = None
    label: str | None = None
    summary: str | None = None
    dossier_state: dict[str, Any] = Field(default_factory=dict)
    missing_matrix: dict[str, Any] = Field(default_factory=dict)
    readiness_summary: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewVerificationRequest(BaseModel):
    """Structured verification request for a submitted supplement."""

    verification_result: str = "accepted"
    verification_note: str | None = None
    verified_by_employee_code: str | None = None
    resolution_note: str | None = None
    verification_snapshot: WorkflowReviewSnapshotRequest | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewCloseRequest(BaseModel):
    """Structured request to close a review session."""

    closure_note: str | None = None
    force_close_open_findings: bool = False
    metadata: dict[str, Any] = Field(default_factory=dict)


class WorkflowReviewFindingRequest(DossierReviewFindingCreateRequest):
    """Structured finding request used by the workflow persistence service."""

    assignment: WorkflowReviewAssignmentRequest | None = None
    employee_actions: list[WorkflowReviewEmployeeActionRequest] = Field(
        default_factory=list
    )


class WorkflowReviewStartRequest(BaseModel):
    """Request payload to persist a proactive dossier review workflow run."""

    project_code: str
    lead_agent_code: str
    lead_reviewer_employee_code: str | None = None
    initiated_by_employee_code: str | None = None
    dossier_scope: str = "project_dossier"
    trigger_source: str = "system_proactive_review"
    status: str = Field(
        default="in_review",
        description=f"One of: {', '.join(DOSSIER_REVIEW_SESSION_STATUSES)}",
    )
    review_reason: str | None = None
    review_summary: str | None = None
    assigned_departments: list[str] = Field(default_factory=list)
    baseline_snapshot: WorkflowReviewSnapshotRequest | None = None
    findings: list[WorkflowReviewFindingRequest] = Field(default_factory=list)
    review_actions: list[dict[str, Any]] = Field(default_factory=list)
    participating_employees: list[WorkflowReviewEmployeeActionRequest] = Field(
        default_factory=list
    )
    metadata: dict[str, Any] = Field(default_factory=dict)

    @model_validator(mode="after")
    def ensure_actor_defaults(self) -> WorkflowReviewStartRequest:
        """Fill workflow actor defaults from the lead reviewer when omitted."""
        if self.initiated_by_employee_code is None:
            self.initiated_by_employee_code = self.lead_reviewer_employee_code
        return self
