using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Iceshrimp.Backend.Core.Configuration;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Iceshrimp.Backend.Core.Database.Tables;

[Table("emoji")]
[Index(nameof(Host))]
[Index(nameof(Name))]
public class Emoji
{
	[Key]
	[Column("id")]
	[StringLength(32)]
	public string Id { get; set; } = null!;

	[Column("updatedAt")] public DateTime? UpdatedAt { get; set; }

	[Column("name")] [StringLength(128)] public string Name { get; set; } = null!;

	[Column("host")] [StringLength(512)] public string? Host { get; set; }

	[Column("originalUrl")]
	[StringLength(512)]
	public string OriginalUrl { get; set; } = null!;

	[Column("uri")] [StringLength(512)] public string? Uri { get; set; }

	[Column("type")] [StringLength(64)] public string? Type { get; set; }

	[Column("tags", TypeName = "character varying(128)[]")]
	public List<string> Tags { get; set; } = [];

	[Column("category")]
	[StringLength(128)]
	public string? Category { get; set; }

	[Column("publicUrl")]
	[StringLength(512)]
	public string RawPublicUrl { get; set; } = null!;

	[Column("license")]
	[StringLength(1024)]
	public string? License { get; set; }

	/// <summary>
	///     Image width
	/// </summary>
	[Column("width")]
	public int? Width { get; set; }

	/// <summary>
	///     Image height
	/// </summary>
	[Column("height")]
	public int? Height { get; set; }

	[Column("sensitive")]
	public bool Sensitive { get; set; }

	public string GetPublicUri(Config.InstanceSection config) => Host == null
		? $"https://{config.WebDomain}/emoji/{Name}"
		: throw new Exception("Cannot access PublicUri for remote emoji");

	public string? GetPublicUriOrNull(Config.InstanceSection config) => Host == null
		? $"https://{config.WebDomain}/emoji/{Name}"
		: null;
	
	public string GetAccessUrl(Config.InstanceSection config)
		=> $"https://{config.WebDomain}/media/emoji/{Id}";

	private class EntityTypeConfiguration : IEntityTypeConfiguration<Emoji>
	{
		public void Configure(EntityTypeBuilder<Emoji> entity)
		{
			entity.Property(e => e.Tags).HasDefaultValueSql("'{}'::character varying[]");
			entity.Property(e => e.Height).HasComment("Image height");
			entity.Property(e => e.RawPublicUrl).HasDefaultValueSql("''::character varying");
			entity.Property(e => e.Width).HasComment("Image width");

			entity.HasIndex(e => e.Name, "GIN_TRGM_emoji_name")
			      .HasMethod("gin")
			      .HasOperators("gin_trgm_ops");
			entity.HasIndex(e => e.Host, "GIN_TRGM_emoji_host")
			      .HasMethod("gin")
			      .HasOperators("gin_trgm_ops");

			// This index must be NULLS NOT DISTINCT to make having multiple local emoji with the same name cause a constraint failure
			entity.HasIndex(nameof(Name), nameof(Host)).IsUnique().AreNullsDistinct(false);
		}
	}
}