<?php

function &last(&$array) {
  end($array);
  return $array[key($array)];
}

class XoiPage extends Page {
  public function addStats($stat1, $stat2)
  {
    $sum = $stat1;
    $sum["average"][0] += $stat2["average"][0];
    $sum["average"][1] += $stat2["average"][1];
    $sum["first9"][0] += $stat2["first9"][0];
    $sum["first9"][1] += $stat2["first9"][1];
    $sum["checkouts"][0] += $stat2["checkouts"][0];
    $sum["checkoutPoints"] = array_merge($sum["checkoutPoints"], $stat2["checkoutPoints"]);
    $sum["checkouts"][1] += $stat2["checkouts"][1];
    if (array_key_exists("checkins", $stat1) && array_key_exists("checkins", $stat2)){
        $sum["checkins"][0] += $stat2["checkins"][0];
        $sum["checkinPoints"] = array_merge($sum["checkinPoints"], $stat2["checkinPoints"]);
        $sum["checkins"][1] += $stat2["checkins"][1];
    }
    $sum["180"] += $stat2["180"];
    $sum["140+"] += $stat2["140+"];
    $sum["100+"] += $stat2["100+"];
    $sum["60+"] += $stat2["60+"];
    return $sum;
  }

  /**
   * @kql-allowed
   */
  public function tournamentStats() {
    $stats = [];
    foreach ($this->playerUUIDs() as $k => $p) {
      $stats[] = $this->parent()->getStats($p);
    }
    return $stats;
  }

  //
  // public function reorderPlayer($order){
  //   kirby()->impersonate('kirby');
  //   return $this->update([
  //     "players" => $order
  //   ]);
  // }
  public function flatScorers(){
    $pp = $this->scorers()->toStructure();
    $players = new Pages();
    foreach ($pp as $i => $p) {
      $players->add($p->member()->toPages());
    }
    return $players;
  }

