"""
Pydantic schemas for Legal Documents, Consent, and Compliance.

These schemas validate JSONFields in Django models and provide typed accessors.
All field values are derived from field_options.yaml (SST).

Usage:
    from lightwave.schema.pydantic.models.legal import (
        LegalDocumentSchema,
        UserConsentSchema,
        CookieConsentSchema,
        DataSubjectRequestSchema,
    )
"""

from __future__ import annotations

from typing import Any

from pydantic import Field

from lightwave.schema.pydantic.core.base import JSONFieldSchema

# =============================================================================
# LEGAL DOCUMENT SCHEMAS
# =============================================================================


class LegalSectionSchema(JSONFieldSchema):
    """
    Schema for a section within a legal document.

    Example:
        {
            "id": "introduction",
            "title": "Introduction",
            "content": "Welcome to LightWave Media...",
            "order": 1,
            "subsections": []
        }
    """

    id: str = Field(..., description="Section identifier (e.g., 'introduction')")
    title: str = Field(..., description="Section title for display")
    content: str = Field("", description="Section content (markdown supported)")
    order: int = Field(0, ge=0, description="Display order within document")
    subsections: list["LegalSectionSchema"] = Field(default_factory=list, description="Nested subsections")
    requires_legal_review: bool = Field(False, description="Whether section needs legal review")
    jurisdiction_specific: bool = Field(False, description="Whether content varies by jurisdiction")
    last_reviewed_at: str | None = Field(None, description="ISO 8601 date of last legal review")
    reviewed_by: str | None = Field(None, description="Who reviewed this section")


class LegalDocumentSchema(JSONFieldSchema):
    """
    Schema for LegalDocument.content JSONField.

    Represents the full content and metadata of a legal document.

    Example:
        {
            "document_type": "privacy_policy",
            "version": "2.1.0",
            "effective_date": "2026-01-22",
            "sections": [...],
            "metadata": {...}
        }
    """

    document_type: str = Field(
        ...,
        description="Type from legal_document_types (terms_of_service, privacy_policy, etc.)",
    )
    version: str = Field(..., description="Semantic version (e.g., '2.1.0')")
    effective_date: str = Field(..., description="ISO 8601 date when document takes effect")
    expiration_date: str | None = Field(None, description="ISO 8601 date when document expires (if applicable)")
    title: str = Field(..., description="Document title for display")
    summary: str = Field("", description="Brief summary of the document")
    sections: list[LegalSectionSchema] = Field(default_factory=list, description="Document sections in order")
    jurisdiction: str = Field("us_california", description="Primary jurisdiction (from legal.yaml jurisdictions)")
    compliance_frameworks: list[str] = Field(
        default_factory=list,
        description="Applicable frameworks (gdpr, ccpa, etc.)",
    )
    language: str = Field("en", description="ISO 639-1 language code")
    translations: dict[str, str] = Field(
        default_factory=dict,
        description="Map of language code to translated document ID",
    )
    metadata: dict[str, Any] = Field(
        default_factory=dict,
        description="Additional metadata (author, review dates, etc.)",
    )


class LegalDocumentVersionSchema(JSONFieldSchema):
    """
    Schema for tracking legal document version history.

    Example:
        {
            "version": "2.1.0",
            "previous_version": "2.0.0",
            "changes_summary": "Updated data retention section",
            "change_type": "material",
            "published_at": "2026-01-22T00:00:00Z"
        }
    """

    version: str = Field(..., description="This version number")
    previous_version: str | None = Field(None, description="Previous version number")
    changes_summary: str = Field(..., description="Summary of changes from previous version")
    change_type: str = Field(
        "minor",
        description="Type of change: 'minor', 'material', 'major'",
    )
    published_at: str = Field(..., description="ISO 8601 datetime when published")
    published_by: str | None = Field(None, description="User ID who published")
    notification_sent: bool = Field(False, description="Whether users were notified of changes")
    re_acceptance_required: bool = Field(False, description="Whether users must re-accept")


# =============================================================================
# CONSENT SCHEMAS
# =============================================================================


