"""Equity Quote Standard Model."""

from datetime import datetime

from openbb_core.provider.abstract.data import Data
from openbb_core.provider.abstract.query_params import QueryParams
from openbb_core.provider.utils.descriptions import (
    DATA_DESCRIPTIONS,
    QUERY_DESCRIPTIONS,
)
from pydantic import Field, field_validator


class EquityQuoteQueryParams(QueryParams):
    """Equity Quote Query."""

    symbol: str = Field(description=QUERY_DESCRIPTIONS.get("symbol", ""))

    @field_validator("symbol", mode="before", check_fields=False)
    @classmethod
    def to_upper(cls, v: str) -> str:
        """Convert field to uppercase."""
        return v.upper()


class EquityQuoteData(Data):
    """Equity Quote Data."""

    symbol: str = Field(description=DATA_DESCRIPTIONS.get("symbol", ""))
    asset_type: str | None = Field(
        default=None, description="Type of asset - i.e, stock, ETF, etc."
    )
    name: str | None = Field(default=None, description="Name of the company or asset.")
    exchange: str | None = Field(
        default=None,
        description="The name or symbol of the venue where the data is from.",
    )
    bid: float | None = Field(default=None, description="Price of the top bid order.")
    bid_size: int | None = Field(
        default=None,
        description="This represents the number of round lot orders at the given price."
        + " The normal round lot size is 100 shares."
        + " A size of 2 means there are 200 shares available at the given price.",
    )
    bid_exchange: str | None = Field(
        default=None,
        description="The specific trading venue where the purchase order was placed.",
    )
    ask: float | None = Field(default=None, description="Price of the top ask order.")
    ask_size: int | None = Field(
        default=None,
        description="This represents the number of round lot orders at the given price."
        + " The normal round lot size is 100 shares."
        + " A size of 2 means there are 200 shares available at the given price.",
    )
    ask_exchange: str | None = Field(
        default=None,
        description="The specific trading venue where the sale order was placed.",
    )
    quote_conditions: str | int | list[str] | list[int] | None = Field(
        default=None,
        description="Conditions or condition codes applicable to the quote.",
    )
    quote_indicators: str | int | list[str] | list[int] | None = Field(
        default=None,
        description="Indicators or indicator codes applicable to the participant"
        + " quote related to the price bands for the issue, or the affect the quote has"
        + " on the NBBO.",
    )
    sales_conditions: str | int | list[str] | list[int] | None = Field(
        default=None,
        description="Conditions or condition codes applicable to the sale.",
    )
    sequence_number: int | None = Field(
        default=None,
        description="The sequence number represents the sequence in which message events happened."
        + " These are increasing and unique per ticker symbol,"
        + " but will not always be sequential (e.g., 1, 2, 6, 9, 10, 11).",
    )
    market_center: str | None = Field(
        default=None,
        description="The ID of the UTP participant that originated the message.",
    )
    participant_timestamp: datetime | None = Field(
        default=None,
        description="Timestamp for when the quote was generated by the exchange.",
    )
    trf_timestamp: datetime | None = Field(
        default=None,
        description="Timestamp for when the TRF (Trade Reporting Facility) received the message.",
    )
    sip_timestamp: datetime | None = Field(
        default=None,
        description="Timestamp for when the SIP (Security Information Processor)"
        + " received the message from the exchange.",
    )
    last_price: float | None = Field(
        default=None, description="Price of the last trade."
    )
    last_tick: str | None = Field(
        default=None, description="Whether the last sale was an up or down tick."
    )
    last_size: int | None = Field(default=None, description="Size of the last trade.")
    last_timestamp: datetime | None = Field(
        default=None, description="Date and Time when the last price was recorded."
    )
    open: float | None = Field(
        default=None, description=DATA_DESCRIPTIONS.get("open", "")
    )
    high: float | None = Field(
        default=None, description=DATA_DESCRIPTIONS.get("high", "")
    )
    low: float | None = Field(
        default=None, description=DATA_DESCRIPTIONS.get("low", "")
    )
    close: float | None = Field(
        default=None, description=DATA_DESCRIPTIONS.get("close", "")
    )
    volume: int | float | None = Field(
        default=None, description=DATA_DESCRIPTIONS.get("volume", "")
    )
    exchange_volume: int | float | None = Field(
        default=None,
        description="Volume of shares exchanged during the trading day on the specific exchange.",
    )
    prev_close: float | None = Field(
        default=None, description=DATA_DESCRIPTIONS.get("prev_close", "")
    )
    change: float | None = Field(
        default=None, description="Change in price from previous close."
    )
    change_percent: float | None = Field(
        default=None,
        description="Change in price as a normalized percentage.",
        json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
    )
    year_high: float | None = Field(
        default=None, description="The one year high (52W High)."
    )
    year_low: float | None = Field(
        default=None, description="The one year low (52W Low)."
    )