  public function playerUUIDs(){
    $pp = $this->flatScorers();
    $players = [];
    foreach ($pp as $i => $p) {
      $players[] = $p->uuid()->toString();
    }
    return $players;
  }
  //
  // public function getPlayerPos($playerUUIDs, $uuid)
  // {
  //   $k = 0;
  //   foreach ($playerUUIDs as $i => $playeruuid) {
  //     if ($playeruuid == $uuid) {
  //       break;
  //     }
  //     $k++;
  //   }
  //   return $k;
  // }
  // // entity can be visit, leg or set
  // public function nextPlayer($playerUUIDs, $uuid)
  // {
  //   $k = $this->getPlayerPos($playerUUIDs, $uuid);
  //   return $playerUUIDs[($k+1)%count($playerUUIDs)];
  // }
  //
  // public function updateStats(&$stats, $visit){
  //   $playerUUIDs = $this->playerUUIDs();
  //   $k = $this->getPlayerPos($playerUUIDs, $visit["player"]);
  //
  //   $todos = [&$stats["stats"][$k]];
  //   $todos[] = &last($stats["sets"])["stats"][$k];
  //   $todos[] = &last(last($stats["sets"])["legs"])["stats"][$k];
  //
  //   foreach ($todos as $i => $value) {
  //     $todos[$i]["average"][0] += $visit["sum"];
  //     $todos[$i]["average"][1] += $visit["numDarts"];
  //     if ($visit["visit"] < 4) {
  //       $todos[$i]["first9"][0] += $visit["sum"];
  //       $todos[$i]["first9"][1] += $visit["numDarts"];
  //     }
  //     if ($visit["toGo"][$k] == 0) {
  //       $todos[$i]["checkouts"][0] += 1;
  //       $todos[$i]["checkoutPoints"][] += $visit["sum"];
  //     }
  //     $todos[$i]["checkouts"][1] += $visit["checkoutTries"];
  //     if ($visit["sum"] == 180) {
  //       $todos[$i]["180"] += 1;
  //     } elseif ($visit["sum"] >= 140) {
  //       $todos[$i]["140+"] += 1;
  //     } elseif ($visit["sum"] >= 100) {
  //       $todos[$i]["100+"] += 1;
  //     } elseif ($visit["sum"] >= 60) {
  //       $todos[$i]["60+"] += 1;
  //     }
  //   }
  //   return $stats;
  // }
  //
  // private function newVisit($player, $round)
  // {
  //   return array(
  //     'player' => $player,
  //     'throws' => [],
  //     'visit' => $round,
  //     'checkoutTries' => 0,
  //     'checkinTries' => 0,
  //     'numDarts' => 0,
  //   );
  // }
  //
  // public function calcPoints($throw)
  // {
  //   $throw = trim($throw);
  //   if ($throw == "") {
  //     return 0;
  //   }
  //   if ($throw == "SB"){
  //     return 25;
  //   }
  //   if ($throw == "DB"){
  //     return 50;
  //   }
  //   if ($throw[0] == "S" || $throw[0] == "O" || $throw[0] == "I"){
  //     return intval(substr($throw, 1));
  //   }
  //   if ($throw[0] == "D"){
  //     return 2*intval(substr($throw, 1));
  //   }
  //   if ($throw[0] == "T"){
  //     return 3*intval(substr($throw, 1));
  //   }
  //   if ($throw[0] == "M"){
  //     return 0;
  //   } else {
  //     // TODO: Check for Na
  //     return intval($throw);
  //   }
  // }
  //
  // public function sumPoints($throws)
  // {
  //   $sum = 0;
  //   foreach ($throws as $i => $throw) {
  //     $points = $this->calcPoints($throw);
  //     $sum += $points;
  //   }
  //   return $sum;
  // }
  //
  // public function getWinner($points, $mode)
  // {
  //   $sum = 0;
  //   $k = 0;
  //   $max = -1;
  //   foreach ($points as $i => $point) {
  //     $sum += $point;
  //     if ($max < $point) {
  //       $max = $point;
  //       $maxidx = $k;
  //     }
  //     $k++;
  //   }
  //   if ($max > $mode/$k) {
  //     return $maxidx;
  //   }
  //   if ($sum == $mode) {
  //     return -2;
  //   }
  //   return -1;
  // }
  //
  // public function clearLastVisit()
  // {
  //   $game = $this->rounds()->parseJSON();
  //   $set = &$game["sets"][count($game["sets"])-1];
  //   $leg = &$set["legs"][count($set["legs"])-1];
  //   $visit = &$leg["visits"][count($leg["visits"])-1];
  //   $visit["throws"] = [];
  //   $visit["checkoutTries"] = 0;
  //   $visit["numDarts"] = 0;
  //   unset($visit["sum"]);
  //   unset($visit["toGo"]);
  //   return $this->storeGame($game);
  // }
  //
  // public function addThrows($throws, $numDarts, $checkoutTries, $done=true)
  // {
  //   $game = $this->rounds()->parseJSON();
  //   $set = &$game["sets"][count($game["sets"])-1];
  //   $leg = &$set["legs"][count($set["legs"])-1];
  //   $visit = &$leg["visits"][count($leg["visits"])-1];
  //   $current_throws = $visit['throws'];
  //   if (count($current_throws)+count($throws) > 3) {
  //     $error = "Two many throws given: ".count($current_throws)." + ".count($throws)." > 3";
  //     throw new \Exception($error, 1);
  //   }
  //   $new_throws = array_merge($current_throws, $throws);
  //
  //   $playerUUIDs = $this->playerUUIDs();
  //   $k = $this->getPlayerPos($playerUUIDs, $visit["player"]);
  //   if (count($leg["visits"])-2 < 0) {
  //     $toGo = array_fill(0, count($playerUUIDs), $this->max()->toInt());
  //   } else {
  //     $toGo = $leg["visits"][count($leg["visits"])-2]["toGo"];
  //   }
  //
  //   $visit["numDarts"] += $numDarts;
  //   $visit["throws"] = $new_throws;
  //   $visit["checkoutTries"] += $checkoutTries;
  //   $visit["sum"] = $this->sumPoints($visit["throws"]);
  //
  //   $rest = $toGo[$k] - $visit["sum"];
  //   if ($rest < 0 or ($this->out()->toString() == "Double" && $rest == 1)) {
  //     $visit["sum"] = 0;
  //   } else {
  //     $toGo[$k] = $rest;
  //   }
  //   $visit["toGo"] = $toGo;
  //   if (!$done) {
  //     $this->storeGame($game);
  //     return;
  //   }
  //
  //   $stats = $this->stats()->parseJSON();
  //   $page = $this->updateStats($stats, $visit);
  //   $update = [];
  //   if ($rest != 0) {
  //     // Normal case...next players turn
  //     $nextPlayer = $this->nextPlayer($playerUUIDs, $visit["player"]);
  //     $isNextRound = 0;
  //     if (last(last($game["sets"])["legs"])['visits'][0]["player"] == $nextPlayer) {
  //       $isNextRound = 1;
  //     }
  //     $newVisit = $this->newVisit($nextPlayer, $visit["visit"]+$isNextRound);
  //     last(last($game["sets"])["legs"])['visits'][] = $newVisit;
  //   } else {
  //     // rest == 0 leg finished
  //     // updates Stats...this is maybe the wrong place to store points
  //     $newlegp = $leg["points"];
  //     $newlegp[$k] += 1;
  //     $winner = $this->getWinner($newlegp, $this->legs()->toInt());
  //     if ($winner != -1) {
  //       $newsetp = $set["points"];
  //       $newsetp[$k] += 1;
  //       $winner = $this->getWinner($newsetp, $this->sets()->toInt());
  //       if ($winner != -1) {
  //         if ($winner == -2) {
  //           $stats["winner"] = "DRAW";
  //         } else {
  //           $stats["winner"] = $visit["player"];
  //         }
  //         // Game Over
  //         $update = [
  //           "enddate" => date("Y-m-d H:i:s")
  //         ];
  //       } else {
  //         // new Set
  //         $this->addNewSet($game, $newsetp);
  //         $stats = $this->addNewSetStats($stats);
  //         $stats = $this->addNewLegStats($stats);
  //       }
  //     } else {
  //       // new Leg
  //       $this->addNewLeg($game, $newlegp);
  //       $stats = $this->addNewLegStats($stats);
  //     }
  //   }
  //   $page = $this->storeGame($game);
  //   $page = $page->storeStats($stats);
  //   $page->update($update);
  // }

