using System.Xml;

namespace Kit.Helpers.Repository
{
    public enum ContentTypes
    {
        Xml = 0,
        Sqlite = 1,
    }

    public interface IFileContent
    {
        ContentTypes Type { get; }
        object Content { get; }
    }

    public abstract class FileContent : IFileContent
    {
        public abstract ContentTypes Type { get; }
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
        public object Content { get; set; }
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
    }

    public class FileContentXml : FileContent
    {
        public override ContentTypes Type => ContentTypes.Xml;
        public FileContentXml(XmlDocument xmlDocument)
        {
            Content = xmlDocument;
        }
    }

    public class FileContentSqlite : FileContent
    {
        public override ContentTypes Type => ContentTypes.Sqlite;
        public IConnectionString ConnectionString => (IConnectionString)Content;
        public FileContentSqlite(IConnectionString connectionString)
        {
            Check.IsTrue(connectionString.Type.Equals(ConnectionStringType.SQLite), $"value ({nameof(connectionString)}.{nameof(connectionString.Type)} = {connectionString.Type.ToString()}) is invalid - {ConnectionStringType.SQLite.ToString()} was expected");
            Content = connectionString;
        }
    }

    public interface IContent<TContentKey>
    {
        public ContentTypes Type { get; }
        IFileContent GetContentDataDefault();
        IFileContent? GetContentData(TContentKey key);
        bool CreateContentData(TContentKey key, IFileContent content, bool skipIfExists = true);
        void UpdateContentData(TContentKey key, IFileContent content);
        int GetRowVersion(IFileContent document);
    }

    public abstract class ContentBase<TContentKey>
    {
        public abstract ContentTypes Type { get; }
        public void CheckFileContent(IFileContent content)
        {
            Check.IsTrue(content.Type.Equals(Type), $"value ({nameof(content)}.{nameof(content.Type)} = {content.Type.ToString()}) is invalid - {Type.ToString()} was expected");
        }
    }
}
