package persistence

import (
	"context"
	"database/sql"
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/nexuscrm/shared/pkg/models"
)

// --- Salesforce-Compatible Flow Methods (FlowDefinition, FlowVersion, FlowInterview) ---

// flowDefinitionSelectColumns is the canonical column list for FlowDefinition
// reads. Kept as a package-level constant to keep SELECTs in lockstep.
const flowDefinitionSelectColumns = `Id, DeveloperName, MasterLabel, Description, ProcessType, TriggerType,
	TriggerObjectOrEvent, ActiveVersionId, LatestVersionId, IsDeleted, IsCustomized, CreatedDate, LastModifiedDate`

const (
	flowVersionSourceStandard = "standard"
	flowVersionSourceCustom   = "custom"
)

// scanFlowDefinition applies a row scan into a FlowDefinition, handling
// nullable columns. Shared by Get/GetByID/GetByName to keep the column
// binding in one place.
func scanFlowDefinition(scan func(...interface{}) error) (*models.FlowDefinition, error) {
	var def models.FlowDefinition
	var desc, triggerType, triggerObj, activeVer, latestVer sql.NullString
	var isDeleted, isCustomized sql.NullBool
	if err := scan(&def.Id, &def.DeveloperName, &def.MasterLabel, &desc, &def.ProcessType,
		&triggerType, &triggerObj, &activeVer, &latestVer, &isDeleted, &isCustomized,
		&def.CreatedDate, &def.LastModifiedDate); err != nil {
		return nil, err
	}
	if desc.Valid {
		def.Description = desc.String
	}
	if triggerType.Valid {
		def.TriggerType = triggerType.String
	}
	if triggerObj.Valid {
		def.TriggerObjectOrEvent = triggerObj.String
	}
	if activeVer.Valid {
		def.ActiveVersionId = activeVer.String
	}
	if latestVer.Valid {
		def.LatestVersionId = latestVer.String
	}
	if isDeleted.Valid {
		def.IsDeleted = isDeleted.Bool
	}
	if isCustomized.Valid {
		def.IsCustomized = isCustomized.Bool
	}
	return &def, nil
}

func nullableString(v string) interface{} {
	if v == "" {
		return nil
	}
	return v
}

// GetAllFlowDefinitions returns all flow definitions.
func (r *MetadataRepository) GetAllFlowDefinitions(ctx context.Context) ([]*models.FlowDefinition, error) {
	query := `SELECT ` + flowDefinitionSelectColumns + `
		FROM FlowDefinition WHERE IsDeleted = false OR IsDeleted IS NULL`

	rows, err := r.GetExecutor(ctx).QueryContext(ctx, query)
	if err != nil {
		if IsTableNotExistsError(err) {
			log.Printf("FlowDefinition table does not exist, returning empty list")
			return []*models.FlowDefinition{}, nil
		}
		return nil, err
	}
	defer rows.Close()

	defs := make([]*models.FlowDefinition, 0)
	for rows.Next() {
		def, err := scanFlowDefinition(rows.Scan)
		if err != nil {
			log.Printf("Warning: Failed to scan flow definition: %v", err)
			continue
		}
		defs = append(defs, def)
	}
	return defs, rows.Err()
}

// GetFlowDefinition returns a flow definition by ID.
func (r *MetadataRepository) GetFlowDefinition(ctx context.Context, id string) (*models.FlowDefinition, error) {
	query := `SELECT ` + flowDefinitionSelectColumns + `
		FROM FlowDefinition WHERE Id = ?`

	def, err := scanFlowDefinition(r.GetExecutor(ctx).QueryRowContext(ctx, query, id).Scan)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, nil
		}
		return nil, err
	}
	return def, nil
}

// GetFlowDefinitionByName returns a flow definition by DeveloperName.
func (r *MetadataRepository) GetFlowDefinitionByName(ctx context.Context, developerName string) (*models.FlowDefinition, error) {
	query := `SELECT ` + flowDefinitionSelectColumns + `
		FROM FlowDefinition WHERE DeveloperName = ?`

	def, err := scanFlowDefinition(r.GetExecutor(ctx).QueryRowContext(ctx, query, developerName).Scan)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, nil
		}
		return nil, err
	}
	return def, nil
}

