from __future__ import annotations

from pydantic import BaseModel


class ActionItem(BaseModel):
    label: str
    enabled: bool
    reason: str | None = None


class PricePoint(BaseModel):
    date: str
    value: str
    currency: str = "CHF"
    provider: str | None = None
    quality_status: str | None = None


class CryptoPosition(BaseModel):
    asset_id: str
    name: str
    symbol: str
    quantity_total: str
    price_chf: str | None = None
    market_value_chf: str | None = None
    portfolio_share_pct: str
    wallet_count: int
    price_status: str
    last_price_update: str | None = None
    coingecko_url: str | None = None


class WalletAllocation(BaseModel):
    wallet_id: str
    wallet: str
    quantity: str
    market_value_chf: str | None = None


class WalletCoin(BaseModel):
    asset_id: str
    name: str
    symbol: str
    quantity: str
    market_value_chf: str | None = None
    status: str


class CoinGeckoInfo(BaseModel):
    market_cap_rank: int | None = None
    market_cap: str | None = None
    volume_24h: str | None = None
    change_24h_pct: str | None = None
    change_7d_pct: str | None = None
    homepage: str | None = None
    image_url: str | None = None


class CryptoPositionDetail(CryptoPosition):
    wallet_allocations: list[WalletAllocation]
    coingecko_info: CoinGeckoInfo | None = None
    available_actions: list[ActionItem] = []
    price_history: list[PricePoint] = []
    read_only_note: str = "Live-Modus später; keine Provider-Abfrage beim Rendern."


class WalletSummary(BaseModel):
    wallet_id: str
    name: str
    wallet_type: str
    provider: str = ""
    coin_count: int
    market_value_chf: str | None = None
    status: str


class WalletDetail(WalletSummary):
    coins: list[WalletCoin]


class EquityPosition(BaseModel):
    position_id: str
    instrument_id: str | None = None
    name: str
    ticker: str = ""
    isin: str = ""
    account: str = ""
    asset_class: str
    quantity: str
    currency: str
    price: str | None = None
    market_value_chf: str | None = None
    portfolio_share_pct: str | None = None
    price_date: str | None = None
    provider: str | None = None
    provider_symbol: str | None = None
    exchange: str | None = None
    price_currency: str | None = None
    data_status: str = "missing"
    status_code: str = "price_missing"
    status_reason: str | None = None
    status: str


class EquityPortfolioSummary(BaseModel):
    total_positions: int
    valued_positions: int
    unvalued_positions: int
    coverage_complete: bool
    equity_value_chf: str | None = None
    valued_partial_chf: str
    value_label: str
    as_of: str | None = None
    last_successful_run: str | None = None
    status: str
    status_label: str
    unvalued_tickers: list[str] = []


class EquityPositionDetail(EquityPosition):
    fx_status: str = "not_needed"
    cost_basis_status: str = "unknown"
    day_change_chf: str | None = None
    last_trade_date: str | None = None
    provider: str | None = None
    source_url: str | None = None
    provider_symbol: str | None = None
    exchange: str | None = None
    price_currency: str | None = None
    fx_rate_to_chf: str | None = None
    data_source: str | None = None
    available_actions: list[ActionItem]
    price_history: list[PricePoint] = []


class CashSnapshot(BaseModel):
    snapshot_id: str
    snapshot_type: str
    balance_date: str
    amount_chf: str
    source: str
    note: str = ""
    difference_to_previous_chf: str | None = None
    audit_hint: str | None = None


class CashPosition(BaseModel):
    id: str
    account_id: str = ""
    platform: str
    account_label: str
    account_type: str = "cash"
    currency: str
    balance_mode: str = "manual"
    amount: str
    amount_chf: str | None = None
    calculated_balance_chf: str = "0.00"
    manual_balance_chf: str | None = None
    csv_anchor_balance_chf: str | None = None
    used_value_chf: str = "0.00"
    difference_chf: str = "0.00"
    last_manual_reconciliation: str | None = None
    last_imported_booking: str | None = None
    status: str


class CashPositionDetail(CashPosition):
    last_change: str | None = None
    history: list[CashSnapshot] = []
    available_actions: list[ActionItem]


class InstrumentSearchCandidate(BaseModel):
    candidate_id: str
    label: str
    asset_class: str
    isin: str = ""
    ticker: str = ""
    exchange: str = ""
    currency: str = ""
    provider: str = ""
    provider_symbol: str = ""
    exchange_name: str = ""
    mic: str = ""
    country: str = ""
    security_type: str = ""
    last_price: str | None = None
    price_currency: str | None = None
    price_date: str | None = None
    confidence_label: str
    review_required: bool


