using ScadaLink.Commons.Entities.Instances;
using ScadaLink.Commons.Entities.Scripts;
using ScadaLink.Commons.Entities.Templates;

namespace ScadaLink.Commons.Interfaces.Repositories;

public interface ITemplateEngineRepository
{
    // Template
    Task<Template?> GetTemplateByIdAsync(int id, CancellationToken cancellationToken = default);
    Task<Template?> GetTemplateWithChildrenAsync(int id, CancellationToken cancellationToken = default);
    Task<IReadOnlyList<Template>> GetAllTemplatesAsync(CancellationToken cancellationToken = default);
    /// <summary>
    /// Returns every template that contains a composition referencing
    /// <paramref name="composedTemplateId"/>. Each result is eager-loaded with
    /// its Attributes / Scripts / Compositions so the caller can build a
    /// CompositionContext without a follow-up round-trip per parent.
    /// </summary>
    Task<IReadOnlyList<Template>> GetTemplatesComposingAsync(int composedTemplateId, CancellationToken cancellationToken = default);
    Task AddTemplateAsync(Template template, CancellationToken cancellationToken = default);
    Task UpdateTemplateAsync(Template template, CancellationToken cancellationToken = default);
    Task DeleteTemplateAsync(int id, CancellationToken cancellationToken = default);

    // TemplateAttribute
    Task<TemplateAttribute?> GetTemplateAttributeByIdAsync(int id, CancellationToken cancellationToken = default);
    Task<IReadOnlyList<TemplateAttribute>> GetAttributesByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
    Task AddTemplateAttributeAsync(TemplateAttribute attribute, CancellationToken cancellationToken = default);
    Task UpdateTemplateAttributeAsync(TemplateAttribute attribute, CancellationToken cancellationToken = default);
    Task DeleteTemplateAttributeAsync(int id, CancellationToken cancellationToken = default);

    // TemplateAlarm
    Task<TemplateAlarm?> GetTemplateAlarmByIdAsync(int id, CancellationToken cancellationToken = default);
    Task<IReadOnlyList<TemplateAlarm>> GetAlarmsByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
    Task AddTemplateAlarmAsync(TemplateAlarm alarm, CancellationToken cancellationToken = default);
    Task UpdateTemplateAlarmAsync(TemplateAlarm alarm, CancellationToken cancellationToken = default);
    Task DeleteTemplateAlarmAsync(int id, CancellationToken cancellationToken = default);

    // TemplateScript
    Task<TemplateScript?> GetTemplateScriptByIdAsync(int id, CancellationToken cancellationToken = default);
    Task<IReadOnlyList<TemplateScript>> GetScriptsByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
    Task AddTemplateScriptAsync(TemplateScript script, CancellationToken cancellationToken = default);
    Task UpdateTemplateScriptAsync(TemplateScript script, CancellationToken cancellationToken = default);
    Task DeleteTemplateScriptAsync(int id, CancellationToken cancellationToken = default);

    // TemplateComposition
    Task<TemplateComposition?> GetTemplateCompositionByIdAsync(int id, CancellationToken cancellationToken = default);
    Task<IReadOnlyList<TemplateComposition>> GetCompositionsByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
    Task AddTemplateCompositionAsync(TemplateComposition composition, CancellationToken cancellationToken = default);
    Task UpdateTemplateCompositionAsync(TemplateComposition composition, CancellationToken cancellationToken = default);
    Task DeleteTemplateCompositionAsync(int id, CancellationToken cancellationToken = default);

