package com.ljs.ifootballmanager.ai.value;

import com.google.common.collect.Ordering;
import com.ljs.ifootballmanager.ai.Context;
import com.ljs.ifootballmanager.ai.Role;
import com.ljs.ifootballmanager.ai.Tactic;
import com.ljs.ifootballmanager.ai.player.Player;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;

public final class NowValue {

  private Context ctx;

  private Player player;

  private Role role;

  private Tactic tactic;

  private NowValue(Context ctx, Player p, Role r, Tactic t) {
    this.ctx = ctx;
    this.player = p;
    this.role = r;
    this.tactic = t;
  }

  private Double getAbility() {
    return player.evaluate(role, tactic).getRating();
  }

  public Double getVsReplacement() {
    return getAbility() - ctx.getReplacementLevel().getReplacementLevel(role, tactic);
  }

  public Double getScore() {
    return getAbility() + getVsReplacement();
  }

  public String format() {
    return String.format(
        "%2s %s : %3d %3d : %3d",
        role,
        tactic.getCode(),
        Math.round(getAbility()),
        Math.round(getVsReplacement()),
        Math.round(getScore()));
  }

  public String formatShort() {
    return String.format("%2s%3d", role, Math.round(getVsReplacement()));
  }

  private static Collection<NowValue> all(Context ctx, Player p) {
    return Arrays.stream(Tactic.values())
        .flatMap(t -> all(ctx, p, t).stream())
        .collect(Collectors.toList());
  }

  private static Collection<NowValue> all(Context ctx, Player p, Tactic t) {
    return Arrays.stream(Role.values())
        .map(r -> new NowValue(ctx, p, r, t))
        .collect(Collectors.toList());
  }

  public static NowValue best(Context ctx, Player p) {
    return Ordering.natural().onResultOf(NowValue::getScore).max(all(ctx, p));
  }

  public static NowValue bestVsReplacement(Context ctx, Player p) {
    return Ordering.natural().onResultOf(NowValue::getVsReplacement).max(all(ctx, p));
  }

  public static NowValue bestVsReplacement(Context ctx, Player p, Tactic t) {
    return Ordering.natural().onResultOf(NowValue::getVsReplacement).max(all(ctx, p, t));
  }
}

@@ -1753,56 +1753,16 @@
 urn 
-Ordering.natural().onResultOf(NowValue::get
+by
 Score
+(
 ).ma
@@ -1865,64 +1865,44 @@
 urn 
-Ordering.natural().onResultOf(NowValue::getVsReplacement
+byVsReplacement().compound(byScore()
 ).ma
@@ -2011,16 +2011,262 @@
  return 
+byVsReplacement().compound(byScore()).max(all(ctx, p, t));%0A  %7D%0A%0A  private static Ordering%3CNowValue%3E byScore() %7B%0A    return Ordering.natural().onResultOf(NowValue::getScore);%0A  %7D%0A%0A  private static Ordering%3CNowValue%3E byVsReplacement() %7B%0A    return 
 Ordering
@@ -2313,36 +2313,16 @@
 lacement
-).max(all(ctx, p, t)
 );%0A  %7D%0A%7D

Tweak selection of best NowValue