using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Dacryptero.Search;
using LiteDB;

namespace Dacryptero.Data
{
    public class File : Base, ISearchable
    {
        public bool Deleted { get; set; }

        public string Name { get; set; } = "";

        public string Mime { get; set; } = "";

        public ObjectId? ParentId { get; set; }

        [BsonRef("person")]
        public Person Person { get; set; } = new Person();

        [BsonIgnore]
        public bool Confidential { get; set; }

        [BsonIgnore]
        public SearchResultType ResultType => SearchResultType.File;

        [BsonRef("file_entry")]
        public List<FileEntry> Entries { get; set; } = new List<FileEntry>();

        public IEnumerable<SearchPart> GetSearchParts()
        {
            yield return new SearchPart(FoundType.Field, "created", new BsonValue(Created));
            yield return new SearchPart(FoundType.Field, "modified", new BsonValue(Modified));
            yield return new SearchPart(FoundType.Field, "deleted", new BsonValue(Deleted));
            yield return new SearchPart(FoundType.Field, "name", new BsonValue(Name));
            yield return new SearchPart(FoundType.Field, "mime", new BsonValue(Mime));
        }

        public List<(string name, string value)> GetInfo()
        {
            return new List<(string name, string value)>();
        }

        public string GetName() => Name;

        public string? GetRole() => null;

        public void WriteTo(Utf8JsonWriter writer, DB.DBSingleController db, bool embeded = false)
        {
            if (!embeded)
                writer.WriteStartObject();
            writer.WriteString("id", Id.ToString());
            writer.WriteString("database", db.Config.Name);
            writer.WriteString("created", Created);
            writer.WriteString("modified", Modified);
            writer.WriteBoolean("deleted", Deleted);
            writer.WriteString("person", Person.Id.ToString());
            writer.WriteString("parent", ParentId?.ToString());
            writer.WriteString("name", Name);
            writer.WriteString("mime", Mime);
            writer.WriteBoolean("confidential", Confidential);
            writer.WriteStartArray("entries");
            foreach (var entry in Entries)
                entry.WriteTo(writer, db.Config);
            writer.WriteEndArray();
            var newests = Entries.OrderByDescending(x => x.Date).FirstOrDefault();
            if (newests is not null)
            {
                writer.WritePropertyName("entry");
                newests.WriteTo(writer, db.Config);
            }
            else writer.WriteNull("entry");
            if (!embeded)
                writer.WriteEndObject();
        }
    }
}