using NpgsqlTypes;
using XF.Domain.Entities;
using XF.Domain.Repository;

namespace Hotline.Repository.SqlSugar.TextSearch;

public interface IRepositoryTextSearch<TEntity>
    where TEntity : class, IEntity<string>, ITextSearch, new()
{
    /// <summary>
    /// 全都采用默认权重
    /// </summary>
    /// <param name="id">原始数据Id</param>
    /// <param name="creationTime">原始数据CreationTime</param>
    /// <param name="texts"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task AddVectorAsync(string id, DateTime creationTime, ICollection<string> texts, CancellationToken cancellationToken);

    /// <summary>
    /// 自定义权重
    /// </summary>
    /// <param name="id">原始数据Id</param>
    /// <param name="creationTime">原始数据CreationTime</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task AddVectorAsync(string id, DateTime creationTime, ICollection<NpgsqlWeight> weights, CancellationToken cancellationToken);

    /// <summary>
    /// 全都采用默认权重
    /// </summary>
    Task UpdateVectorAsync(string id, ICollection<string> texts, CancellationToken cancellationToken);

    /// <summary>
    /// 自定义权重
    /// </summary>
    Task UpdateVectorAsync(string id, ICollection<NpgsqlWeight> weights, CancellationToken cancellationToken);

    Task<List<RankedResult<TEntity>>> SearchAsync(IReadOnlyList<string> texts, CancellationToken cancellationToken);
}

public class RankedResult<TEntity>
{
    public double Score { get; set; }

    public TEntity Entity { get; set; }
}

public class NpgsqlWeight
{
    public string Text { get; set; }

    public string Weight { get; set; } = NpgsqlLexemeWeight.C;
}

public sealed class NpgsqlLexemeWeight
{
    public const string A = "A";
    public const string B = "B";
    public const string C = "C";
    public const string D = "D";
    public const string E = "E";

    public static IReadOnlyList<KeyValuePair<string, string>> All() =>
        new List<KeyValuePair<string, string>>
        {
            new(A,"最高优先级"),
            new(B,"较高优先级"),
            new(C,"默认优先级"),
            new(D,"较低优先级"),
            new(E,"最低优先级"),
        };
}
