from abc import ABC, abstractmethod
from typing import Generator

import pandas as pd

from internal_types.types import Quote


class TradingGateway(ABC):

  @abstractmethod
  def next_quote(self) -> Generator[Quote, None, None]:
    pass

  @abstractmethod
  def submit_order(self) -> None:
    # todo: submit_order -> async submit_order with callback
    pass


class BacktestGateway(TradingGateway):

  def __init__(self, csv: str, t0: str, t1: str):
    # [t0, t1)
    # t0 & t1: YYYY-mm-dd

    # todo: download parquet from clickhouse and store locally

    df = pd.read_csv(csv)
    df['date_dt'] = pd.to_datetime(df['time'], unit='s')
    df.rename(columns={'time': 'timestamp', 'Volume': 'volume'}, inplace=True)
    self.df = df[(pd.Timestamp(t0) <= df['date_dt']) & (df['date_dt'] < pd.Timestamp(t1))]

  def next_quote(self) -> Generator[Quote, None, None]:
    for row in self.df.itertuples(index=False):
      yield Quote(
        timestamp=row.timestamp,  # type: ignore
        open=row.open,  # type: ignore
        high=row.high,  # type: ignore
        low=row.low,  # type: ignore
        close=row.close,  # type: ignore
        volume=row.volume)  # type: ignore

  def submit_order(self) -> None:
    # todo: submit_order -> async submit_order with callback
    pass