// CreateFlowDefinition creates a new flow definition.
func (r *MetadataRepository) CreateFlowDefinition(ctx context.Context, def *models.FlowDefinition) error {
	now := time.Now().Format(time.RFC3339)
	query := `INSERT INTO FlowDefinition (Id, DeveloperName, MasterLabel, Description, ProcessType,
		TriggerType, TriggerObjectOrEvent, ActiveVersionId, LatestVersionId, IsDeleted, IsCustomized,
		CreatedDate, LastModifiedDate)
		VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
	_, err := r.GetExecutor(ctx).ExecContext(ctx, query, def.Id, def.DeveloperName, def.MasterLabel, def.Description,
		def.ProcessType, def.TriggerType, def.TriggerObjectOrEvent, nullableString(def.ActiveVersionId), nullableString(def.LatestVersionId),
		def.IsDeleted, def.IsCustomized, now, now)
	return err
}

// UpdateFlowDefinition replaces the FlowDefinition projection, including
// reconcile-owned fields such as tombstones. Control-plane writers use this
// path; tooling PATCH must use PatchFlowDefinition instead.
func (r *MetadataRepository) UpdateFlowDefinition(ctx context.Context, id string, def *models.FlowDefinition) error {
	now := time.Now().Format(time.RFC3339)
	query := `UPDATE FlowDefinition SET DeveloperName = ?, MasterLabel = ?, Description = ?, ProcessType = ?,
		TriggerType = ?, TriggerObjectOrEvent = ?, ActiveVersionId = ?, LatestVersionId = ?, IsDeleted = ?, LastModifiedDate = ?
		WHERE Id = ?`
	_, err := r.GetExecutor(ctx).ExecContext(ctx, query, def.DeveloperName, def.MasterLabel, def.Description, def.ProcessType,
		def.TriggerType, def.TriggerObjectOrEvent, nullableString(def.ActiveVersionId), nullableString(def.LatestVersionId), def.IsDeleted, now, id)
	return err
}

// PatchFlowDefinition applies sparse admin-authored Tooling updates without
// touching internal reconcile state such as IsDeleted/IsCustomized.
func (r *MetadataRepository) PatchFlowDefinition(ctx context.Context, id string, patch *models.FlowDefinitionPatch) error {
	if patch == nil || patch.Empty() {
		return nil
	}

	now := time.Now().Format(time.RFC3339)
	sets := make([]string, 0, 9)
	args := make([]interface{}, 0, 10)

	if patch.DeveloperName != nil {
		sets = append(sets, "DeveloperName = ?")
		args = append(args, *patch.DeveloperName)
	}
	if patch.MasterLabel != nil {
		sets = append(sets, "MasterLabel = ?")
		args = append(args, *patch.MasterLabel)
	}
	if patch.Description != nil {
		sets = append(sets, "Description = ?")
		args = append(args, *patch.Description)
	}
	if patch.ProcessType != nil {
		sets = append(sets, "ProcessType = ?")
		args = append(args, *patch.ProcessType)
	}
	if patch.TriggerType != nil {
		sets = append(sets, "TriggerType = ?")
		args = append(args, *patch.TriggerType)
	}
	if patch.TriggerObjectOrEvent != nil {
		sets = append(sets, "TriggerObjectOrEvent = ?")
		args = append(args, *patch.TriggerObjectOrEvent)
	}
	if patch.ActiveVersionId != nil {
		sets = append(sets, "ActiveVersionId = ?")
		args = append(args, nullableString(*patch.ActiveVersionId))
	}
	if patch.LatestVersionId != nil {
		sets = append(sets, "LatestVersionId = ?")
		args = append(args, nullableString(*patch.LatestVersionId))
	}

	sets = append(sets, "LastModifiedDate = ?")
	args = append(args, now, id)

	query := `UPDATE FlowDefinition SET ` + strings.Join(sets, ", ") + ` WHERE Id = ?`
	_, err := r.GetExecutor(ctx).ExecContext(ctx, query, args...)
	return err
}

// MarkFlowDefinitionCustomized sets IsCustomized=1 on a flow definition so
// future apply passes preserve admin ownership of the row.
func (r *MetadataRepository) MarkFlowDefinitionCustomized(ctx context.Context, id string) error {
	now := time.Now().Format(time.RFC3339)
	_, err := r.GetExecutor(ctx).ExecContext(
		ctx,
		`UPDATE FlowDefinition SET IsCustomized = 1, LastModifiedDate = ? WHERE Id = ?`,
		now, id,
	)
	return err
}

// SetLatestVersionId updates ONLY the LatestVersionId field on a FlowDefinition.
func (r *MetadataRepository) SetLatestVersionId(ctx context.Context, definitionId string, versionId string) error {
	now := time.Now().Format(time.RFC3339)
	query := `UPDATE FlowDefinition SET LatestVersionId = ?, LastModifiedDate = ? WHERE Id = ?`
	_, err := r.GetExecutor(ctx).ExecContext(ctx, query, versionId, now, definitionId)
	return err
}

// SetTriggerInfo updates the TriggerType and TriggerObjectOrEvent fields on a FlowDefinition.
func (r *MetadataRepository) SetTriggerInfo(ctx context.Context, definitionId string, triggerType string, objectOrEvent string) error {
	now := time.Now().Format(time.RFC3339)
	query := `UPDATE FlowDefinition SET TriggerType = ?, TriggerObjectOrEvent = ?, LastModifiedDate = ? WHERE Id = ?`
	_, err := r.GetExecutor(ctx).ExecContext(ctx, query, triggerType, objectOrEvent, now, definitionId)
	return err
}

// DeleteFlowDefinition deletes a flow definition.
func (r *MetadataRepository) DeleteFlowDefinition(ctx context.Context, id string) error {
	now := time.Now().Format(time.RFC3339)
	query := `UPDATE FlowDefinition
		SET IsDeleted = 1, IsCustomized = 1, ActiveVersionId = NULL, LastModifiedDate = ?
		WHERE Id = ?`
	_, err := r.GetExecutor(ctx).ExecContext(ctx, query, now, id)
	return err
}

// GetFlowVersions returns all versions for a flow definition.
func (r *MetadataRepository) GetFlowVersions(ctx context.Context, definitionId string) ([]*models.FlowVersion, error) {
	query := `SELECT Id, DefinitionId, MasterLabel, VersionNumber, Status, Description, ProcessType, Metadata,
		Source, IsDeleted, CreatedDate, LastModifiedDate FROM Flow WHERE DefinitionId = ? ORDER BY VersionNumber DESC`

	rows, err := r.GetExecutor(ctx).QueryContext(ctx, query, definitionId)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	versions := make([]*models.FlowVersion, 0)
	for rows.Next() {
		var v models.FlowVersion
		var masterLabel, desc, metadata, source sql.NullString
		var isDeleted sql.NullBool
		var createdDate, lastModifiedDate sql.NullString
		if err := rows.Scan(&v.Id, &v.DefinitionId, &masterLabel, &v.VersionNumber, &v.Status, &desc, &v.ProcessType,
			&metadata, &source, &isDeleted, &createdDate, &lastModifiedDate); err != nil {
			log.Printf("Warning: Failed to scan flow version: %v", err)
			continue
		}
		if masterLabel.Valid {
			v.MasterLabel = masterLabel.String
		}
		if desc.Valid {
			v.Description = desc.String
		}
		if metadata.Valid {
			v.MetadataJSON = metadata.String
		}
		if source.Valid {
			v.Source = source.String
		}
		if isDeleted.Valid {
			v.IsDeleted = isDeleted.Bool
		}
		if createdDate.Valid {
			v.CreatedDate = createdDate.String
		}
		if lastModifiedDate.Valid {
			v.LastModifiedDate = lastModifiedDate.String
		}
		v.HydrateMetadata()
		versions = append(versions, &v)
	}
	return versions, rows.Err()
}

// GetFlowVersion returns a specific flow version.
func (r *MetadataRepository) GetFlowVersion(ctx context.Context, id string) (*models.FlowVersion, error) {
	query := `SELECT Id, DefinitionId, MasterLabel, VersionNumber, Status, Description, ProcessType, Metadata,
		Source, IsDeleted, CreatedDate, LastModifiedDate FROM Flow WHERE Id = ?`

	var v models.FlowVersion
	var masterLabel, desc, metadata, source sql.NullString
	var isDeleted sql.NullBool
	var createdDate, lastModifiedDate sql.NullString
	err := r.GetExecutor(ctx).QueryRowContext(ctx, query, id).Scan(&v.Id, &v.DefinitionId, &masterLabel, &v.VersionNumber, &v.Status,
		&desc, &v.ProcessType, &metadata, &source, &isDeleted, &createdDate, &lastModifiedDate)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, nil
		}
		return nil, err
	}
	if masterLabel.Valid {
		v.MasterLabel = masterLabel.String
	}
	if desc.Valid {
		v.Description = desc.String
	}
	if metadata.Valid {
		v.MetadataJSON = metadata.String
	}
	if source.Valid {
		v.Source = source.String
	}
	if isDeleted.Valid {
		v.IsDeleted = isDeleted.Bool
	}
	if createdDate.Valid {
		v.CreatedDate = createdDate.String
	}
	if lastModifiedDate.Valid {
		v.LastModifiedDate = lastModifiedDate.String
	}
	v.HydrateMetadata()
	return &v, nil
}

// GetFlowVersionsByIDs retrieves multiple flow versions by IDs in a single query.
func (r *MetadataRepository) GetFlowVersionsByIDs(ctx context.Context, ids []string) (map[string]*models.FlowVersion, error) {
	if len(ids) == 0 {
		return nil, nil
	}

	placeholders := make([]string, len(ids))
	args := make([]interface{}, len(ids))
	for i, id := range ids {
		placeholders[i] = "?"
		args[i] = id
	}

	query := fmt.Sprintf(
		`SELECT Id, DefinitionId, MasterLabel, VersionNumber, Status, Description, ProcessType, Metadata,
			Source, IsDeleted, CreatedDate, LastModifiedDate FROM Flow WHERE Id IN (%s)`,
		strings.Join(placeholders, ","),
	)

	rows, err := r.GetExecutor(ctx).QueryContext(ctx, query, args...)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	result := make(map[string]*models.FlowVersion, len(ids))
	for rows.Next() {
		var v models.FlowVersion
		var masterLabel, desc, metadata, source sql.NullString
		var isDeleted sql.NullBool
		var createdDate, lastModifiedDate sql.NullString
		if err := rows.Scan(&v.Id, &v.DefinitionId, &masterLabel, &v.VersionNumber, &v.Status,
			&desc, &v.ProcessType, &metadata, &source, &isDeleted, &createdDate, &lastModifiedDate); err != nil {
			return nil, err
		}
		if masterLabel.Valid {
			v.MasterLabel = masterLabel.String
		}
		if desc.Valid {
			v.Description = desc.String
		}
		if metadata.Valid {
			v.MetadataJSON = metadata.String
		}
		if source.Valid {
			v.Source = source.String
		}
		if isDeleted.Valid {
			v.IsDeleted = isDeleted.Bool
		}
		if createdDate.Valid {
			v.CreatedDate = createdDate.String
		}
		if lastModifiedDate.Valid {
			v.LastModifiedDate = lastModifiedDate.String
		}
		v.HydrateMetadata()
		result[v.Id] = &v
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return result, nil
}

// GetActiveFlowVersion returns the active version for a flow definition.
func (r *MetadataRepository) GetActiveFlowVersion(ctx context.Context, definitionId string) (*models.FlowVersion, error) {
	query := `SELECT Id, DefinitionId, MasterLabel, VersionNumber, Status, Description, ProcessType, Metadata,
		Source, IsDeleted, CreatedDate, LastModifiedDate FROM Flow WHERE DefinitionId = ? AND Status = 'Active' LIMIT 1`

	var v models.FlowVersion
	var masterLabel, desc, metadata, source sql.NullString
	var isDeleted sql.NullBool
	var createdDate, lastModifiedDate sql.NullString
	err := r.GetExecutor(ctx).QueryRowContext(ctx, query, definitionId).Scan(&v.Id, &v.DefinitionId, &masterLabel, &v.VersionNumber, &v.Status,
		&desc, &v.ProcessType, &metadata, &source, &isDeleted, &createdDate, &lastModifiedDate)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, nil
		}
		return nil, err
	}
	if masterLabel.Valid {
		v.MasterLabel = masterLabel.String
	}
	if desc.Valid {
		v.Description = desc.String
	}
	if metadata.Valid {
		v.MetadataJSON = metadata.String
	}
	if source.Valid {
		v.Source = source.String
	}
	if isDeleted.Valid {
		v.IsDeleted = isDeleted.Bool
	}
	if createdDate.Valid {
		v.CreatedDate = createdDate.String
	}
	if lastModifiedDate.Valid {
		v.LastModifiedDate = lastModifiedDate.String
	}
	v.HydrateMetadata()
	return &v, nil
}

// CreateFlowVersion creates a new tooling-authored flow version. Tooling
// writes always mark the version as custom.
func (r *MetadataRepository) CreateFlowVersion(ctx context.Context, version *models.FlowVersion) error {
	return r.createFlowVersionWithSource(ctx, version, flowVersionSourceCustom)
}

// CreateSeededFlowVersion creates a pack-authored flow version. Control-plane
// seeders use this path so shipped versions stay Source='standard' and do not
// masquerade as admin-authored versions.
func (r *MetadataRepository) CreateSeededFlowVersion(ctx context.Context, version *models.FlowVersion) error {
	return r.createFlowVersionWithSource(ctx, version, flowVersionSourceStandard)
}

// CreateTenantFlowVersion creates a tenant-overlay flow version. Tenant overlay
// flows are org-authored runtime metadata, not protected platform-standard flows,
// so they are written with Source='custom' and can be executed by the generic
// automation path.
func (r *MetadataRepository) CreateTenantFlowVersion(ctx context.Context, version *models.FlowVersion) error {
	return r.createFlowVersionWithSource(ctx, version, flowVersionSourceCustom)
}

func (r *MetadataRepository) createFlowVersionWithSource(ctx context.Context, version *models.FlowVersion, source string) error {
	version.SerializeMetadata()
	now := time.Now().Format(time.RFC3339)
	query := fmt.Sprintf(`INSERT INTO Flow (Id, DefinitionId, VersionNumber, Status, Description, ProcessType, Metadata,
		Source, CreatedDate, LastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, '%s', ?, ?)`, source)
	_, err := r.GetExecutor(ctx).ExecContext(ctx, query, version.Id, version.DefinitionId, version.VersionNumber, version.Status,
		version.Description, version.ProcessType, version.MetadataJSON, now, now)
	return err
}

// UpdateFlowVersion updates a flow version and flips Source to 'custom'.
func (r *MetadataRepository) UpdateFlowVersion(ctx context.Context, id string, version *models.FlowVersion) error {
	version.SerializeMetadata()
	now := time.Now().Format(time.RFC3339)
	query := fmt.Sprintf(`UPDATE Flow SET Status = ?, Description = ?, Metadata = ?, Source = '%s', LastModifiedDate = ? WHERE Id = ?`, flowVersionSourceCustom)
	_, err := r.GetExecutor(ctx).ExecContext(ctx, query, version.Status, version.Description, version.MetadataJSON, now, id)
	return err
}

// ActivateFlowVersion activates a flow version and deactivates others.
func (r *MetadataRepository) ActivateFlowVersion(ctx context.Context, id string) error {
	var definitionId string
	err := r.GetExecutor(ctx).QueryRowContext(ctx, "SELECT DefinitionId FROM Flow WHERE Id = ?", id).Scan(&definitionId)
	if err != nil {
		return err
	}

	_, err = r.GetExecutor(ctx).ExecContext(ctx, "UPDATE Flow SET Status = 'Obsolete' WHERE DefinitionId = ? AND Status = 'Active'", definitionId)
	if err != nil {
		return err
	}

	_, err = r.GetExecutor(ctx).ExecContext(ctx, "UPDATE Flow SET Status = 'Active' WHERE Id = ?", id)
	if err != nil {
		return err
	}

	_, err = r.GetExecutor(ctx).ExecContext(ctx, "UPDATE FlowDefinition SET ActiveVersionId = ?, IsDeleted = 0 WHERE Id = ?", id, definitionId)
	return err
}

// DeactivateFlowVersion deactivates a flow version.
func (r *MetadataRepository) DeactivateFlowVersion(ctx context.Context, id string) error {
	_, err := r.GetExecutor(ctx).ExecContext(ctx, "UPDATE Flow SET Status = 'Draft' WHERE Id = ?", id)
	if err != nil {
		return err
	}
	_, err = r.GetExecutor(ctx).ExecContext(
		ctx,
		"UPDATE FlowDefinition SET ActiveVersionId = NULL WHERE ActiveVersionId = ?",
		id,
	)
	return err
}

// DeleteFlowVersion deletes a flow version.
func (r *MetadataRepository) DeleteFlowVersion(ctx context.Context, id string) error {
	query := `DELETE FROM Flow WHERE Id = ?`
	_, err := r.GetExecutor(ctx).ExecContext(ctx, query, id)
	return err
}

// GetFlowInterviews returns all flow interviews.
func (r *MetadataRepository) GetFlowInterviews(ctx context.Context) ([]*models.FlowInterview, error) {
	query := `SELECT Id, FlowVersionId, InterviewLabel, InterviewStatus, CurrentElement, OwnerId,
		ContextData, CreatedDate, PausedDate FROM FlowInterview
		WHERE InterviewStatus IN ('Running', 'Paused') ORDER BY CreatedDate DESC`

	rows, err := r.GetExecutor(ctx).QueryContext(ctx, query)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	interviews := make([]*models.FlowInterview, 0)
	for rows.Next() {
		var i models.FlowInterview
		var label, currentElement, contextData sql.NullString
		var pausedDate sql.NullTime
		if err := rows.Scan(&i.Id, &i.FlowVersionId, &label, &i.InterviewStatus, &currentElement,
			&i.OwnerId, &contextData, &i.CreatedDate, &pausedDate); err != nil {
			log.Printf("Warning: Failed to scan flow interview: %v", err)
			continue
		}
		if label.Valid {
			i.InterviewLabel = label.String
		}
		if currentElement.Valid {
			i.CurrentElement = currentElement.String
		}
		if contextData.Valid {
			i.ContextDataJSON = contextData.String
		}
		if pausedDate.Valid {
			i.PausedDate = &pausedDate.Time
		}
		interviews = append(interviews, &i)
	}
	return interviews, rows.Err()
}

// GetFlowInterview returns a flow interview by ID.
func (r *MetadataRepository) GetFlowInterview(ctx context.Context, id string) (*models.FlowInterview, error) {
	query := `SELECT Id, FlowVersionId, InterviewLabel, InterviewStatus, CurrentElement, OwnerId,
		ContextData, CreatedDate, PausedDate FROM FlowInterview WHERE Id = ?`

	var i models.FlowInterview
	var label, currentElement, contextData sql.NullString
	var pausedDate sql.NullTime
	err := r.GetExecutor(ctx).QueryRowContext(ctx, query, id).Scan(&i.Id, &i.FlowVersionId, &label, &i.InterviewStatus,
		&currentElement, &i.OwnerId, &contextData, &i.CreatedDate, &pausedDate)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, nil
		}
		return nil, err
	}
	if label.Valid {
		i.InterviewLabel = label.String
	}
	if currentElement.Valid {
		i.CurrentElement = currentElement.String
	}
	if contextData.Valid {
		i.ContextDataJSON = contextData.String
	}
	if pausedDate.Valid {
		i.PausedDate = &pausedDate.Time
	}
	return &i, nil
}

// SaveFlowInterview creates or updates a flow interview.
func (r *MetadataRepository) SaveFlowInterview(ctx context.Context, interview *models.FlowInterview) error {
	query := `INSERT INTO FlowInterview (Id, FlowVersionId, InterviewLabel, InterviewStatus, CurrentElement,
		OwnerId, ContextData, CreatedDate, PausedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
		ON DUPLICATE KEY UPDATE InterviewStatus = VALUES(InterviewStatus), CurrentElement = VALUES(CurrentElement),
		ContextData = VALUES(ContextData), PausedDate = VALUES(PausedDate)`
	_, err := r.GetExecutor(ctx).ExecContext(ctx, query, interview.Id, interview.FlowVersionId, interview.InterviewLabel,
		interview.InterviewStatus, interview.CurrentElement, interview.OwnerId, interview.ContextDataJSON,
		interview.CreatedDate, interview.PausedDate)
	return err
}

// DeleteFlowInterview deletes a flow interview.
func (r *MetadataRepository) DeleteFlowInterview(ctx context.Context, id string) error {
	query := `DELETE FROM FlowInterview WHERE Id = ?`
	_, err := r.GetExecutor(ctx).ExecContext(ctx, query, id)
	return err
}