    // Instance
    Task<Instance?> GetInstanceByIdAsync(int id, CancellationToken cancellationToken = default);
    Task<IReadOnlyList<Instance>> GetAllInstancesAsync(CancellationToken cancellationToken = default);
    Task<IReadOnlyList<Instance>> GetInstancesByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
    Task<IReadOnlyList<Instance>> GetInstancesBySiteIdAsync(int siteId, CancellationToken cancellationToken = default);
    Task<Instance?> GetInstanceByUniqueNameAsync(string uniqueName, CancellationToken cancellationToken = default);
    Task AddInstanceAsync(Instance instance, CancellationToken cancellationToken = default);
    Task UpdateInstanceAsync(Instance instance, CancellationToken cancellationToken = default);
    Task DeleteInstanceAsync(int id, CancellationToken cancellationToken = default);

    // InstanceAttributeOverride
    Task<IReadOnlyList<InstanceAttributeOverride>> GetOverridesByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default);
    Task AddInstanceAttributeOverrideAsync(InstanceAttributeOverride attributeOverride, CancellationToken cancellationToken = default);
    Task UpdateInstanceAttributeOverrideAsync(InstanceAttributeOverride attributeOverride, CancellationToken cancellationToken = default);
    Task DeleteInstanceAttributeOverrideAsync(int id, CancellationToken cancellationToken = default);

    // InstanceAlarmOverride
    Task<IReadOnlyList<InstanceAlarmOverride>> GetAlarmOverridesByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default);
    Task<InstanceAlarmOverride?> GetAlarmOverrideAsync(int instanceId, string alarmCanonicalName, CancellationToken cancellationToken = default);
    Task AddInstanceAlarmOverrideAsync(InstanceAlarmOverride alarmOverride, CancellationToken cancellationToken = default);
    Task UpdateInstanceAlarmOverrideAsync(InstanceAlarmOverride alarmOverride, CancellationToken cancellationToken = default);
    Task DeleteInstanceAlarmOverrideAsync(int id, CancellationToken cancellationToken = default);

    // InstanceConnectionBinding
    Task<IReadOnlyList<InstanceConnectionBinding>> GetBindingsByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default);
    Task AddInstanceConnectionBindingAsync(InstanceConnectionBinding binding, CancellationToken cancellationToken = default);
    Task UpdateInstanceConnectionBindingAsync(InstanceConnectionBinding binding, CancellationToken cancellationToken = default);
    Task DeleteInstanceConnectionBindingAsync(int id, CancellationToken cancellationToken = default);

    // Area
    Task<Area?> GetAreaByIdAsync(int id, CancellationToken cancellationToken = default);
    Task<IReadOnlyList<Area>> GetAreasBySiteIdAsync(int siteId, CancellationToken cancellationToken = default);
    Task AddAreaAsync(Area area, CancellationToken cancellationToken = default);
    Task UpdateAreaAsync(Area area, CancellationToken cancellationToken = default);
    Task DeleteAreaAsync(int id, CancellationToken cancellationToken = default);

    // SharedScript
    Task<SharedScript?> GetSharedScriptByIdAsync(int id, CancellationToken cancellationToken = default);
    Task<SharedScript?> GetSharedScriptByNameAsync(string name, CancellationToken cancellationToken = default);
    Task<IReadOnlyList<SharedScript>> GetAllSharedScriptsAsync(CancellationToken cancellationToken = default);
    Task AddSharedScriptAsync(SharedScript sharedScript, CancellationToken cancellationToken = default);
    Task UpdateSharedScriptAsync(SharedScript sharedScript, CancellationToken cancellationToken = default);
    Task DeleteSharedScriptAsync(int id, CancellationToken cancellationToken = default);

    // TemplateFolder
    Task<TemplateFolder?> GetFolderByIdAsync(int id, CancellationToken cancellationToken = default);
    Task<IReadOnlyList<TemplateFolder>> GetAllFoldersAsync(CancellationToken cancellationToken = default);
    Task AddFolderAsync(TemplateFolder folder, CancellationToken cancellationToken = default);
    Task UpdateFolderAsync(TemplateFolder folder, CancellationToken cancellationToken = default);
    Task DeleteFolderAsync(int id, CancellationToken cancellationToken = default);

    Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}
