using SQLite;

namespace Blahblah.FlowerApp.Data;

internal sealed class Constants
{
    public const string CategoryOther = "other";
    public const string EventUnknown = "unknown";

    public const string ApiVersionName = "api_version";
    public const string LastTokenName = "last_token";

    public const string BaseUrl = "https://app.blahblaho.com";
    public const string AppVersion = "0.3.802";
    public const string UserAgent = $"FlowerApp/{AppVersion}";

    public const SQLiteOpenFlags SQLiteFlags =
        SQLiteOpenFlags.ReadWrite |
        SQLiteOpenFlags.Create |
        SQLiteOpenFlags.SharedCache;

    const string dbFilename = "flowerstory.db3";
    public static string DatabasePath => Path.Combine(FileSystem.AppDataDirectory, dbFilename);

    static string? apiVersion;
    public static string? ApiVersion => apiVersion;

    static string? authorization;
    public static string? Authorization => authorization;

    public static void SetAuthorization(string auth)
    {
        authorization = auth;
    }

    public static async Task<Definitions?> Initialize(ILoggerContent logger, string? version, CancellationToken cancellation = default)
    {
        try
        {
            var v = await Extensions.FetchAsync<string>("api/version", cancellation);
            apiVersion = v;

            if (v != version)
            {
                var definition = await Extensions.FetchAsync<Definitions>($"api/consts?{v}", cancellation);
                return definition;
            }
        }
        catch (Exception ex)
        {
            logger.LogError(ex, $"error occurs on fetching version and definitions, {ex.Message}");
        }

        return null;
    }
}

internal record Definitions
{
    public required string ApiVersion { get; init; }

    public required Dictionary<int, NamedItem> Categories { get; init; }

    public required Dictionary<int, EventItem> Events { get; init; }
}

public record NamedItem(string Name, string? Description)
{
    public string Name { get; init; } = Name;

    public string? Description { get; init; } = Description;
}

public record EventItem(string Name, string? Description, bool Unique) : NamedItem(Name, Description)
{
    public bool Unique { get; init; } = Unique;
}