"""
ISMS Audit Execution (Findings, CAPA, Reviews, Internal Audit, Readiness) Pydantic schemas — extracted from compliance/api/schemas.py.

Phase 1 Step 3: the monolithic ``compliance.api.schemas`` module is being
split per domain under ``compliance.schemas``. This module is re-exported
from ``compliance.api.schemas`` for backwards compatibility.
"""

from datetime import datetime, date
from typing import Optional, List, Any, Dict

from pydantic import BaseModel, ConfigDict, Field

from compliance.schemas.common import (
    PaginationMeta, RegulationType, ControlType, ControlDomain,
    ControlStatus, RiskLevel, EvidenceStatus,
)


class AuditFindingBase(BaseModel):
    """Base schema for Audit Finding."""
    finding_type: str  # "major", "minor", "ofi", "positive"
    iso_chapter: Optional[str] = None
    annex_a_control: Optional[str] = None
    title: str
    description: str
    objective_evidence: str
    impact_description: Optional[str] = None
    affected_processes: Optional[List[str]] = None
    affected_assets: Optional[List[str]] = None
    owner: Optional[str] = None
    due_date: Optional[date] = None


class AuditFindingCreate(AuditFindingBase):
    """Schema for creating Audit Finding."""
    audit_session_id: Optional[str] = None
    internal_audit_id: Optional[str] = None
    auditor: str


class AuditFindingUpdate(BaseModel):
    """Schema for updating Audit Finding."""
    title: Optional[str] = None
    description: Optional[str] = None
    root_cause: Optional[str] = None
    root_cause_method: Optional[str] = None
    owner: Optional[str] = None
    due_date: Optional[date] = None
    status: Optional[str] = None


class AuditFindingResponse(AuditFindingBase):
    """Response schema for Audit Finding."""
    id: str
    finding_id: str
    audit_session_id: Optional[str] = None
    internal_audit_id: Optional[str] = None
    root_cause: Optional[str] = None
    root_cause_method: Optional[str] = None
    status: str
    auditor: Optional[str] = None
    identified_date: date
    closed_date: Optional[date] = None
    verification_method: Optional[str] = None
    verified_by: Optional[str] = None
    verified_at: Optional[datetime] = None
    closure_notes: Optional[str] = None
    closed_by: Optional[str] = None
    is_blocking: bool
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class AuditFindingListResponse(BaseModel):
    """List response for Audit Findings."""
    findings: List[AuditFindingResponse]
    total: int
    major_count: int
    minor_count: int
    ofi_count: int
    open_count: int


class AuditFindingCloseRequest(BaseModel):
    """Request to close an Audit Finding."""
    closure_notes: str
    closed_by: str
    verification_method: str
    verification_evidence: str


# --- Corrective Actions (CAPA) ---

class CorrectiveActionBase(BaseModel):
    """Base schema for Corrective Action."""
    capa_type: str  # "corrective", "preventive", "both"
    title: str
    description: str
    expected_outcome: Optional[str] = None
    assigned_to: str
    planned_completion: date
    effectiveness_criteria: Optional[str] = None
    estimated_effort_hours: Optional[int] = None
    resources_required: Optional[str] = None


class CorrectiveActionCreate(CorrectiveActionBase):
    """Schema for creating Corrective Action."""
    finding_id: str
    planned_start: Optional[date] = None


class CorrectiveActionUpdate(BaseModel):
    """Schema for updating Corrective Action."""
    title: Optional[str] = None
    description: Optional[str] = None
    assigned_to: Optional[str] = None
    planned_completion: Optional[date] = None
    status: Optional[str] = None
    progress_percentage: Optional[int] = None
    implementation_evidence: Optional[str] = None


class CorrectiveActionResponse(CorrectiveActionBase):
    """Response schema for Corrective Action."""
    id: str
    capa_id: str
    finding_id: str
    planned_start: Optional[date] = None
    actual_completion: Optional[date] = None
    status: str
    progress_percentage: int
    approved_by: Optional[str] = None
    actual_effort_hours: Optional[int] = None
    implementation_evidence: Optional[str] = None
    evidence_ids: Optional[List[str]] = None
    effectiveness_verified: bool
    effectiveness_verification_date: Optional[date] = None
    effectiveness_notes: Optional[str] = None
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class CorrectiveActionListResponse(BaseModel):
    """List response for Corrective Actions."""
    actions: List[CorrectiveActionResponse]
    total: int


