using ZB.MOM.WW.ScadaBridge.Commons.Entities.Instances;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Scripts;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Templates;

namespace ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;

public interface ITemplateEngineRepository
{
    // Template
    /// <summary>Retrieves a template by ID.</summary>
    /// <param name="id">The template ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching template, or <see langword="null"/> if not found.</returns>
    Task<Template?> GetTemplateByIdAsync(int id, CancellationToken cancellationToken = default);
    /// <summary>Retrieves a template with its child entities by ID.</summary>
    /// <param name="id">The template ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching template with children loaded, or <see langword="null"/> if not found.</returns>
    Task<Template?> GetTemplateWithChildrenAsync(int id, CancellationToken cancellationToken = default);
    /// <summary>
    /// Bulk variant of <see cref="GetTemplateWithChildrenAsync(int, CancellationToken)"/>
    /// that fetches every template whose <see cref="Template.Name"/> matches one of
    /// <paramref name="names"/> in a single SQL/EF query, eager-loading
    /// Attributes / Alarms / Scripts / Compositions. Resolves the N+1
    /// in <c>BundleImporter.PreviewAsync</c> — names that don't match an
    /// existing template are omitted from the result rather than producing a
    /// null entry, so callers should look up by name into the returned list.
    /// </summary>
    /// <param name="names">Template names to load. Duplicate / null / empty names are filtered out.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of matched templates with children loaded.</returns>
    Task<IReadOnlyList<Template>> GetTemplatesWithChildrenAsync(IEnumerable<string> names, CancellationToken cancellationToken = default);
    /// <summary>Retrieves all templates.</summary>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of all templates.</returns>
    Task<IReadOnlyList<Template>> GetAllTemplatesAsync(CancellationToken cancellationToken = default);
    /// <summary>
    /// Read-only, no-tracking variant of <see cref="GetAllTemplatesAsync"/> for the
    /// design-time ANALYSIS walks — acyclicity (<c>CycleDetector</c>), naming
    /// collisions (<c>CollisionDetector</c>) and canonical-name resolution
    /// (<c>TemplateResolver</c>). Script bodies are NOT loaded
    /// (<see cref="TemplateScript.Code"/> comes back empty) because no analysis
    /// consumer reads them; everything those walks do read — ids, parent and
    /// composition edges, member names and lock flags — is present.
    ///
    /// <para>
    /// Do NOT use this for the inheritance reconciler or the flattener: the
    /// reconciler compares and copies script bodies and writes through tracked
    /// entities, and the flattener must observe rows an in-flight bundle import
    /// has staged on the shared change tracker. Both keep using
    /// <see cref="GetAllTemplatesAsync"/> / <see cref="GetTemplateWithChildrenAsync"/>.
    /// </para>
    /// </summary>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of all templates without script bodies.</returns>
    Task<IReadOnlyList<Template>> GetAllTemplatesForAnalysisAsync(CancellationToken cancellationToken = default);
    /// <summary>
    /// Database-side paged listing of templates as row summaries (child
    /// collections reduced to counts, no script bodies). Backs the
    /// <c>ListTemplates</c> management command, which previously materialised
    /// every template's full child graph and then paged the list in memory.
    /// </summary>
    /// <param name="skip">Number of rows to skip; negative values are floored at 0.</param>
    /// <param name="take">
    /// Page size. <see langword="null"/> or non-positive returns every remaining
    /// row (the historical unpaged behaviour); otherwise clamped to
    /// <see cref="Types.Templates.TemplateSummary.MaxPageSize"/>.
    /// </param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to one page of template summaries, ordered by id.</returns>
    Task<IReadOnlyList<Types.Templates.TemplateSummary>> GetTemplateSummariesAsync(int skip, int? take, 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>
    /// <param name="composedTemplateId">The composed template ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of parent templates that reference the composed template.</returns>
    Task<IReadOnlyList<Template>> GetTemplatesComposingAsync(int composedTemplateId, CancellationToken cancellationToken = default);
    /// <summary>Adds a new template.</summary>
    /// <param name="template">The template to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddTemplateAsync(Template template, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing template.</summary>
    /// <param name="template">The template to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateTemplateAsync(Template template, CancellationToken cancellationToken = default);
    /// <summary>Deletes a template by ID.</summary>
    /// <param name="id">The template ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteTemplateAsync(int id, CancellationToken cancellationToken = default);

    // TemplateAttribute
    /// <summary>Retrieves a template attribute by ID.</summary>
    /// <param name="id">The attribute ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching attribute, or <see langword="null"/> if not found.</returns>
    Task<TemplateAttribute?> GetTemplateAttributeByIdAsync(int id, CancellationToken cancellationToken = default);
    /// <summary>Retrieves attributes for a template.</summary>
    /// <param name="templateId">The template ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of attributes for the specified template.</returns>
    Task<IReadOnlyList<TemplateAttribute>> GetAttributesByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
    /// <summary>Adds a new template attribute.</summary>
    /// <param name="attribute">The attribute to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddTemplateAttributeAsync(TemplateAttribute attribute, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing template attribute.</summary>
    /// <param name="attribute">The attribute to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateTemplateAttributeAsync(TemplateAttribute attribute, CancellationToken cancellationToken = default);
    /// <summary>Deletes a template attribute by ID.</summary>
    /// <param name="id">The attribute ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteTemplateAttributeAsync(int id, CancellationToken cancellationToken = default);

    // TemplateAlarm
    /// <summary>Retrieves a template alarm by ID.</summary>
    /// <param name="id">The alarm ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching alarm, or <see langword="null"/> if not found.</returns>
    Task<TemplateAlarm?> GetTemplateAlarmByIdAsync(int id, CancellationToken cancellationToken = default);
    /// <summary>Retrieves alarms for a template.</summary>
    /// <param name="templateId">The template ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of alarms for the specified template.</returns>
    Task<IReadOnlyList<TemplateAlarm>> GetAlarmsByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
    /// <summary>Adds a new template alarm.</summary>
    /// <param name="alarm">The alarm to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddTemplateAlarmAsync(TemplateAlarm alarm, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing template alarm.</summary>
    /// <param name="alarm">The alarm to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateTemplateAlarmAsync(TemplateAlarm alarm, CancellationToken cancellationToken = default);
    /// <summary>Deletes a template alarm by ID.</summary>
    /// <param name="id">The alarm ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteTemplateAlarmAsync(int id, CancellationToken cancellationToken = default);

    // TemplateNativeAlarmSource
    /// <summary>Retrieves a template native alarm source by ID.</summary>
    /// <param name="id">The native alarm source ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching native alarm source, or <see langword="null"/> if not found.</returns>
    Task<TemplateNativeAlarmSource?> GetTemplateNativeAlarmSourceByIdAsync(int id, CancellationToken cancellationToken = default);
    /// <summary>Retrieves native alarm sources for a template.</summary>
    /// <param name="templateId">The template ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of native alarm sources for the specified template.</returns>
    Task<IReadOnlyList<TemplateNativeAlarmSource>> GetNativeAlarmSourcesByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
    /// <summary>Adds a new template native alarm source.</summary>
    /// <param name="source">The native alarm source to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddTemplateNativeAlarmSourceAsync(TemplateNativeAlarmSource source, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing template native alarm source.</summary>
    /// <param name="source">The native alarm source to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateTemplateNativeAlarmSourceAsync(TemplateNativeAlarmSource source, CancellationToken cancellationToken = default);
    /// <summary>Deletes a template native alarm source by ID.</summary>
    /// <param name="id">The native alarm source ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteTemplateNativeAlarmSourceAsync(int id, CancellationToken cancellationToken = default);

    // TemplateScript
    /// <summary>Retrieves a template script by ID.</summary>
    /// <param name="id">The script ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching script, or <see langword="null"/> if not found.</returns>
    Task<TemplateScript?> GetTemplateScriptByIdAsync(int id, CancellationToken cancellationToken = default);
    /// <summary>Retrieves scripts for a template.</summary>
    /// <param name="templateId">The template ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of scripts for the specified template.</returns>
    Task<IReadOnlyList<TemplateScript>> GetScriptsByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
    /// <summary>Adds a new template script.</summary>
    /// <param name="script">The script to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddTemplateScriptAsync(TemplateScript script, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing template script.</summary>
    /// <param name="script">The script to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateTemplateScriptAsync(TemplateScript script, CancellationToken cancellationToken = default);
    /// <summary>Deletes a template script by ID.</summary>
    /// <param name="id">The script ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteTemplateScriptAsync(int id, CancellationToken cancellationToken = default);

    // TemplateComposition
    /// <summary>Retrieves a template composition by ID.</summary>
    /// <param name="id">The composition ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching composition, or <see langword="null"/> if not found.</returns>
    Task<TemplateComposition?> GetTemplateCompositionByIdAsync(int id, CancellationToken cancellationToken = default);
    /// <summary>Retrieves compositions for a template.</summary>
    /// <param name="templateId">The template ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of compositions for the specified template.</returns>
    Task<IReadOnlyList<TemplateComposition>> GetCompositionsByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
    /// <summary>Adds a new template composition.</summary>
    /// <param name="composition">The composition to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddTemplateCompositionAsync(TemplateComposition composition, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing template composition.</summary>
    /// <param name="composition">The composition to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateTemplateCompositionAsync(TemplateComposition composition, CancellationToken cancellationToken = default);
    /// <summary>Deletes a template composition by ID.</summary>
    /// <param name="id">The composition ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteTemplateCompositionAsync(int id, CancellationToken cancellationToken = default);

    // Instance
    /// <summary>Retrieves an instance by ID.</summary>
    /// <param name="id">The instance ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching instance, or <see langword="null"/> if not found.</returns>
    Task<Instance?> GetInstanceByIdAsync(int id, CancellationToken cancellationToken = default);
    /// <summary>Retrieves all instances.</summary>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of all instances.</returns>
    Task<IReadOnlyList<Instance>> GetAllInstancesAsync(CancellationToken cancellationToken = default);
    /// <summary>Retrieves instances for a template.</summary>
    /// <param name="templateId">The template ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of instances for the specified template.</returns>
    Task<IReadOnlyList<Instance>> GetInstancesByTemplateIdAsync(int templateId, CancellationToken cancellationToken = default);
    /// <summary>Retrieves instances for a site.</summary>
    /// <param name="siteId">The site ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of instances for the specified site.</returns>
    Task<IReadOnlyList<Instance>> GetInstancesBySiteIdAsync(int siteId, CancellationToken cancellationToken = default);
    /// <summary>Retrieves an instance by unique name.</summary>
    /// <param name="uniqueName">The unique instance name.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching instance, or <see langword="null"/> if not found.</returns>
    Task<Instance?> GetInstanceByUniqueNameAsync(string uniqueName, CancellationToken cancellationToken = default);
    /// <summary>Adds a new instance.</summary>
    /// <param name="instance">The instance to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddInstanceAsync(Instance instance, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing instance.</summary>
    /// <param name="instance">The instance to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateInstanceAsync(Instance instance, CancellationToken cancellationToken = default);
    /// <summary>Deletes an instance by ID.</summary>
    /// <param name="id">The instance ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteInstanceAsync(int id, CancellationToken cancellationToken = default);

    // InstanceAttributeOverride
    /// <summary>Retrieves attribute overrides for an instance.</summary>
    /// <param name="instanceId">The instance ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of attribute overrides for the specified instance.</returns>
    Task<IReadOnlyList<InstanceAttributeOverride>> GetOverridesByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default);
    /// <summary>Adds a new instance attribute override.</summary>
    /// <param name="attributeOverride">The override to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddInstanceAttributeOverrideAsync(InstanceAttributeOverride attributeOverride, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing instance attribute override.</summary>
    /// <param name="attributeOverride">The override to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateInstanceAttributeOverrideAsync(InstanceAttributeOverride attributeOverride, CancellationToken cancellationToken = default);
    /// <summary>Deletes an instance attribute override by ID.</summary>
    /// <param name="id">The override ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteInstanceAttributeOverrideAsync(int id, CancellationToken cancellationToken = default);

