"""
Synor Economics SDK Types.
"""

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


class ServiceType(str, Enum):
    """Service types for pricing."""
    COMPUTE = "compute"
    STORAGE = "storage"
    DATABASE = "database"
    HOSTING = "hosting"
    BRIDGE = "bridge"
    RPC = "rpc"


class BillingPeriod(str, Enum):
    """Billing period."""
    HOURLY = "hourly"
    DAILY = "daily"
    WEEKLY = "weekly"
    MONTHLY = "monthly"


class StakeStatus(str, Enum):
    """Stake status."""
    ACTIVE = "active"
    UNSTAKING = "unstaking"
    WITHDRAWN = "withdrawn"
    SLASHED = "slashed"


class DiscountType(str, Enum):
    """Discount type."""
    PERCENTAGE = "percentage"
    FIXED = "fixed"
    VOLUME = "volume"
    REFERRAL = "referral"


class InvoiceStatus(str, Enum):
    """Invoice status."""
    PENDING = "pending"
    PAID = "paid"
    OVERDUE = "overdue"
    CANCELLED = "cancelled"


@dataclass
class UsageMetrics:
    """Usage metrics for pricing."""
    compute_hours: Optional[float] = None
    storage_bytes: Optional[int] = None
    database_ops: Optional[int] = None
    hosting_requests: Optional[int] = None
    bridge_transfers: Optional[int] = None
    rpc_calls: Optional[int] = None


@dataclass
class ServiceUsage:
    """Service usage in plan."""
    service: ServiceType
    metrics: UsageMetrics
    tier: Optional[str] = None


@dataclass
class UsagePlan:
    """Usage plan for cost estimation."""
    services: List[ServiceUsage]
    period: BillingPeriod
    start_date: Optional[int] = None
    end_date: Optional[int] = None


@dataclass
class AppliedDiscount:
    """Applied discount."""
    code: str
    type: DiscountType
    value: str
    savings: str
    description: Optional[str] = None


@dataclass
class TaxAmount:
    """Tax amount."""
    name: str
    rate: float
    amount: str


@dataclass
class Price:
    """Price breakdown."""
    service: ServiceType
    base_price: str
    quantity: str
    unit: str
    subtotal: str
    discounts: List[AppliedDiscount]
    total: str
    currency: str


@dataclass
class CostEstimate:
    """Cost estimate."""
    services: List[Price]
    subtotal: str
    discounts: List[AppliedDiscount]
    taxes: List[TaxAmount]
    total: str
    currency: str
    valid_until: int


@dataclass
class UsageDetail:
    """Usage detail."""
    timestamp: int
    operation: str
    quantity: float
    unit: str
    cost: str


@dataclass
class ServiceUsageRecord:
    """Service usage record."""
    service: ServiceType
    metrics: UsageMetrics
    cost: str
    details: List[UsageDetail]


@dataclass
class Usage:
    """Usage record."""
    period: BillingPeriod
    start_date: int
    end_date: int
    services: List[ServiceUsageRecord]
    total_cost: str
    currency: str


@dataclass
class InvoiceItem:
    """Invoice item."""
    service: ServiceType
    description: str
    quantity: str
    unit_price: str
    total: str


@dataclass
class Invoice:
    """Invoice."""
    id: str
    status: InvoiceStatus
    period: BillingPeriod
    start_date: int
    end_date: int
    items: List[InvoiceItem]
    subtotal: str
    discounts: List[AppliedDiscount]
    taxes: List[TaxAmount]
    total: str
    currency: str
    due_date: int
    paid_at: Optional[int] = None
    payment_method: Optional[str] = None


@dataclass
class AccountBalance:
    """Account balance."""
    available: str
    pending: str
    reserved: str
    total: str
    currency: str
    last_updated: int
    credit_limit: Optional[str] = None


@dataclass
class StakeReceipt:
    """Stake receipt."""
    id: str
    amount: str
    lock_duration: int
    start_date: int
    end_date: int
    apy: str
    estimated_rewards: str
    tx_hash: str


@dataclass
class UnstakeReceipt:
    """Unstake receipt."""
    id: str
    stake_id: str
    amount: str
    rewards: str
    total: str
    unbonding_period: int
    available_at: int
    tx_hash: str


@dataclass
class StakeInfo:
    """Stake info."""
    id: str
    amount: str
    status: StakeStatus
    lock_duration: int
    start_date: int
    end_date: int
    apy: str
    earned_rewards: str
    pending_rewards: str
    validator: Optional[str] = None


@dataclass
class StakeRewardDetail:
    """Stake reward detail."""
    stake_id: str
    earned: str
    pending: str
    apy: str


@dataclass
class StakingRewards:
    """Staking rewards."""
    total_earned: str
    pending: str
    claimed: str
    stakes: List[StakeRewardDetail]
    last_claim_date: Optional[int] = None
    next_claim_available: Optional[int] = None


@dataclass
class Discount:
    """Discount."""
    code: str
    type: DiscountType
    value: str
    description: str
    valid_from: int
    valid_until: int
    applicable_services: List[ServiceType]
    used_count: int
    min_purchase: Optional[str] = None
    max_discount: Optional[str] = None
    usage_limit: Optional[int] = None


@dataclass
class StakeOptions:
    """Staking options."""
    validator: Optional[str] = None
    auto_compound: Optional[bool] = None
    lock_duration: Optional[int] = None


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