"""
vWrite/vSpeak Output Models.

Pydantic models for structured output formatting derived from:
    lightwave://schemas/ai/output/structured_outputs

The vWrite/vSpeak system provides:
- Tone-aware output formatting (Jony Ive, DHH, Stripe, etc.)
- Platform-specific formatting (Slack, WhatsApp, CLI, API)
- Consistent voice across all agent outputs
- Audit trail for all generated content

Usage:
    from lightwave.schema.pydantic.contracts.outputs import (
        VWriteOutput,
        VSpeakOutput,
        ToneModel,
        OutputFormat,
        OutputMode,
    )

    # Create a vWrite output
    output = VWriteOutput(
        content="Here is your report...",
        tone="lightwave_authentic",
        format="markdown",
        agent_type="v_accountant",
    )

    # Create a vSpeak output
    response = VSpeakOutput(
        content="Invoice is $4,250, due Friday.",
        tone="lightwave_authentic",
        suggested_followups=["Send reminder?", "View details?"],
    )
"""

from __future__ import annotations

from datetime import datetime
from typing import Literal
from uuid import UUID, uuid4

from pydantic import Field

from lightwave.schema.pydantic.core.base import LightwaveBaseSchema, SSTSchema

# =============================================================================
# Enums / Literal Types (derived from SST)
# =============================================================================

# Output modes
OutputMode = Literal["v_write", "v_speak"]

# Tone models from structured_outputs.yaml
ToneModel = Literal[
    "lightwave_authentic",
    "apple_jony_ive",
    "basecamp_dhh",
    "stripe_atlas",
    "professional_formal",
    "friendly_casual",
]

# Output formats
OutputFormat = Literal[
    "plain_text",
    "markdown",
    "html",
    "slack_blocks",
    "slack_mrkdwn",
    "json",
]

# Platforms
Platform = Literal["cli", "slack", "whatsapp", "email", "api"]


# =============================================================================
# Tone Characteristics
# =============================================================================


class ToneCharacteristics(SSTSchema):
    """Numeric characteristics defining a tone model."""

    warmth: float = Field(
        ...,
        ge=0.0,
        le=1.0,
        description="Level of warmth/friendliness (0=cold, 1=very warm)",
    )
    formality: float = Field(
        ...,
        ge=0.0,
        le=1.0,
        description="Level of formality (0=casual, 1=very formal)",
    )
    directness: float = Field(
        ...,
        ge=0.0,
        le=1.0,
        description="Level of directness (0=indirect, 1=very direct)",
    )
    humor: float = Field(
        ...,
        ge=0.0,
        le=1.0,
        description="Level of humor allowed (0=none, 1=frequent)",
    )


# Tone model characteristics (from SST)
TONE_CHARACTERISTICS: dict[ToneModel, ToneCharacteristics] = {
    "lightwave_authentic": ToneCharacteristics(warmth=0.8, formality=0.5, directness=0.7, humor=0.3),
    "apple_jony_ive": ToneCharacteristics(warmth=0.6, formality=0.7, directness=0.8, humor=0.1),
    "basecamp_dhh": ToneCharacteristics(warmth=0.4, formality=0.3, directness=1.0, humor=0.4),
    "stripe_atlas": ToneCharacteristics(warmth=0.5, formality=0.8, directness=0.9, humor=0.0),
    "professional_formal": ToneCharacteristics(warmth=0.3, formality=1.0, directness=0.6, humor=0.0),
    "friendly_casual": ToneCharacteristics(warmth=1.0, formality=0.2, directness=0.5, humor=0.6),
}


# =============================================================================
# Output Metadata
# =============================================================================


class OutputMetadata(LightwaveBaseSchema):
    """Metadata included with all outputs."""

    request_id: UUID = Field(
        default_factory=uuid4,
        description="Unique identifier for the request",
    )
    agent_type: str = Field(..., description="Agent that generated the output")
    output_mode: OutputMode = Field(..., description="v_write or v_speak")
    tone: ToneModel = Field(..., description="Tone model used")
    format: OutputFormat = Field(..., description="Output format")
    generated_at: datetime = Field(
        default_factory=datetime.utcnow,
        description="When the output was generated",
    )
    token_count: int | None = Field(None, description="Number of tokens in output")
    confidence: float | None = Field(
        None,
        ge=0.0,
        le=1.0,
        description="Agent confidence in response (0-1)",
    )


# =============================================================================
# vWrite Output
# =============================================================================


