import math
from enum import Enum, auto
from typing import override

from internal_types.types import Instrument, Position, Quote
from strategy.strategy import Strategy
from utils.utils import Portfolio


class State(Enum):
  POS_0 = auto()
  POS_1 = auto()


class BuyAndHold(Strategy):

  def __init__(self, init_balance, instr: Instrument):
    self.state = State.POS_0
    self.balance = init_balance
    self.instr = instr
    self.portfolio = Portfolio()
    self.desired_pos = 0

  @override
  def curr_position(self) -> int:
    return self.portfolio.curr_position(self.instr)

  @override
  def desired_position(self) -> int:
    return self.desired_pos

  @override
  def order_filled(self, new_pos: Position):
    self.portfolio.add_pos(new_pos)

  @override
  def process_quote(self, quote: Quote):
    match self.state:
      case State.POS_0:
        self.desired_pos = math.floor(self.balance / quote.close / self.instr.multiplier)
        self.state = State.POS_1
      case State.POS_1:
        pass
      case _:
        raise RuntimeError('invalid state')

  @override
  def net_liquid_value(self, closing_price: float) -> float:
    return self.balance + self.portfolio.total_gains(self.instr, closing_price)
