UI/Hud/Hud.razor
@using System.Threading.Tasks;
@using Milaine.Managers;
@using Milaine.Settings;
@using Milaine.UI;
@using Milaine.Utils;
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent
@namespace Sandbox

<root>
  <header class="header">
    <section class="day-manager">
      <h2>
        @TranslationsInstance.T("milaine.days", data)
        @* @Language.GetPhrase("milaine.days", data) *@
      </h2>
    </section>
    <section class="clock">
      <p>@DayNightManagerInstance.CurrentTimeString</p>
    </section>
  </header>
  <section class="progress-end-game">
    <div class="progress-bar">
      <div class="bar" style="width: @(GetPercentage())%;" />
      <p>@Formatter.ToDisplay(InvestmentManagerInstance.Total) / @Formatter.ToDisplay(IdleManagerInstance.Goal)</p>
    </div>
  </section>
  <button class="slot" style="pointer-events: @(!isPanelOpened ? "all" : "none");" onclick=@TogglePanel>
    <p class="kbd">E</p>
    <p class="title">
      @TranslationsInstance.T("milaine.tree-skills")
      @* #milaine.tree-skills *@
    </p>
  </button>
  <div class="container">
    <section class="content">
      <Image src="resources/wallet-minimal.png" class="image" style="width: 40px; height: 40px;" />
      <p class="headline">[email protected](Dollars)</p>
      <FloatingTextManager />
    </section>
  </div>
  @if (isInitializedDay) {
    <div class="day-container">
      <h2 class="heading-current-day">
        @* @Language.GetPhrase("milaine.days", data) *@
        @TranslationsInstance.T("milaine.days", data)
      </h2>
    </div>
  }
  @if (isGameWin) {
    <div
      style="background-color: black; position: absolute; top: 0; left: 0; right: 0; bottom: 0; justify-content: center; align-items: center;">
      <div style="width: 30%;justify-content:center;align-items:center;">
        <p style="font-size: 40px; font-family: 'JetBrains Mono';">
          @* #milaine.wingame *@
          @TranslationsInstance.T("milaine.wingame")
        </p>
      </div>
    </div>
  }

  @if (isDayEnd && !isGameWin) {
    <div class="day-container night">
      <div class="summary-container">
        <header class="summary-header">
          <div class="summary-title">
            <span class="circle" />
            <h2 class="normal-font">
              @* #milaine.summary.title *@
              @TranslationsInstance.T("milaine.summary.title")
            </h2>
          </div>
          <div class="separator" />
        </header>
        <div class="row">
          <div class="form-control nth mblue">
            <div class="form-control-header">
              <h3 class="normal-font">
                @* #milaine.summary.investment *@
                @TranslationsInstance.T("milaine.summary.investment")
              </h3>
              <span class="circle-base circle-blue" />
            </div>
            <p class="number">
              [email protected](InvestmentManagerInstance.Profit)
            </p>
          </div>
          <div class="form-control nth mgreen">
            <div class="form-control-header">
              <h3 class="normal-font">
                @* #milaine.summary.wallet *@
                @TranslationsInstance.T("milaine.summary.wallet")
              </h3>
              <span class="circle-base circle-green" />
            </div>
            <p class="number">
              [email protected](InvestmentManagerInstance.WalletPasive)
            </p>
          </div>
          <div class="form-control nth mred">
            <div class="form-control-header">
              <h3 class="normal-font">
                @* #milaine.summary.dollar-spent *@
                @TranslationsInstance.T("milaine.summary.dollar-spent")
              </h3>
              <span class="circle-base circle-red" />
            </div>
            <p class="number">
              [email protected](IdleManagerInstance.DollarsSpent)
            </p>
          </div>
        </div>
        <div class="separator" />

        @if (DayNightManagerInstance.Day == DayNightManager.MAX_DAYS) {
          <button class="btn-next-action normal-font" onclick=@HandleAgain>
            @* #milaine.back-to-past *@
            @TranslationsInstance.T("milaine.back-to-past")
          </button>
        } else {
          <button class="btn-next-action normal-font" onclick=@HandleNextDay>
            @* #milaine.next-day *@
            @TranslationsInstance.T("milaine.next-day")
          </button>
        }
      </div>
    </div>
  }
  <div class="version-manager">
    <p>@("v" + VersionManagerInstance.Version.ToString())</p>
  </div>