class InstrumentSearchRequest(BaseModel):
    asset_class: str
    query: str
    currency: str | None = None
    exchange: str | None = None
    country: str | None = None
    main_listing_only: bool = True
    hide_cdr_adr_derivatives: bool = True


class ProviderSearchResponse(BaseModel):
    candidates: list[InstrumentSearchCandidate]
    warnings: list[str] = []
    selection_required: bool = True


class CleanupPreviewResponse(BaseModel):
    accounts: int
    instruments: int
    transactions: int
    alerts: int
    manual_positions_preserved: int
    warnings: list[str] = []


class GenericConfirmRequest(BaseModel):
    confirm: bool
    note: str = ""
    confirmation_text: str | None = None


class RemovePositionPreviewResponse(BaseModel):
    position_id: str
    transaction_count: int
    safe_to_remove: bool
    reason: str
    affected_transactions: int
    consequences: list[str]


class ContainerPreviewRequest(BaseModel):
    name: str | None = None
    wallet_type: str | None = None
    platform_name: str | None = None
    account_name: str | None = None
    account_type: str | None = None
    currency: str = "CHF"
    note: str = ""


class ContainerConfirmRequest(ContainerPreviewRequest):
    preview_id: str | None = None
    confirm: bool


class ReferenceAccount(BaseModel):
    account_id: str
    label: str
    account_type: str
    currency: str
    valuation_mode: str = "positions"
    portfolio_bucket: str = "other"
    allow_position_adds: bool = True


class AccountValuePreviewRequest(BaseModel):
    valuation_date: str
    total_value_chf: str
    note: str = ""


class AccountValueConfirmRequest(AccountValuePreviewRequest):
    preview_id: str
    confirm: bool


class PositionPreviewRequest(BaseModel):
    asset_class: str
    account_id: str
    instrument_id: str | None = None
    candidate_id: str | None = None
    name: str | None = None
    ticker: str | None = None
    isin: str | None = None
    quantity: str
    currency: str
    trade_date: str
    transaction_type: str
    cost_basis_original: str | None = None
    note: str = ""


class PositionConfirmRequest(PositionPreviewRequest):
    preview_id: str
    confirm: bool


class CashPreviewRequest(BaseModel):
    account_id: str
    currency: str
    amount: str
    transaction_type: str
    booking_date: str
    note: str = ""


class CashConfirmRequest(CashPreviewRequest):
    preview_id: str
    confirm: bool


class CashSnapshotPreviewRequest(BaseModel):
    account_id: str
    snapshot_type: str
    balance_date: str
    amount_chf: str
    note: str = ""


class CashSnapshotConfirmRequest(CashSnapshotPreviewRequest):
    preview_id: str
    confirm: bool


class CryptoActionPreviewRequest(BaseModel):
    asset_id: str | None = None
    coin_name: str | None = None
    symbol: str | None = None
    wallet_id: str
    target_wallet_id: str | None = None
    quantity: str
    fee_quantity: str | None = None
    transaction_type: str
    effective_date: str
    note: str = ""
    coingecko_id: str | None = None


class CryptoActionConfirmRequest(CryptoActionPreviewRequest):
    preview_id: str
    confirm: bool


class EquitySellPreviewRequest(BaseModel):
    position_id: str
    cash_account_id: str | None = None
    quantity: str
    price_original: str
    currency: str
    trade_date: str
    fees_original: str | None = None
    note: str = ""


class EquitySellConfirmRequest(EquitySellPreviewRequest):
    preview_id: str
    confirm: bool


class EquityDividendPreviewRequest(BaseModel):
    position_id: str
    cash_account_id: str
    gross_amount: str
    currency: str
    swiss_tax: str | None = None
    foreign_tax: str | None = None
    other_deductions: str | None = None
    payment_date: str
    note: str = ""


class EquityDividendConfirmRequest(EquityDividendPreviewRequest):
    preview_id: str
    confirm: bool


class PreviewResponse(BaseModel):
    preview_id: str
    asset_class: str | None = None
    summary: str
    amount_chf: str | None = None
    fx_status: str
    warnings: list[str]


class ConfirmResponse(BaseModel):
    status: str
    entity_id: str
    audit_id: str
    message: str


class AuditEntry(BaseModel):
    audit_id: str
    timestamp: str
    action: str
    entity_type: str
    entity_id: str
    note: str | None = None
    quality_status: str