class VWriteOutput(LightwaveBaseSchema):
    """
    Written, documented output for persistent records.

    vWrite is used for:
    - Reports
    - Documentation
    - Emails
    - Contracts
    - Summaries

    Characteristics:
    - Persistent
    - Formatted
    - Auditable
    - Async-friendly
    """

    content: str = Field(..., description="The formatted output content")
    tone: ToneModel = Field(
        "lightwave_authentic",
        description="Tone model used for formatting",
    )
    format: OutputFormat = Field(
        "markdown",
        description="Output format",
    )
    agent_type: str = Field(..., description="Agent that generated the output")
    metadata: OutputMetadata | None = Field(None, description="Output metadata")

    # vWrite-specific fields
    title: str | None = Field(None, description="Document title if applicable")
    sections: list[str] | None = Field(
        None,
        description="Document sections used (e.g., ['summary', 'details'])",
    )

    def with_metadata(self) -> VWriteOutput:
        """Add metadata if not present."""
        if self.metadata is None:
            return self.model_copy(
                update={
                    "metadata": OutputMetadata(
                        agent_type=self.agent_type,
                        output_mode="v_write",
                        tone=self.tone,
                        format=self.format,
                    )
                }
            )
        return self

    @property
    def tone_characteristics(self) -> ToneCharacteristics:
        """Get the characteristics for the current tone."""
        return TONE_CHARACTERISTICS[self.tone]


# =============================================================================
# vSpeak Output
# =============================================================================


class VSpeakOutput(LightwaveBaseSchema):
    """
    Conversational, ephemeral output for real-time interaction.

    vSpeak is used for:
    - Chat responses
    - Quick answers
    - Confirmations
    - Clarifications

    Characteristics:
    - Realtime
    - Natural
    - Contextual
    - Concise
    """

    content: str = Field(..., description="The conversational output content")
    tone: ToneModel = Field(
        "lightwave_authentic",
        description="Tone model used for formatting",
    )
    agent_type: str = Field(..., description="Agent that generated the output")
    metadata: OutputMetadata | None = Field(None, description="Output metadata")

    # vSpeak-specific fields
    suggested_followups: list[str] = Field(
        default_factory=list,
        max_length=3,
        description="Suggested follow-up actions or questions",
    )
    requires_confirmation: bool = Field(
        False,
        description="Whether this response requires user confirmation",
    )
    pending_action: str | None = Field(
        None,
        description="Action pending user confirmation",
    )

    def with_metadata(self) -> VSpeakOutput:
        """Add metadata if not present."""
        if self.metadata is None:
            return self.model_copy(
                update={
                    "metadata": OutputMetadata(
                        agent_type=self.agent_type,
                        output_mode="v_speak",
                        tone=self.tone,
                        format="plain_text",
                    )
                }
            )
        return self

    @property
    def tone_characteristics(self) -> ToneCharacteristics:
        """Get the characteristics for the current tone."""
        return TONE_CHARACTERISTICS[self.tone]


# =============================================================================
# Platform Defaults
# =============================================================================


class PlatformDefaults(SSTSchema):
    """Default output settings for a platform."""

    output_mode: OutputMode
    format: OutputFormat
    tone: ToneModel


# Platform default mappings (from SST)
PLATFORM_DEFAULTS: dict[Platform, PlatformDefaults] = {
    "cli": PlatformDefaults(
        output_mode="v_write",
        format="markdown",
        tone="lightwave_authentic",
    ),
    "slack": PlatformDefaults(
        output_mode="v_speak",
        format="slack_blocks",
        tone="lightwave_authentic",
    ),
    "whatsapp": PlatformDefaults(
        output_mode="v_speak",
        format="plain_text",
        tone="friendly_casual",
    ),
    "email": PlatformDefaults(
        output_mode="v_write",
        format="html",
        tone="professional_formal",
    ),
    "api": PlatformDefaults(
        output_mode="v_write",
        format="json",
        tone="stripe_atlas",
    ),
}


def get_platform_defaults(platform: Platform) -> PlatformDefaults:
    """Get default output settings for a platform."""
    return PLATFORM_DEFAULTS[platform]


# =============================================================================
# Format Request/Response (for API)
# =============================================================================


class FormatOutputRequest(LightwaveBaseSchema):
    """Request to format content using vWrite/vSpeak."""

    content: str = Field(..., min_length=1, description="Content to format")
    mode: OutputMode = Field(..., description="Output mode (v_write or v_speak)")
    agent_type: str = Field(..., description="Agent type generating the output")
    tone: ToneModel | None = Field(
        None,
        description="Tone model (defaults based on platform)",
    )
    format: OutputFormat | None = Field(
        None,
        description="Output format (defaults based on platform)",
    )
    platform: Platform = Field(
        "cli",
        description="Target platform for formatting",
    )
    # vSpeak options
    include_followups: bool = Field(
        True,
        description="Whether to suggest follow-up actions",
    )
    # vWrite options
    template: str | None = Field(
        None,
        description="Document template (report, email, documentation)",
    )


class FormatOutputResponse(LightwaveBaseSchema):
    """Response from format output request."""

    content: str = Field(..., description="Formatted content")
    mode: OutputMode = Field(..., description="Output mode used")
    tone: ToneModel = Field(..., description="Tone model applied")
    format: OutputFormat = Field(..., description="Output format used")
    metadata: OutputMetadata = Field(..., description="Output metadata")
    suggested_followups: list[str] = Field(
        default_factory=list,
        description="Suggested follow-ups (vSpeak only)",
    )
