using Microsoft.CommandPalette.Extensions.Toolkit;

namespace Olive.Helpers;

internal sealed class SettingsManager : JsonSettingsManager
{
  private const string Namespace = "Olive";

  public SettingsManager()
  {
    FilePath = SettingsJsonPath();
    Settings.Add(_klipyApiKey);
    Settings.Add(_resultCount);
    Settings.Add(_closeAfterCopy);
    Settings.Add(_pasteAfterCopy);

    // Load settings from file upon initialization
    LoadSettings();

    Settings.SettingsChanged += (_, _) => { SaveSettings(); };
  }

  public string SettingsPath => FilePath;

  private readonly TextSetting _klipyApiKey = new(
    Namespaced(nameof(KlipyApiKey)),
    "Klipy API key",
    "Private key used to call the Klipy API. It stays stored locally in Olive settings.",
    string.Empty)
  {
    Placeholder = "Required",
    IsRequired = true,
    ErrorMessage = "Klipy API key is required."
  };

  private const int MinResultCount = 30;
  private const int MaxResultCount = 100;

  private readonly IntegerSetting _resultCount = new(
    Namespaced(nameof(ResultCount)),
    "Result count",
    "Number of GIF results to load for each search.",
    50,
    MinResultCount,
    MaxResultCount)
  {
    Placeholder = $"Min {MinResultCount}, max {MaxResultCount}",
    IsRequired = true,
    ErrorMessage = $"Enter a number between {MinResultCount} and {MaxResultCount}."
  };

  private readonly ToggleSetting _closeAfterCopy = new(
    Namespaced(nameof(CloseAfterCopy)),
    "Close after copy",
    "Automatically close Olive after copying a GIF.",
    true);

  private readonly ToggleSetting _pasteAfterCopy = new(
    Namespaced(nameof(PasteAfterCopy)),
    "Paste after copy",
    "After copying a GIF, send Ctrl+V.",
    false);

  public string KlipyApiKey
  {
    get
    {
      LoadSettings();
      return _klipyApiKey.Value ?? string.Empty;
    }
  }

  public bool HasKlipyApiKey => !string.IsNullOrWhiteSpace(KlipyApiKey);

  public int ResultCount
  {
    get
    {
      LoadSettings();
      return Math.Clamp(_resultCount.Value, 30, 100);
    }
  }

  public bool CloseAfterCopy
  {
    get
    {
      LoadSettings();
      return _closeAfterCopy.Value;
    }
  }

  public bool PasteAfterCopy
  {
    get
    {
      LoadSettings();
      return _pasteAfterCopy.Value;
    }
  }

  private static string SettingsJsonPath()
  {
    var directory = Utilities.BaseSettingsPath("Olive");
    Directory.CreateDirectory(directory);

    return Path.Combine(directory, "settings.json");
  }

  private static string Namespaced(string propertyName)
  {
    return $"{Namespace}.{propertyName}";
  }
}