class UserConsentSchema(JSONFieldSchema):
    """
    Schema for UserConsent.consent_data JSONField.

    Records the details of a user's consent.

    Example:
        {
            "consent_type": "terms_acceptance",
            "document_type": "terms_of_service",
            "document_version": "2.1.0",
            "consented_at": "2026-01-22T15:30:00Z",
            "ip_address": "192.168.1.1",
            "user_agent": "Mozilla/5.0...",
            "collection_point": "signup"
        }
    """

    consent_type: str = Field(
        ...,
        description="Type from consent_types (terms_acceptance, marketing_emails, etc.)",
    )
    document_type: str | None = Field(None, description="Associated document type (if applicable)")
    document_version: str | None = Field(None, description="Version of document consented to")
    consented_at: str = Field(..., description="ISO 8601 datetime of consent")
    ip_address: str | None = Field(None, description="IP address at time of consent")
    user_agent: str | None = Field(None, description="Browser user agent")
    collection_point: str = Field(
        "unknown",
        description="Where consent was collected (signup, checkout, settings, etc.)",
    )
    explicit: bool = Field(True, description="Whether consent was explicit (checked box vs. implied)")
    double_opt_in: bool = Field(False, description="Whether double opt-in was completed")
    double_opt_in_at: str | None = Field(None, description="ISO 8601 datetime of double opt-in confirmation")


class ConsentRevocationSchema(JSONFieldSchema):
    """
    Schema for recording consent revocation.

    Example:
        {
            "revoked_at": "2026-01-22T16:00:00Z",
            "revocation_method": "account_settings",
            "reason": "No longer interested"
        }
    """

    revoked_at: str = Field(..., description="ISO 8601 datetime of revocation")
    revocation_method: str = Field(
        "unknown",
        description="How revoked (unsubscribe_link, account_settings, support_request, dsr)",
    )
    reason: str | None = Field(None, description="User-provided reason (optional)")
    ip_address: str | None = Field(None, description="IP address at time of revocation")


class CookieConsentSchema(JSONFieldSchema):
    """
    Schema for storing cookie consent preferences.

    Example:
        {
            "strictly_necessary": true,
            "performance": false,
            "functional": true,
            "targeting": false,
            "consented_at": "2026-01-22T15:30:00Z",
            "gpc_detected": false
        }
    """

    strictly_necessary: bool = Field(True, description="Always true (required)")
    performance: bool = Field(False, description="Analytics cookies consent")
    functional: bool = Field(True, description="Functional cookies consent")
    targeting: bool = Field(False, description="Advertising cookies consent")
    consented_at: str = Field(..., description="ISO 8601 datetime of consent")
    updated_at: str | None = Field(None, description="ISO 8601 datetime of last update")
    ip_address: str | None = Field(None, description="IP address at consent")
    gpc_detected: bool = Field(False, description="Whether Global Privacy Control signal was detected")
    do_not_sell: bool = Field(False, description="CCPA Do Not Sell opt-out status")


# =============================================================================
# DATA SUBJECT REQUEST SCHEMAS
# =============================================================================


class DataSubjectRequestSchema(JSONFieldSchema):
    """
    Schema for DataSubjectRequest.request_data JSONField.

    Records GDPR/CCPA data subject request details.

    Example:
        {
            "request_type": "access",
            "requester_email": "user@example.com",
            "verified": true,
            "verification_method": "email_link",
            "scope": ["all"],
            "submitted_at": "2026-01-22T15:30:00Z"
        }
    """

    request_type: str = Field(
        ...,
        description="Type from data_subject_request_types (access, erasure, etc.)",
    )
    requester_email: str = Field(..., description="Email of person making request")
    requester_name: str | None = Field(None, description="Name of requester")
    verified: bool = Field(False, description="Whether identity has been verified")
    verification_method: str | None = Field(
        None, description="How identity was verified (email_link, id_document, etc.)"
    )
    verified_at: str | None = Field(None, description="ISO 8601 datetime of verification")
    scope: list[str] = Field(
        default_factory=lambda: ["all"],
        description="Scope of request (all, specific categories, etc.)",
    )
    specific_data: list[str] = Field(
        default_factory=list,
        description="Specific data items requested (if not 'all')",
    )
    submitted_at: str = Field(..., description="ISO 8601 datetime of submission")
    deadline: str | None = Field(None, description="ISO 8601 date by which request must be fulfilled")
    notes: str = Field("", description="Internal notes about the request")