</root>

@code
{
  private const float ANIMATION_DURATION = 5f;

  [Property, Title("Translations")]
  [Feature("Managers")]
  public Translations TranslationsInstance { get; set; }

  [Property, Title("VersionManager")]
  [Feature("Managers")]
  public VersionManager VersionManagerInstance { get; set; }

  [Property, Title("IdleManager")]
  [Feature("Managers")]
  public IdleManager IdleManagerInstance { get; set; }

  [Property, Title("InvestmentManager")]
  [Feature("Managers")]
  public InvestmentManager InvestmentManagerInstance { get; set; }

  [Property, Title("DayNightManager")]
  [Feature("Managers")]
  public DayNightManager DayNightManagerInstance { get; set; }

  [Property, Title("GameManager")]
  [Feature("Managers")]
  public GameManager GameManagerInstance { get; set; }

  [Property, Title("TreeSkillPanel")]
  [Feature("General")]
  public TreeSkillPanel TreeSkillPanelInstance { get; set; }

  [Property]
  [Feature("General")]
  public int Dollars { get; set; } = 0;

  private bool isPanelOpened = false;

  private Dictionary<string, object> data = [];

  private bool isInitializedDay = false;
  private bool isDayEnd = false;

  private bool isGameWin = false;

  protected override int BuildHash() => System.HashCode.Combine(Dollars,
DayNightManagerInstance.CurrentTimeString, DayNightManagerInstance.Day, InvestmentManagerInstance.Total
, IdleManagerInstance.DollarsSpent, InvestmentManagerInstance.WalletPasive, InvestmentManagerInstance.Profit);

  protected override void OnAwake() {
    base.OnStart();

    data["Day"] = DayNightManagerInstance.Day;
    IdleManagerInstance.OnDeposit += RefreshDeposit;
    IdleManagerInstance.OnChange += Refresh;
    DayNightManagerInstance.OnStartDay += StartDay;
    DayNightManagerInstance.OnEndDay += EndDay;
    GameManagerInstance.OnWinGame += OnWinGame;
  }

  protected override void OnUpdate() {
    if (Input.Pressed("use")) {
      TogglePanel();
      return;
    }

    if (Input.EscapePressed) {
      isPanelOpened = false;
      StateHasChanged();
      TreeSkillPanelInstance.Close();
    }
  }

  protected override void OnDestroy() {
    base.OnDestroy();

    IdleManagerInstance.OnDeposit -= RefreshDeposit;
    IdleManagerInstance.OnChange -= Refresh;
    DayNightManagerInstance.OnStartDay -= StartDay;
    DayNightManagerInstance.OnEndDay -= EndDay;
    GameManagerInstance.OnWinGame -= OnWinGame;

  }

  private void OnWinGame() {
    isGameWin = GameManagerInstance.IsGameWin;
  }

  private void TogglePanel() {
    isPanelOpened = !isPanelOpened;
    StateHasChanged();

    Panel.Blur();

    if (isPanelOpened) {
      TreeSkillPanelInstance.Open();
      return;
    }

    TreeSkillPanelInstance.Close();
  }

  private string GetPercentage() {
    float Total = InvestmentManagerInstance.Total;
    float percentage = (Total / IdleManagerInstance.Goal) * 100;

    return Pixel.Inv(percentage);
  }

  private void StartDay() {
    isInitializedDay = true;
    StateHasChanged();

    _ = HideAafterDelay();
  }

  private void EndDay() {
    isDayEnd = true;
    StateHasChanged();
  }

  private void HandleNextDay() {
    isDayEnd = false;
    DayNightManagerInstance.NextDay();
    data["Day"] = DayNightManagerInstance.Day;
    StateHasChanged();
    StartDay();
  }

  private async Task HideAafterDelay() {
    await Task.DelaySeconds(ANIMATION_DURATION);
    isInitializedDay = false;
    StateHasChanged();
  }

  private void Refresh(int dollars, int amount) {
    Dollars = dollars;
    FloatingTextManager.Instance.Spawn($"+{amount}", 25f, 10f);
  }

  private void RefreshDeposit() {
    Dollars = 0;
  }

  private void HandleAgain() {
    GameManagerInstance.Restart();
  }
}