package wow.doge.mygame

import game.GameApp
import com.jme3.app.StatsAppState

import akka.actor.typed.ActorSystem
import akka.actor.typed.SpawnProtocol
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.Behavior
import akka.util.Timeout
import com.jme3.system.AppSettings
import wow.doge.mygame.game.GameAppActor
import wow.doge.mygame.scriptsystem.ScriptCachingActor
object Main extends App {
  import java.util.logging.{Logger, Level}
  Logger.getLogger("").setLevel(Level.SEVERE)

  // runner.runCode("""|println("starting scala script engine")""".stripMargin)
  val gameApp = new GameApp(
    // new EntityDataState(),
    // new TestAppState(),
    // new PlayerMovementState(),
    // new FlyCamAppState(),
    new StatsAppState()
  )
  val settings = new AppSettings(true)
  // settings.setVSync(true)
  settings.setFrameRate(144)
  gameApp.setSettings(settings)
  val actorSystem = ActorSystem(RootActor(gameApp), "rootActor")
  // actorSystem.eventStream
  // gameApp.start()
  println("here 1")
  // actorSystem.terminate()
  // JMEExecutorService.shutdown()
  // println("here 2")
  //FIXME remove this
  // System.exit(0)
}

object RootActor {
  def apply(app: GameApp): Behavior[SpawnProtocol.Command] =
    Behaviors.setup { ctx =>
      ctx.log.debug("Starting root actor")
      val testActor = ctx.spawn(TestActor(), "testActor")
      val _ = ctx.spawn(GameAppActor(app), "gameAppActor")

      testActor ! TestActor.Test
      SpawnProtocol()
    }
}

object TestActor {
  sealed trait Command
  case object Test extends Command
  private case object Done extends Command
  // sealed trait Result
  // case object Done extends Result

  import scala.concurrent.duration._
  implicit val timeout = Timeout(15.seconds)
  // implicit val scheduler =

  def apply(): Behavior[Command] =
    Behaviors.setup { ctx =>
      ctx.spawn(ScriptCachingActor(), "scriptCacher")
      Behaviors.receiveMessage { msg =>
        msg match {
          case Test =>
            // ctx.ask(
            //   router,
            //   ScriptActor.Compile(
            //     // os.pwd / "some.sc",
            //     os.pwd / "src" / "main" / "resources" / "hello2.main.kts",
            //     _
            //   )
            // ) {
            //   case Success(value) =>
            //     ctx.log.debug("Received Value")
            //     ctx.log.debug(value.toString())
            //     Done
            //   case Failure(exception) =>
            //     ctx.log.debug(s"Received Error ${exception.getMessage()}")
            //     Done
            // }
            // val x = scriptStorer
            //   .askT(
            //     ScriptStoringActor
            //       .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
            //   )(timeout, ctx.system.scheduler)

            // ctx.ask(
            //   scriptStorer,
            //   ScriptStoringActor
            //     .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
            // ) {
            //   case Success(value) => {
            //     ctx.log.debug(value.toString())
            //     ctx.ask(
            //       scriptStorer,
            //       ScriptStoringActor
            //         .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
            //     ) {
            //       case Success(value) => {
            //         ctx.log.debug(value.toString())
            //         Done
            //       }
            //       case Failure(exception) =>
            //         ctx.log.debug(exception.getMessage())
            //         Done
            //     }
            //     Done
            //   }
            //   case Failure(exception) =>
            //     ctx.log.debug(exception.getMessage())
            //     Done
            // }

            Behaviors.same
          case Done => Behaviors.same
        }

      // SpawnProtocol()
      // Behaviors.same
      }
    }
}