class DataSubjectRequestResponseSchema(JSONFieldSchema):
    """
    Schema for recording response to a data subject request.

    Example:
        {
            "status": "completed",
            "completed_at": "2026-01-25T10:00:00Z",
            "response_method": "secure_download",
            "data_provided": true,
            "download_url": "https://..."
        }
    """

    status: str = Field(
        ...,
        description="Status from data_subject_request_statuses",
    )
    completed_at: str | None = Field(None, description="ISO 8601 datetime when completed")
    response_method: str | None = Field(None, description="How response was delivered (email, secure_download, mail)")
    data_provided: bool = Field(False, description="Whether data was provided")
    download_url: str | None = Field(None, description="Secure download URL (if applicable)")
    download_expires_at: str | None = Field(None, description="When download link expires")
    denial_reason: str | None = Field(None, description="Reason for denial (if denied)")
    denial_code: str | None = Field(None, description="Legal basis for denial (e.g., 'legal_obligation')")
    appeal_available: bool = Field(True, description="Whether appeal is available")
    appeal_deadline: str | None = Field(None, description="Deadline for appeal (if applicable)")
    processed_by: str | None = Field(None, description="User ID who processed")


# =============================================================================
# COMPLIANCE SCHEMAS
# =============================================================================


class ComplianceAuditSchema(JSONFieldSchema):
    """
    Schema for recording compliance audit results.

    Example:
        {
            "framework": "gdpr",
            "audit_date": "2026-01-22",
            "auditor": "Internal Compliance",
            "findings": [...],
            "overall_status": "compliant"
        }
    """

    framework: str = Field(..., description="Framework audited (gdpr, ccpa, etc.)")
    audit_date: str = Field(..., description="ISO 8601 date of audit")
    auditor: str = Field(..., description="Who performed the audit")
    audit_type: str = Field("internal", description="Type: internal, external, self-assessment")
    scope: list[str] = Field(default_factory=list, description="Areas covered by audit")
    findings: list[dict[str, Any]] = Field(
        default_factory=list,
        description="List of findings with severity and recommendations",
    )
    overall_status: str = Field(
        "pending",
        description="Overall status: compliant, non_compliant, partially_compliant, pending",
    )
    remediation_plan: str | None = Field(None, description="Plan to address non-compliance")
    next_audit_date: str | None = Field(None, description="Scheduled next audit date")


class DataBreachRecordSchema(JSONFieldSchema):
    """
    Schema for recording data breach incidents (GDPR Art. 33/34).

    Example:
        {
            "incident_date": "2026-01-22T10:00:00Z",
            "discovered_date": "2026-01-22T12:00:00Z",
            "breach_type": "unauthorized_access",
            "data_categories_affected": ["identifiers", "financial"],
            "estimated_affected_count": 1000
        }
    """

    incident_id: str = Field(..., description="Unique incident identifier")
    incident_date: str = Field(..., description="ISO 8601 datetime of incident")
    discovered_date: str = Field(..., description="ISO 8601 datetime of discovery")
    breach_type: str = Field(
        ...,
        description="Type: unauthorized_access, data_loss, disclosure, etc.",
    )
    description: str = Field(..., description="Description of the breach")
    data_categories_affected: list[str] = Field(
        default_factory=list,
        description="Categories of data affected",
    )
    estimated_affected_count: int | None = Field(None, ge=0, description="Estimated number of affected individuals")
    risk_level: str = Field("medium", description="Risk level: low, medium, high, critical")
    authority_notified: bool = Field(False, description="Whether supervisory authority was notified")
    authority_notification_date: str | None = Field(None, description="ISO 8601 datetime of authority notification")
    individuals_notified: bool = Field(False, description="Whether affected individuals were notified")
    individual_notification_date: str | None = Field(None, description="ISO 8601 datetime of individual notification")
    remediation_actions: list[str] = Field(default_factory=list, description="Actions taken to remediate")
    root_cause: str | None = Field(None, description="Root cause analysis")
    lessons_learned: str | None = Field(None, description="Lessons learned")


# =============================================================================
# AI DISCLOSURE SCHEMA
# =============================================================================


class AIUsageDisclosureSchema(JSONFieldSchema):
    """
    Schema for AI usage disclosure in services.

    Example:
        {
            "feature_name": "Email Classification",
            "description": "AI categorizes emails by priority",
            "data_used": ["email_subject", "email_body"],
            "human_oversight": true,
            "automated_decision": false
        }
    """

    feature_name: str = Field(..., description="Name of the AI-powered feature")
    description: str = Field(..., description="What the AI does")
    data_used: list[str] = Field(default_factory=list, description="Types of data used by AI")
    human_oversight: bool = Field(True, description="Whether human reviews AI output")
    automated_decision: bool = Field(
        False,
        description="Whether AI makes automated decisions affecting users (GDPR Art. 22)",
    )
    opt_out_available: bool = Field(False, description="Whether users can opt out of this AI feature")
    model_provider: str | None = Field(None, description="AI model provider (e.g., 'Anthropic', 'OpenAI')")
    data_retention: str | None = Field(None, description="How long AI-processed data is retained")
