package pl.edu.pw.mini.sg.movingtargets.coord

import pl.edu.pw.mini.jk.sg.game.common.State
import pl.edu.pw.mini.jk.sg.game.immutable.{ImmutableGame, Payoffs}
import pl.edu.pw.mini.jk.sg.game.immutable.mutable.MutableWrapper
import pl.edu.pw.mini.sg.movingtargets.{AttackStart, MovingTargetsGameConfig}

final case class CoordImmutableGame (
  defenderState: CoordDefenderState,
  attackerState: CoordAttackerState,
  attackStarted: Option[AttackStart],
  game: MovingTargetsGameConfig,
  defenderPayoff: Double,
  attackerPayoff: Double 
) extends State[CoordAttackerState, CoordDefenderState] with ImmutableGame[CoordMove, CoordAttackerMove, CoordDefenderState, CoordAttackerState, CoordImmutableGame] {
  override def attackerVisibleState: CoordAttackerState = attackerState
  override def defenderVisibleState: CoordDefenderState = defenderState
  override def makeMoves(defenderMove: CoordMove, attackerMove: CoordAttackerMove) : (Payoffs, CoordImmutableGame) = {
    val newDefenderState = defenderState.advance(defenderMove)
    val newAttackerState = attackerState.advance(attackerMove)
    //Jeśli jestem w stanie decyzyjnym atakującego, to jest to początek timeStepu
    val payoffs = newAttackerState match {
      case _: CoordAttackerMoveState => game.getRewardForAS(attackStarted, newDefenderState.currentPositions, newDefenderState.getTimeStep)
      case _ => (Payoffs(0, 0, 0, 0), attackStarted)
    }

    val newAttackStarted = attackerMove match {
      case AttackDecision(targetId) => Some(AttackStart(timeStep = defenderState.getTimeStep+1, targetId = targetId))
      case _ => payoffs._2
    }


    (payoffs._1, copy(defenderState = newDefenderState, attackerState = newAttackerState, attackStarted = newAttackStarted, defenderPayoff = defenderPayoff + payoffs._1.defenderPayoff, attackerPayoff = payoffs._1.attackerPayoff + attackerPayoff))
  }
  override def getAttackerVisibleState(): CoordAttackerState = attackerState
  override def getDefenderVisibleState(): CoordDefenderState = defenderState
  override def timeStep = defenderState.timeStep
}


object CoordImmutableGame {
  final def initialState(gameConfig: MovingTargetsGameConfig) =
    CoordImmutableGame(
      defenderState = CoordDefenderState.initialState(gameConfig),
      attackerState = CoordAttackerState.initialState(gameConfig),
      attackStarted = None,
      game = gameConfig,
      defenderPayoff = 0,
      attackerPayoff = 0
    )

  final def createMutableGame(gameConfig: MovingTargetsGameConfig) = {
    new MutableWrapper[CoordAttackerMove, CoordMove, CoordAttackerState, CoordDefenderState, CoordImmutableGame](initialState(gameConfig))
  }
}
