package beerpongelo

import (
	"math"

	"git.kapelle.org/niklas/beerpong-elo/internal/model"
	"git.kapelle.org/niklas/beerpong-elo/internal/repo"
)

type Controller struct {
	repo repo.Repo
}

func newController(repo repo.Repo) Controller {
	return Controller{
		repo: repo,
	}
}

func (c *Controller) AddGame(game model.Game) (model.GameID, error) {
	parsedGame := model.Game{
		Added:    game.Added,
		Score:    game.Score,
		Overtime: game.Overtime,
	}

	author, err := c.repo.GetOrCreatePlayerID(string(game.Author))
	if err != nil {
		return "", err
	}
	parsedGame.Author = author

	t0p0, err := c.repo.GetOrCreatePlayerID(string(game.Team0Player0))
	if err != nil {
		return "", err
	}
	parsedGame.Team0Player0 = t0p0

	t0p1, err := c.repo.GetOrCreatePlayerID(string(game.Team0Player1))
	if err != nil {
		return "", err
	}
	parsedGame.Team0Player1 = t0p1

	t1p0, err := c.repo.GetOrCreatePlayerID(string(game.Team1Player0))
	if err != nil {
		return "", err
	}
	parsedGame.Team1Player0 = t1p0

	t1p1, err := c.repo.GetOrCreatePlayerID(string(game.Team1Player1))
	if err != nil {
		return "", err
	}
	parsedGame.Team1Player1 = t1p1

	id, err := c.repo.AddGame(parsedGame)
	if err != nil {
		return "", err
	}

	parsedGame.ID = id

  err = c.createGameResult(parsedGame)

  if err != nil {
    return "", err
  }

	return id, nil
}

func (c *Controller) createGameResult(game model.Game) error {
	t0p0, err := c.repo.GetPlayer(game.Team0Player0)
	if err != nil {
		return err
	}
	t0p1, err := c.repo.GetPlayer(game.Team0Player1)
	if err != nil {
		return err
	}
	t1p0, err := c.repo.GetPlayer(game.Team1Player0)
	if err != nil {
		return err
	}
	t1p1, err := c.repo.GetPlayer(game.Team1Player1)
	if err != nil {
		return err
	}

	newT0p0, newT0p1, newT1p0, newT1p1 := NewRating(float64(t0p0.Elo), float64(t0p1.Elo), float64(t1p0.Elo), float64(t1p1.Elo), game.Score)

	t0p0Result := model.GameResult{
		Game:     game.ID,
		Player:   t0p0.ID,
		StartElo: t0p0.Elo,
		EndElo:   int(math.Round(newT0p0)),
	}

	t0p1Result := model.GameResult{
		Game:     game.ID,
		Player:   t0p1.ID,
		StartElo: t0p1.Elo,
		EndElo:   int(math.Round(newT0p1)),
	}

	t1p0Result := model.GameResult{
		Game:     game.ID,
		Player:   t1p0.ID,
		StartElo: t1p0.Elo,
		EndElo:   int(math.Round(newT1p0)),
	}

	t1p1Result := model.GameResult{
		Game:     game.ID,
		Player:   t1p1.ID,
		StartElo: t1p1.Elo,
		EndElo:   int(math.Round(newT1p1)),
	}

  _,err = c.repo.AddGameResult(t0p0Result)
  if err != nil{
    return err
  }
  
  _,err = c.repo.AddGameResult(t0p1Result)
  if err != nil{
    return err
  }
  
  _,err = c.repo.AddGameResult(t1p0Result)
  if err != nil{
    return err
  }
  
  _,err = c.repo.AddGameResult(t1p1Result)
  if err != nil{
    return err
  }

	return nil
}