  // private function newSingleStats($player)
  // {
  //   return array(
  //     "player" => $player,
  //     "average" => [0, 0],
  //     "first9" => [0, 0],
  //     "checkouts" => [0, 0],
  //     "checkoutPoints" => [],
  //     "checkins" => [0, 0],
  //     "checkinPoints" => [],
  //     "60+" => 0,
  //     "100+" => 0,
  //     "140+" => 0,
  //     "180" => 0
  //   );
  // }
  // private function newStats(){
  //   $playerUUIDs = $this->playerUUIDs();
  //   $stats = array(
  //     // "winner" => "",
  //     "stats" => []
  //   );
  //   foreach ($playerUUIDs as $i => $player) {
  //     $n = $this->newSingleStats($player);
  //     $stats["stats"][] = $n;
  //   }
  //   return $stats;
  // }
  //
  // private function addNewSet(&$game, $points){
  //   $playerUUIDs = $this->playerUUIDs();
  //   $set = &$game["sets"][count($game["sets"])-1];
  //   $leg = &$set["legs"][count($set["legs"])-1];
  //   $p = $this->nextPlayer($playerUUIDs, $set["legs"][0]["visits"][0]["player"]);
  //   $game["sets"][] = array(
  //         'points' => $points,
  //         'legs' => [
  //           array(
  //             'points' => array_fill(0, count($playerUUIDs), 0),
  //             'visits' => [$this->newVisit($p, 1)]
  //           )
  //         ]
  //       );
  //   return $game;
  // }
  // private function addNewLeg(&$game, $points){
  //   $playerUUIDs = $this->playerUUIDs();
  //   $set = &$game["sets"][count($game["sets"])-1];
  //   $leg = &$set["legs"][count($set["legs"])-1];
  //   $p = $this->nextPlayer($playerUUIDs, $leg["visits"][0]["player"]);
  //   $set["legs"][] = array(
  //     'points' => $points,
  //     'visits' => [$this->newVisit($p, 1)]
  //   );
  //   return $game;
  // }
  //
  // private function addNewSetStats(&$stats){
  //   $stats["sets"][] = $this->newStats();
  //   $stats["sets"][0]["legs"] = [];
  //   return $stats;
  // }
  // private function addNewLegStats(&$stats){
  //   last($stats["sets"])["legs"][] = $this->newStats();
  //   return $stats;
  // }
  //
  // public function recalcStats(){
  //   $game = $this->rounds()->parseJSON();
  //   $page = $this->initStats();
  //   $stats = $page->stats()->parseJSON();
  //   $lastset = count($game["sets"])-1;
  //   foreach ($game["sets"] as $i => $set) {
  //     $lastleg = count($set["legs"])-1;
  //     foreach ($set["legs"] as $j => $leg) {
  //       $lastvisit = count($leg["visits"])-1;
  //       foreach ($leg["visits"] as $k => $visit) {
  //         if (!($k == $lastvisit && $j == $lastleg && $i == $lastset)) {
  //           $this->updateStats($stats, $visit);
  //         }
  //         if ($k == $lastvisit && $j != $lastleg) {
  //           $this->addNewLegStats($stats);
  //         }
  //       }
  //       if ($j == $lastleg && $i != $lastset) {
  //         $this->addNewSetStats($stats);
  //       }
  //     }
  //   }
  //   return $this->storeStats($stats);
  // }
  //
  // private function initStats()
  // {
  //   $stats = $this->newStats();
  //   $stats["sets"] = [];
  //   $this->addNewSetStats($stats);
  //   $this->addNewLegStats($stats);
  //   return $this->storeStats($stats);
  // }

  // public function initGame($startTime = true) {
  //   $playerUUIDs = $this->playerUUIDs();
  //   $game = array('sets' => [array(
  //         'points' => array_fill(0, count($playerUUIDs), 0),
  //         'legs' => [
  //           array(
  //             'points' => array_fill(0, count($playerUUIDs), 0),
  //             'visits' => [$this->newVisit($playerUUIDs[0], 1)]
  //           )
  //         ]
  //       )
  //   ]);

  //   $page = $this->initStats();
  //   $update = [
  //     'rounds' => json_encode($game)
  //   ];
  //   if ($startTime) {
  //     $update['startdate'] = date("Y-m-d H:i:s");
  //   }
  //   kirby()->impersonate('kirby');
  //   return $page->update($update);
  // }
  //
  // public function storeStats($stats)
  // {
  //   kirby()->impersonate('kirby');
  //   return $this->update([
  //     "stats" => json_encode($stats)
  //   ]);
  //
  // }
  // public function storeGame($game)
  // {
  //   kirby()->impersonate('kirby');
  //   return $this->update([
  //     "rounds" => json_encode($game)
  //   ]);
  // }
}