using System.Collections.Generic;
using System.Data.Common;
using System.Threading.Tasks;
using GB5Shared.DTO.Framework.Login;
using GB5Shared.DTO.WorkFlow;
namespace GB5Shared.WorkFlow.WorkFlowRunTime
{
///
/// Low-level persistence contract for the workflow engine.
/// All methods accept a so the engine can
/// co-ordinate everything inside one database transaction.
///
public interface IWorkFlowRunTime
{
// ── Config resolution ─────────────────────────────────────────────────
///
/// Returns all MWORKFLOWCONFIG rows that might apply for the given context,
/// ordered most-specific-first. The engine evaluates EVALCONDITION on
/// each row and picks the first match.
///
Task> GetWorkflowConfigsAsync(
int entityId,
int clientId,
int ouId,
int bizTransactionClassId,
int bizTransactionId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
///
/// Looks up MBIZTRANSACTIONTYPE.BIZTRANSACTIONTYPEID by BizTransactionClassId.
/// Returns -1 when no matching row exists (FK-safe fallback).
///
Task GetBizTransactionTypeIdAsync(
int bizTransactionClassId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
// ── Definition load ───────────────────────────────────────────────────
/// Loads a workflow by its PK (already resolved via MWORKFLOWCONFIG).
Task GetWorkflowByIdAsync(
int workflowId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
///
/// Loads the latest active workflow definition by EntityId + TenantId
/// (kept for backward compat with old path).
///
Task GetActiveDefinitionAsync(
int entityId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
///
/// Legacy helper used by the old CheckWorkFlowApplicability path.
/// Returns only the header row (no steps/transitions).
///
Task GetActiveWorkflowAsync(
int entityId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
Task> GetConditionAsync(
int? conditionGroupId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
Task> GetRuleGroupsAsync(
IEnumerable ruleGroupIds,
LoginDTO loginDTO,
DbTransaction dbTransaction);
// ── Instance CRUD ─────────────────────────────────────────────────────
///
/// Deletes any pending TWORKFLOWTASK and TWORKFLOWINSTANCE rows for the
/// given tenant + entity + object before a fresh instance is inserted.
/// Only rows with WORKFLOWSTATUS = 0 (Pending) are removed.
///
Task DeleteDuplicateInstanceAsync(
int entityId,
int objectId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
///
/// Cancels every REAL pending (WORKFLOWSTATUS=0) instance for the given tenant +
/// entity + object — unlike , this also
/// cancels instances that already have history (i.e. a genuine in-flight approval),
/// used when the underlying record is deleted or resubmitted after an edit. Also
/// cancels the pending TWORKFLOWTASK rows and, for WIP-backed instances, the linked
/// TWORKFLOWWIP row. Returns the instances that were cancelled so the caller can
/// write TWORKFLOWHISTORY entries against each.
///
Task> CancelPendingInstancesAsync(
int entityId,
int objectId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
Task InsertInstanceAsync(
WorkflowInstance instance,
LoginDTO loginDTO,
DbTransaction dbTransaction);
Task UpdateInstanceAsync(
WorkflowInstance instance,
LoginDTO loginDTO,
DbTransaction dbTransaction);
Task GetInstanceAsync(
long instanceId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
Task GetInstanceAsync(
long clientId,
string entityName,
long entityId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
// ── Task CRUD ─────────────────────────────────────────────────────────
Task InsertTaskAsync(
WorkflowTask task,
LoginDTO loginDTO,
DbTransaction dbTransaction);
Task UpdateTaskAsync(
WorkflowTask task,
LoginDTO loginDTO,
DbTransaction dbTransaction);
Task GetTaskAsync(
int taskId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
///
/// Returns all pending tasks for a given instance + approval level.
/// Used to decide whether the level is complete.
///
Task> GetPendingTasksForLevelAsync(
int instanceId,
int approvalLevel,
LoginDTO loginDTO,
DbTransaction dbTransaction);
/// Kept for backward compat (step-based parallel check).
Task> GetPendingTasksForStepAsync(
int instanceId,
long stepId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
Task> GetInboxTasksAsync(
long userId,
IEnumerable? roles,
IEnumerable? pools,
LoginDTO loginDTO,
DbTransaction dbTransaction);
// ── History ───────────────────────────────────────────────────────────
Task InsertHistoryAsync(
WorkflowHistory history,
LoginDTO loginDTO,
DbTransaction dbTransaction);
// ── Delegation ────────────────────────────────────────────────────────
Task> GetUserDelegationsAsync(
long principalUserId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
// ── WIP (Form-Based Approval) ─────────────────────────────────────────
///
/// Inserts a new TWORKFLOWWIP row (STATUS=Pending, WorkflowInstanceId=-1).
/// Returns the new WipId.
///
Task InsertWipAsync(
int entityId,
int tenantId,
string dataJson,
string? loginJson,
string? apiEndpoint,
int createdById,
LoginDTO loginDTO,
DbTransaction dbTransaction);
/// Binds the workflow instance to the WIP row after the instance is created.
Task UpdateWipInstanceIdAsync(
int wipId,
int workflowInstanceId,
int modifiedById,
LoginDTO loginDTO,
DbTransaction dbTransaction);
/// Returns the WIP record linked to a workflow instance, or null if this is not a WIP instance.
Task GetWipByInstanceIdAsync(
int instanceId,
LoginDTO loginDTO,
DbTransaction dbTransaction);
/// Updates the WIP STATUS and LASTACTION; sets OBJECTID when the real entity has been saved.
Task UpdateWipStatusAsync(
int wipId,
byte status,
byte lastAction,
int objectId,
int modifiedById,
LoginDTO loginDTO,
DbTransaction dbTransaction);
// ── Auto-approve ──────────────────────────────────────────────────────
///
/// Returns all pending tasks whose DUEON has passed and whose step
/// has ISAUTOAPPROVE = 0 (0=Yes). Used by the background auto-approve job.
///
Task> GetOverdueAutoApproveTasksAsync(
LoginDTO loginDTO,
DbTransaction dbTransaction);
}
}