using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.Web;

using Blazored.LocalStorage;

using decePubClient.Models;
using decePubClient.Models.Types;
using decePubClient.Resources;
using decePubClient.Services;

using DnetIndexedDb;
using DnetIndexedDb.Fluent;
using DnetIndexedDb.Models;

using Markdig;

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Localization;

namespace decePubClient.Extensions;

public static class GenericExtensions
{
	public static IServiceCollection AddIndexedDb(this IServiceCollection services)
	{
		return services.AddIndexedDbDatabase<IndexedDb>(options =>
		{
			var model = new IndexedDbDatabaseModel()
				.WithName("data")
				.WithVersion(1)
				.WithModelId(1);

			model.AddStore(nameof(Message))
				.WithKey(nameof(Message.MessageId))
				.AddUniqueIndex(nameof(Message.MessageId))
				.AddIndex(nameof(Message.RootMessageId))
				.AddIndex(nameof(Message.User))
				.AddIndex(nameof(Message.MessageType))
				.AddIndex(nameof(Message.Title))
				.AddIndex(nameof(Message.Content))
				.AddIndex(nameof(Message.CreatedAt))
				.AddIndex(nameof(Message.Medias));

			options.UseDatabase(model);
		});
	}

	public static string GetPassedTime(this DateTime dateTime, IStringLocalizer localizer)
	{
		var timeframe = DateTime.Now - dateTime.ToLocalTime();
		switch ((int)timeframe.TotalHours)
		{
			case >= 24:
				return string.Format(localizer["{0}d"], (int)timeframe.TotalDays);
			case >= 1 and < 24:
				return string.Format(localizer["{0}h"], (int)timeframe.TotalHours);
			case 0:
				return string.Format(localizer["{0}m"], (int)timeframe.TotalMinutes);
			default:
				return default;
		}
	}

	public static string GetFileSize(this long size, IStringLocalizer<AllStrings> localizer)
	{
		switch (size)
		{
			case >= 1_048_576:
				return string.Format(localizer["{0:N0}MB"], size / 1_048_576);
			case < 1_048_576:
				return string.Format(localizer["{0}KB"], size / 1_024);
		}
	}

	public static string ParseContent(this string content, ContentType contentType)
	{
		switch (contentType)
		{
			case ContentType.PlainText:
				return content;
			case ContentType.HTML:
				return ((MarkupString)content).Value;
			case ContentType.Markdown:
				return Markdown.ToHtml(content);
			default:
				return default;
		}
	}

	public static string GetMessageTypeIcon(this MessageType messageType)
	{
		switch (messageType)
		{
			case MessageType.Public:
				return "ion-md-globe";
			case MessageType.Unlisted:
				return "ion-md-unlock";
			case MessageType.FollowersOnly:
				return "ion-md-lock";
			case MessageType.Direct:
				return "ion-md-paper-plane";
			default:
				return default;
		}
	}

	public static string GetTimelineTypeIcon(this TimelineType timelineType)
	{
		switch (timelineType)
		{
			case TimelineType.Home:
				return "ion-md-home";
			case TimelineType.Local:
				return "ion-md-people";
			case TimelineType.Federation:
				return "ion-md-globe";
			default:
				return default;
		}
	}

	public static string GetContentTypeIcon(this ContentType contentType)
	{
		switch (contentType)
		{
			case ContentType.PlainText:
				return "ion-md-quote";
			case ContentType.HTML:
				return "ion-logo-html5";
			case ContentType.Markdown:
				return "ion-logo-markdown";
			default:
				return default;
		}
	}

	public static string GetMediaTypeIcon(this MediaType mediaType)
	{
		switch (mediaType)
		{
			case MediaType.Images:
				return "ion-md-images";
			case MediaType.Video:
				return "ion-md-videocam";
			case MediaType.Documents:
				return "ion-md-document";
			case MediaType.Audio:
				return "ion-md-volume-high";
			default:
				return default;
		}
	}
}