from __future__ import annotations

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field


# ── Vote Session ─────────────────────────────────────────────────


class VoteSessionCreate(BaseModel):
    """Payload for opening a new vote session."""

    decision_id: UUID | None = None
    item_version_id: UUID | None = None
    voting_protocol_id: UUID = Field(..., description="ID of the voting protocol to apply")


class VoteSessionOut(BaseModel):
    """Full vote session representation including tallies."""

    model_config = ConfigDict(from_attributes=True)

    id: UUID
    decision_id: UUID | None = None
    item_version_id: UUID | None = None
    voting_protocol_id: UUID

    # Snapshot at session start
    wot_size: int
    smith_size: int
    techcomm_size: int

    # Dates
    starts_at: datetime
    ends_at: datetime

    # Status
    status: str

    # Tallies
    votes_for: int
    votes_against: int
    votes_total: int
    smith_votes_for: int
    techcomm_votes_for: int
    threshold_required: float
    result: str | None = None

    # Chain recording
    chain_recorded: bool
    chain_tx_hash: str | None = None

    created_at: datetime


class VoteSessionListOut(BaseModel):
    """Lighter vote session representation for list endpoints (no nested votes)."""

    model_config = ConfigDict(from_attributes=True)

    id: UUID
    decision_id: UUID | None = None
    item_version_id: UUID | None = None
    voting_protocol_id: UUID

    # Snapshot at session start
    wot_size: int
    smith_size: int
    techcomm_size: int

    # Dates
    starts_at: datetime
    ends_at: datetime

    # Status
    status: str

    # Tallies
    votes_for: int
    votes_against: int
    votes_total: int
    threshold_required: float
    result: str | None = None

    created_at: datetime


# ── Threshold Details ────────────────────────────────────────────


class ThresholdDetailOut(BaseModel):
    """Detailed threshold computation result for a vote session."""

    wot_threshold: int
    smith_threshold: int | None = None
    techcomm_threshold: int | None = None
    votes_for: int
    votes_against: int
    votes_total: int
    wot_passed: bool
    smith_passed: bool | None = None
    techcomm_passed: bool | None = None
    overall_passed: bool
    participation_rate: float
    formula_params: dict


# ── Vote Result ──────────────────────────────────────────────────


class VoteResultOut(BaseModel):
    """Structured vote result response."""

    session_id: UUID
    result: str | None = None  # adopted, rejected
    threshold_required: float
    votes_for: int
    votes_against: int
    votes_total: int
    adopted: bool
    nuanced_breakdown: dict | None = None  # for nuanced votes


# ── Vote ─────────────────────────────────────────────────────────


class VoteCreate(BaseModel):
    """Payload for casting a vote (with cryptographic proof)."""

    session_id: UUID
    vote_value: str = Field(..., max_length=32, description="for, against, or nuanced level")
    nuanced_level: int | None = Field(default=None, ge=0, le=5, description="0-5 for nuanced votes")
    comment: str | None = None
    signature: str = Field(..., description="Ed25519 signature of signed_payload")
    signed_payload: str = Field(..., description="The exact payload that was signed")


class VoteOut(BaseModel):
    """Full vote representation."""

    model_config = ConfigDict(from_attributes=True)

    id: UUID
    session_id: UUID
    voter_id: UUID
    vote_value: str
    nuanced_level: int | None = None
    comment: str | None = None
    signature: str
    signed_payload: str
    voter_wot_status: str
    voter_is_smith: bool
    voter_is_techcomm: bool
    is_active: bool
    created_at: datetime
