using System;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Dacryptero.Data;
using Dacryptero.DB;

namespace Dacryptero.Search.AST
{
    public class SortOption : OptionBase
    {
        public enum SortTarget
        {
            None,
            Score,
            Attribute,
            Field,
        }

        public enum SortDirection
        {
            Ascending,
            Descending,
        }

        public SortTarget Target { get; }

        public string? Name { get; }

        public SortDirection Direction { get; }

        protected override string Key => "sort";

        public SortOption(SortTarget target, string? name, SortDirection direction)
        {
            Target = target;
            Name = name;
            Direction = direction;
        }

        public override string ToString()
        {
            return $"{base.ToString()} {Target} {Name} {Direction}";
        }

        public override SearchProgress Check(SearchContext context)
        {
#if DEBUG
            throw new System.InvalidOperationException("This operation will not produce a meaningful result");
#else
            return new SearchProgress(1, new Collections.TreeCollection<ResultFound>());
#endif
        }

        public override bool Equals(object? obj)
        {
            return obj is SortOption option &&
                Target == option.Target &&
                Name == option.Name &&
                Direction == option.Direction;
        }

        public bool IsConflicting(SortOption other)
        {
            return Target == other.Target
                && Target != SortTarget.None
                && Name == other.Name
                && Direction != other.Direction;
        }

        public override int GetHashCode()
        {
            return HashCode.Combine(Target, Name, Direction);
        }

        public override Task<SearchIndex> GetSearchIndexAsync(DBSingleController db,
            IndexSource source, CancellationToken cancellationToken
        )
        {
            return Task.FromResult(SearchIndex.All);
        }

        public void WriteTo(Utf8JsonWriter writer)
        {
            writer.WriteStartObject();
            writer.WriteString("target", Target.ToString());
            writer.WriteString("name", Name);
            writer.WriteString("direction", Direction.ToString());
            writer.WriteEndObject();
        }
    }
}