class CAPAVerifyRequest(BaseModel):
    """Request to verify CAPA effectiveness."""
    verified_by: str
    effectiveness_notes: str
    is_effective: bool


# --- Management Review (ISO 27001 9.3) ---

class ReviewAttendee(BaseModel):
    """Single attendee in management review."""
    name: str
    role: str


class ReviewActionItem(BaseModel):
    """Single action item from management review."""
    action: str
    owner: str
    due_date: date


class ManagementReviewBase(BaseModel):
    """Base schema for Management Review."""
    title: str
    review_date: date
    review_period_start: Optional[date] = None
    review_period_end: Optional[date] = None
    chairperson: str
    attendees: Optional[List[ReviewAttendee]] = None


class ManagementReviewCreate(ManagementReviewBase):
    """Schema for creating Management Review."""
    pass


class ManagementReviewUpdate(BaseModel):
    """Schema for updating Management Review."""
    # Inputs (9.3)
    input_previous_actions: Optional[str] = None
    input_isms_changes: Optional[str] = None
    input_security_performance: Optional[str] = None
    input_interested_party_feedback: Optional[str] = None
    input_risk_assessment_results: Optional[str] = None
    input_improvement_opportunities: Optional[str] = None
    input_policy_effectiveness: Optional[str] = None
    input_objective_achievement: Optional[str] = None
    input_resource_adequacy: Optional[str] = None
    # Outputs (9.3)
    output_improvement_decisions: Optional[str] = None
    output_isms_changes: Optional[str] = None
    output_resource_needs: Optional[str] = None
    # Action items
    action_items: Optional[List[ReviewActionItem]] = None
    # Assessment
    isms_effectiveness_rating: Optional[str] = None
    key_decisions: Optional[str] = None
    status: Optional[str] = None


class ManagementReviewResponse(ManagementReviewBase):
    """Response schema for Management Review."""
    id: str
    review_id: str
    input_previous_actions: Optional[str] = None
    input_isms_changes: Optional[str] = None
    input_security_performance: Optional[str] = None
    input_interested_party_feedback: Optional[str] = None
    input_risk_assessment_results: Optional[str] = None
    input_improvement_opportunities: Optional[str] = None
    input_policy_effectiveness: Optional[str] = None
    input_objective_achievement: Optional[str] = None
    input_resource_adequacy: Optional[str] = None
    output_improvement_decisions: Optional[str] = None
    output_isms_changes: Optional[str] = None
    output_resource_needs: Optional[str] = None
    action_items: Optional[List[ReviewActionItem]] = None
    isms_effectiveness_rating: Optional[str] = None
    key_decisions: Optional[str] = None
    status: str
    approved_by: Optional[str] = None
    approved_at: Optional[datetime] = None
    minutes_document_path: Optional[str] = None
    next_review_date: Optional[date] = None
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class ManagementReviewListResponse(BaseModel):
    """List response for Management Reviews."""
    reviews: List[ManagementReviewResponse]
    total: int


class ManagementReviewApproveRequest(BaseModel):
    """Request to approve Management Review."""
    approved_by: str
    next_review_date: date
    minutes_document_path: Optional[str] = None


# --- Internal Audit (ISO 27001 9.2) ---

class InternalAuditBase(BaseModel):
    """Base schema for Internal Audit."""
    title: str
    audit_type: str  # "scheduled", "surveillance", "special"
    scope_description: str
    iso_chapters_covered: Optional[List[str]] = None
    annex_a_controls_covered: Optional[List[str]] = None
    processes_covered: Optional[List[str]] = None
    departments_covered: Optional[List[str]] = None
    criteria: Optional[str] = None
    planned_date: date
    lead_auditor: str
    audit_team: Optional[List[str]] = None


class InternalAuditCreate(InternalAuditBase):
    """Schema for creating Internal Audit."""
    pass


class InternalAuditUpdate(BaseModel):
    """Schema for updating Internal Audit."""
    title: Optional[str] = None
    scope_description: Optional[str] = None
    actual_start_date: Optional[date] = None
    actual_end_date: Optional[date] = None
    auditee_representatives: Optional[List[str]] = None
    status: Optional[str] = None
    audit_conclusion: Optional[str] = None
    overall_assessment: Optional[str] = None


