using FitConnect.Models;

namespace FitConnect;

public class EncryptedSubmissionBuilder : IEncryptedBuilderWithData,
    IEncryptedBuilderWithMetadata, IEncryptedBuilderWithAttachments,
    IEncryptedBuilderWithDestination, IEncryptedBuilderWithService {
    private Uri? SchemaUri { get; set; }

    private readonly SendableEncryptedSubmission _submission;

    internal EncryptedSubmissionBuilder() {
        _submission = new SendableEncryptedSubmission();
    }


    public SendableEncryptedSubmission Build() {
        _submission.SchemaUri = SchemaUri;
        return _submission;
    }


    public IEncryptedBuilderWithAttachments AddEncryptedAttachments(
        params EncryptedAttachment[] attachments) {
        _submission.Attachments ??= new Dictionary<Guid, string>();

        foreach (var attachment in attachments) {
            var (id, data) = attachment.Deconstruct();
            _submission.Attachments.Add(id, data);
        }

        return this;
    }

    public IEncryptedBuilderWithService
        SetServiceType(string serviceIdentifier, string serviceName) {
        _submission.ServiceName = serviceName;
        _submission.ServiceIdentifier = serviceIdentifier;
        return this;
    }

    public IEncryptedBuilderWithData SetEncryptedData(string data) {
        _submission.Data = data;
        return this;
    }


    public IEncryptedBuilderWithMetadata SetEncryptedMetadata(string metadata) {
        _submission.Metadata = metadata;
        return this;
    }

    public IEncryptedBuilderWithDestination SetDestination(Guid destinationId) {
        _submission.DestinationId = destinationId;
        return this;
    }
}

public interface IEncryptedBuilderWithDestination {
    IEncryptedBuilderWithService SetServiceType(string serviceIdentifier, string serviceName);
}

public interface IEncryptedBuilderWithService {
    IEncryptedBuilderWithMetadata SetEncryptedMetadata(string metadata);
}

public interface IEncryptedBuilderWithMetadata {
    IEncryptedBuilderWithData SetEncryptedData(string data);
}

public interface IEncryptedBuilderWithData {
    IEncryptedBuilderWithAttachments AddEncryptedAttachments(
        params EncryptedAttachment[] attachments);
}

public interface IEncryptedBuilderWithAttachments {
    SendableEncryptedSubmission Build();
}