from datetime import datetime

from mexc.core import timestamp as ts, validator, TypedDict
from mexc.spot.core import SpotMixin, ErrorResponse

class AggTrade(TypedDict):
  a: str | None
  """Aggregate tradeId"""
  f: str | None
  """First tradeId"""
  l: str | None
  """Last tradeId"""
  p: str
  """Price"""
  q: str
  """Quantity"""
  T: int
  """Timestamp"""
  m: bool
  """Is buyer maker"""
  M: bool
  """Is best match"""


Response: type[list[AggTrade] | ErrorResponse] = list[AggTrade] | ErrorResponse # type: ignore
validate_response = validator(Response)

class AggTrades(SpotMixin):
  async def agg_trades(
    self, symbol: str, *, limit: int | None = None,
    start: datetime | None = None, end: datetime | None = None,
    validate: bool | None = None,
  ) -> list[AggTrade]:
    """Get aggregate trades for a given symbol, between two timestamps. There must be at most 1h between `start` and `end`.
    
    - `symbol`: The symbol being traded, e.g. `BTCUSDT`.
    - `limit`: The maximum number of trades to return (default: 500, max: 1000).
    - `start`: The start time to query. If given, only trades after this time will be returned (inclusive).
    - `end`: The end time to query. If given, only trades before this time will be returned (inclusive).
    - `validate`: Whether to validate the response against the expected schema (default: True).

    > [MEXC API docs](https://mexcdevelop.github.io/apidocs/spot_v3_en/#compressed-aggregate-trades-list)
    """
    params: dict = {'symbol': symbol}
    if limit is not None:
      params['limit'] = limit
    if start is not None:
      params['startTime'] = ts.dump(start)
    if end is not None:
      params['endTime'] = ts.dump(end)
    r = await self.request('GET', '/api/v3/aggTrades', params=params)
    return self.output(r.text, validate_response, validate)