class InternalAuditResponse(InternalAuditBase):
    """Response schema for Internal Audit."""
    id: str
    audit_id: str
    actual_start_date: Optional[date] = None
    actual_end_date: Optional[date] = None
    auditee_representatives: Optional[List[str]] = None
    status: str
    total_findings: int
    major_findings: int
    minor_findings: int
    ofi_count: int
    positive_observations: int
    audit_conclusion: Optional[str] = None
    overall_assessment: Optional[str] = None
    report_date: Optional[date] = None
    report_document_path: Optional[str] = None
    report_approved_by: Optional[str] = None
    report_approved_at: Optional[datetime] = None
    follow_up_audit_required: bool
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class InternalAuditListResponse(BaseModel):
    """List response for Internal Audits."""
    audits: List[InternalAuditResponse]
    total: int


class InternalAuditCompleteRequest(BaseModel):
    """Request to complete Internal Audit."""
    audit_conclusion: str
    overall_assessment: str  # "conforming", "minor_nc", "major_nc"
    follow_up_audit_required: bool


# --- ISMS Readiness Check ---

class PotentialFinding(BaseModel):
    """Potential finding from readiness check."""
    check: str
    status: str  # "pass", "fail", "warning"
    recommendation: str
    iso_reference: Optional[str] = None


class ISMSReadinessCheckResponse(BaseModel):
    """Response for ISMS Readiness Check."""
    id: str
    check_date: datetime
    triggered_by: Optional[str] = None
    overall_status: str  # "ready", "at_risk", "not_ready"
    certification_possible: bool
    # Chapter statuses
    chapter_4_status: Optional[str] = None
    chapter_5_status: Optional[str] = None
    chapter_6_status: Optional[str] = None
    chapter_7_status: Optional[str] = None
    chapter_8_status: Optional[str] = None
    chapter_9_status: Optional[str] = None
    chapter_10_status: Optional[str] = None
    # Findings
    potential_majors: List[PotentialFinding]
    potential_minors: List[PotentialFinding]
    improvement_opportunities: List[PotentialFinding]
    # Scores
    readiness_score: float
    documentation_score: Optional[float] = None
    implementation_score: Optional[float] = None
    evidence_score: Optional[float] = None
    # Priority actions
    priority_actions: List[str]

    model_config = ConfigDict(from_attributes=True)


class ISMSReadinessCheckRequest(BaseModel):
    """Request to run ISMS Readiness Check."""
    triggered_by: str = "manual"


# --- Audit Trail ---

class AuditTrailEntry(BaseModel):
    """Single audit trail entry."""
    id: str
    entity_type: str
    entity_id: str
    entity_name: Optional[str] = None
    action: str
    field_changed: Optional[str] = None
    old_value: Optional[str] = None
    new_value: Optional[str] = None
    change_summary: Optional[str] = None
    performed_by: str
    performed_at: datetime

    model_config = ConfigDict(from_attributes=True)


class AuditTrailResponse(BaseModel):
    """Response for Audit Trail query."""
    entries: List[AuditTrailEntry]
    total: int
    pagination: PaginationMeta


# --- ISO 27001 Chapter Status Overview ---

class ISO27001ChapterStatus(BaseModel):
    """Status of a single ISO 27001 chapter."""
    chapter: str
    title: str
    status: str  # "compliant", "partial", "non_compliant", "not_started"
    completion_percentage: float
    open_findings: int
    key_documents: List[str]
    last_reviewed: Optional[datetime] = None


class ISO27001OverviewResponse(BaseModel):
    """Complete ISO 27001 status overview."""
    overall_status: str  # "ready", "at_risk", "not_ready", "not_started"
    certification_readiness: float  # 0-100
    chapters: List[ISO27001ChapterStatus]
    scope_approved: bool
    soa_approved: bool
    last_management_review: Optional[datetime] = None
    last_internal_audit: Optional[datetime] = None
    open_major_findings: int
    open_minor_findings: int
    policies_count: int
    policies_approved: int
    objectives_count: int
    objectives_achieved: int