    // InstanceAlarmOverride
    /// <summary>Retrieves alarm overrides for an instance.</summary>
    /// <param name="instanceId">The instance ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of alarm overrides for the specified instance.</returns>
    Task<IReadOnlyList<InstanceAlarmOverride>> GetAlarmOverridesByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default);
    /// <summary>Retrieves an alarm override by instance and alarm name.</summary>
    /// <param name="instanceId">The instance ID.</param>
    /// <param name="alarmCanonicalName">The alarm canonical name.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching alarm override, or <see langword="null"/> if not found.</returns>
    Task<InstanceAlarmOverride?> GetAlarmOverrideAsync(int instanceId, string alarmCanonicalName, CancellationToken cancellationToken = default);
    /// <summary>Adds a new instance alarm override.</summary>
    /// <param name="alarmOverride">The override to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddInstanceAlarmOverrideAsync(InstanceAlarmOverride alarmOverride, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing instance alarm override.</summary>
    /// <param name="alarmOverride">The override to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateInstanceAlarmOverrideAsync(InstanceAlarmOverride alarmOverride, CancellationToken cancellationToken = default);
    /// <summary>Deletes an instance alarm override by ID.</summary>
    /// <param name="id">The override ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteInstanceAlarmOverrideAsync(int id, CancellationToken cancellationToken = default);

    // InstanceNativeAlarmSourceOverride
    /// <summary>Retrieves native alarm source overrides for an instance.</summary>
    /// <param name="instanceId">The instance ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of native alarm source overrides for the specified instance.</returns>
    Task<IReadOnlyList<InstanceNativeAlarmSourceOverride>> GetNativeAlarmSourceOverridesByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default);
    /// <summary>Retrieves a single native alarm source override by instance + source canonical name.</summary>
    /// <param name="instanceId">The instance ID.</param>
    /// <param name="sourceCanonicalName">The canonical name of the native alarm source.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching override, or <see langword="null"/> if not found.</returns>
    Task<InstanceNativeAlarmSourceOverride?> GetNativeAlarmSourceOverrideAsync(int instanceId, string sourceCanonicalName, CancellationToken cancellationToken = default);
    /// <summary>Adds a new instance native alarm source override.</summary>
    /// <param name="ovr">The override to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddInstanceNativeAlarmSourceOverrideAsync(InstanceNativeAlarmSourceOverride ovr, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing instance native alarm source override.</summary>
    /// <param name="ovr">The override to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateInstanceNativeAlarmSourceOverrideAsync(InstanceNativeAlarmSourceOverride ovr, CancellationToken cancellationToken = default);
    /// <summary>Deletes an instance native alarm source override by ID.</summary>
    /// <param name="id">The override ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteInstanceNativeAlarmSourceOverrideAsync(int id, CancellationToken cancellationToken = default);

    // InstanceConnectionBinding
    /// <summary>Retrieves connection bindings for an instance.</summary>
    /// <param name="instanceId">The instance ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of connection bindings for the specified instance.</returns>
    Task<IReadOnlyList<InstanceConnectionBinding>> GetBindingsByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default);
    /// <summary>Adds a new instance connection binding.</summary>
    /// <param name="binding">The binding to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddInstanceConnectionBindingAsync(InstanceConnectionBinding binding, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing instance connection binding.</summary>
    /// <param name="binding">The binding to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateInstanceConnectionBindingAsync(InstanceConnectionBinding binding, CancellationToken cancellationToken = default);
    /// <summary>Deletes an instance connection binding by ID.</summary>
    /// <param name="id">The binding ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteInstanceConnectionBindingAsync(int id, CancellationToken cancellationToken = default);

    // Area
    /// <summary>Retrieves an area by ID.</summary>
    /// <param name="id">The area ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching area, or <see langword="null"/> if not found.</returns>
    Task<Area?> GetAreaByIdAsync(int id, CancellationToken cancellationToken = default);
    /// <summary>Retrieves areas for a site.</summary>
    /// <param name="siteId">The site ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of areas for the specified site.</returns>
    Task<IReadOnlyList<Area>> GetAreasBySiteIdAsync(int siteId, CancellationToken cancellationToken = default);
    /// <summary>Adds a new area.</summary>
    /// <param name="area">The area to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddAreaAsync(Area area, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing area.</summary>
    /// <param name="area">The area to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateAreaAsync(Area area, CancellationToken cancellationToken = default);
    /// <summary>Deletes an area by ID.</summary>
    /// <param name="id">The area ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteAreaAsync(int id, CancellationToken cancellationToken = default);

    // SharedScript
    /// <summary>Retrieves a shared script by ID.</summary>
    /// <param name="id">The script ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching shared script, or <see langword="null"/> if not found.</returns>
    Task<SharedScript?> GetSharedScriptByIdAsync(int id, CancellationToken cancellationToken = default);
    /// <summary>Retrieves a shared script by name.</summary>
    /// <param name="name">The script name.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching shared script, or <see langword="null"/> if not found.</returns>
    Task<SharedScript?> GetSharedScriptByNameAsync(string name, CancellationToken cancellationToken = default);
    /// <summary>Retrieves all shared scripts.</summary>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of all shared scripts.</returns>
    Task<IReadOnlyList<SharedScript>> GetAllSharedScriptsAsync(CancellationToken cancellationToken = default);
    /// <summary>Adds a new shared script.</summary>
    /// <param name="sharedScript">The script to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddSharedScriptAsync(SharedScript sharedScript, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing shared script.</summary>
    /// <param name="sharedScript">The script to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateSharedScriptAsync(SharedScript sharedScript, CancellationToken cancellationToken = default);
    /// <summary>Deletes a shared script by ID.</summary>
    /// <param name="id">The script ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteSharedScriptAsync(int id, CancellationToken cancellationToken = default);

    // TemplateFolder
    /// <summary>Retrieves a template folder by ID.</summary>
    /// <param name="id">The folder ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the matching folder, or <see langword="null"/> if not found.</returns>
    Task<TemplateFolder?> GetFolderByIdAsync(int id, CancellationToken cancellationToken = default);
    /// <summary>Retrieves all template folders.</summary>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to a read-only list of all template folders.</returns>
    Task<IReadOnlyList<TemplateFolder>> GetAllFoldersAsync(CancellationToken cancellationToken = default);
    /// <summary>Adds a new template folder.</summary>
    /// <param name="folder">The folder to add.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task AddFolderAsync(TemplateFolder folder, CancellationToken cancellationToken = default);
    /// <summary>Updates an existing template folder.</summary>
    /// <param name="folder">The folder to update.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task UpdateFolderAsync(TemplateFolder folder, CancellationToken cancellationToken = default);
    /// <summary>Deletes a template folder by ID.</summary>
    /// <param name="id">The folder ID.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task DeleteFolderAsync(int id, CancellationToken cancellationToken = default);

    /// <summary>Saves pending changes to the database.</summary>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task that resolves to the number of rows written to the database.</returns>
    Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}
