using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using FitConnect.BaseClasses;
using FitConnect.Models;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;

namespace FitConnect;

public class Subscriber : FunctionalBaseClass {
    public Subscriber(FitConnectEndpoints endpoints,
        X509Certificate2? certificate = null, ILogger? logger = null) : base(logger, endpoints,
        certificate) {
    }


    /// <summary>
    ///     Returns the content of an embedded resource file.
    ///     <para>Implemented for the JSON schemas</para>
    /// </summary>
    /// <param name="filename">File name of the resource</param>
    /// <returns>Content of the resource file as string</returns>
    /// <exception cref="Exception"></exception>
    private async Task<string> GetContentFromEmbeddedResource(string filename) {
        var assembly = typeof(Subscriber).GetTypeInfo().Assembly;
        var resourceName = $"{assembly.GetName().Name}.{filename}";
        await using var stream = assembly.GetManifestResourceStream(resourceName);
        if (stream == null) throw new Exception($"Could not find embedded resource {resourceName}");

        using var reader = new StreamReader(stream);
        return await reader.ReadToEndAsync();
    }

    /// <summary>
    ///     Decrypt Data (Fachdaten)
    /// </summary>
    /// <param name="privateKey"></param>
    /// <param name="data">(Fachdaten)</param>
    /// <returns></returns>
    public async Task<string> DecryptToStringAsync(string privateKey, string data) {
        throw new NotImplementedException();
    }

    /// <summary>
    ///     Decrypt attachments (Anhänge)
    /// </summary>
    /// <param name="privateKey"></param>
    /// <param name="data">Encrypted attachments</param>
    /// <returns></returns>
    public async Task<byte[]> DecryptToBytesAsync(string privateKey, string data) {
        throw new NotImplementedException();
    }

    /// <summary>
    ///     Checks the validity of the given metadata against the schema.
    /// </summary>
    /// <param name="metaData">JSON meta data</param>
    /// <returns></returns>
    public async Task<bool> CheckMetadataAsync(string metaData) {
        var jsonScheme =
            JSchema.Parse(await GetContentFromEmbeddedResource("metadata.schema.json"));

        var meta = JObject.Parse(metaData);
        return meta.IsValid(jsonScheme);
    }


    /// <summary>
    ///     Check Hash from Metadata
    /// </summary>
    /// <param name="metaData">Metadata in JSON Format</param>
    /// <returns></returns>
    public async Task<bool> CheckHashAsync(string metaData, string hash) {
        throw new NotImplementedException();
    }


    /// <summary>
    ///     Create SecurityEventToken and signature
    /// </summary>
    /// <param name="data"></param>
    /// <param name="attachment"></param>
    /// <param name="privateKey"></param>
    /// <returns></returns>
    public async Task<SecurityEventToken> CreateSecurityEventTokenAsync(string data,
        string attachment, string privateKey) {
        throw new NotImplementedException();
    }

    /// <summary>
    ///     Get single submission from API
    /// </summary>
    /// <param name="id">The id of the submission</param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<Submission> GetSubmissionAsync(string id) {
        throw new NotImplementedException();
    }

    /// <summary>
    ///     Get available submissions from API
    /// </summary>
    /// <param name="destinationId"></param>
    /// <param name="offset"></param>
    /// <param name="limit"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<List<Submission>> GetSubmissionsAsync(string destinationId, int offset = 0,
        int limit = 100) {
        throw new NotImplementedException();
    }
}