"""
Synor Governance SDK Types.
"""

from dataclasses import dataclass, field
from enum import Enum
from typing import Optional, List


class ProposalStatus(str, Enum):
    """Proposal status."""
    DRAFT = "draft"
    ACTIVE = "active"
    PASSED = "passed"
    REJECTED = "rejected"
    EXECUTED = "executed"
    CANCELLED = "cancelled"
    EXPIRED = "expired"


class VoteChoice(str, Enum):
    """Vote choice."""
    FOR = "for"
    AGAINST = "against"
    ABSTAIN = "abstain"


class ProposalType(str, Enum):
    """Proposal type."""
    PARAMETER_CHANGE = "parameter_change"
    TREASURY_SPEND = "treasury_spend"
    UPGRADE = "upgrade"
    TEXT = "text"
    CUSTOM = "custom"


class DaoType(str, Enum):
    """DAO type."""
    TOKEN = "token"
    MULTISIG = "multisig"
    HYBRID = "hybrid"


class VestingStatus(str, Enum):
    """Vesting status."""
    ACTIVE = "active"
    PAUSED = "paused"
    COMPLETED = "completed"
    CANCELLED = "cancelled"


@dataclass
class ProposalAction:
    """Proposal action."""
    target: str
    value: str
    calldata: str
    description: Optional[str] = None


@dataclass
class ProposalDraft:
    """Proposal draft."""
    title: str
    description: str
    type: ProposalType
    actions: List[ProposalAction] = field(default_factory=list)
    start_time: Optional[int] = None
    end_time: Optional[int] = None
    quorum: Optional[str] = None
    threshold: Optional[str] = None


@dataclass
class Proposal:
    """Proposal."""
    id: str
    title: str
    description: str
    type: ProposalType
    status: ProposalStatus
    proposer: str
    actions: List[ProposalAction]
    start_time: int
    end_time: int
    quorum: str
    threshold: str
    for_votes: str
    against_votes: str
    abstain_votes: str
    total_votes: str
    created_at: int
    executed_at: Optional[int] = None
    execution_tx_hash: Optional[str] = None


@dataclass
class ProposalFilter:
    """Proposal filter."""
    status: Optional[ProposalStatus] = None
    type: Optional[ProposalType] = None
    proposer: Optional[str] = None
    limit: Optional[int] = None
    offset: Optional[int] = None


@dataclass
class Vote:
    """Vote."""
    choice: VoteChoice
    reason: Optional[str] = None


@dataclass
class VoteReceipt:
    """Vote receipt."""
    proposal_id: str
    voter: str
    choice: VoteChoice
    weight: str
    timestamp: int
    tx_hash: str
    reason: Optional[str] = None


@dataclass
class DelegationInfo:
    """Delegation info."""
    address: str
    amount: str
    timestamp: int


@dataclass
class DelegationReceipt:
    """Delegation receipt."""
    delegator: str
    delegatee: str
    amount: str
    timestamp: int
    tx_hash: str


@dataclass
class VotingPower:
    """Voting power."""
    address: str
    own_power: str
    delegated_power: str
    total_power: str
    delegated_from: List[DelegationInfo]
    delegated_to: Optional[DelegationInfo] = None


@dataclass
class DaoConfig:
    """DAO configuration."""
    name: str
    type: DaoType
    voting_period: int
    quorum: str
    proposal_threshold: str
    token_address: Optional[str] = None
    signers: Optional[List[str]] = None
    threshold: Optional[int] = None
    timelock_delay: Optional[int] = None


@dataclass
class Dao:
    """DAO."""
    id: str
    name: str
    type: DaoType
    voting_period: int
    quorum: str
    proposal_threshold: str
    treasury: str
    total_proposals: int
    active_proposals: int
    total_members: int
    created_at: int
    token_address: Optional[str] = None
    signers: Optional[List[str]] = None
    threshold: Optional[int] = None
    timelock_delay: Optional[int] = None


@dataclass
class VestingSchedule:
    """Vesting schedule."""
    beneficiary: str
    total_amount: str
    start_time: int
    cliff_duration: int
    vesting_duration: int
    revocable: bool = False


@dataclass
class VestingContract:
    """Vesting contract."""
    id: str
    beneficiary: str
    total_amount: str
    released_amount: str
    vested_amount: str
    start_time: int
    cliff_time: int
    end_time: int
    revocable: bool
    status: VestingStatus
    created_at: int
    tx_hash: str


@dataclass
class ClaimResult:
    """Claim result."""
    vesting_id: str
    amount: str
    recipient: str
    timestamp: int
    tx_hash: str


@dataclass
class GovernanceTransaction:
    """Governance transaction."""
    tx_hash: str
    timestamp: int
    block_number: int
    status: str


@dataclass
class GovernanceConfig:
    """Governance SDK configuration."""
    api_key: str
    endpoint: str = "https://governance.synor.io/v1"
    timeout: float = 30.0
    retries: int = 3
    debug: bool = False
