import { getLogger as getLogger$1 } from "../../../logger.js";
import manageDbClient_default from "../../../data/db/manageDbClient.js";
import manageDbPool_default from "../../../data/db/manageDbPool.js";
import runDbClient_default from "../../../data/db/runDbClient.js";
import "../../../data/db/index.js";
import { scheduledTriggerRunnerWorkflow } from "../workflow/functions/scheduledTriggerRunner.js";
import { cancelPastPendingInvocationsForTrigger, cancelPendingInvocationsForTrigger, createScheduledWorkflow, generateId, getProjectScopedRef, getScheduledWorkflowByTriggerId, resolveRef, updateScheduledWorkflowRunId, withRef } from "@inkeep/agents-core";
import { start } from "workflow/api";

//#region src/domains/run/services/ScheduledTriggerService.ts
/**
* Service for managing scheduled trigger workflows.
*
* Handles starting, stopping, and restarting workflow runners
* when scheduled triggers are created, updated, or deleted.
*/
const logger = getLogger$1("ScheduledTriggerService");
/**
* Get or create a scheduled workflow for a trigger.
* Uses branch-scoped database connection for DoltgreSQL compatibility.
*/
async function getOrCreateScheduledWorkflow(params) {
	const { tenantId, projectId, agentId, scheduledTriggerId, triggerName } = params;
	const scopes = {
		tenantId,
		projectId,
		agentId
	};
	const ref = getProjectScopedRef(tenantId, projectId, "main");
	const resolvedRef = await resolveRef(manageDbClient_default)(ref);
	if (!resolvedRef) throw new Error(`Failed to resolve ref for project ${projectId}`);
	return withRef(manageDbPool_default, resolvedRef, async (db) => {
		const existingWorkflow = await getScheduledWorkflowByTriggerId(db)({
			scopes,
			scheduledTriggerId
		});
		if (existingWorkflow) return existingWorkflow;
		return await createScheduledWorkflow(db)({
			tenantId,
			projectId,
			agentId,
			id: generateId(),
			name: `Workflow for ${triggerName}`,
			scheduledTriggerId
		});
	});
}
/**
* Start a workflow runner for a scheduled trigger.
* Returns the runner ID.
*/
async function startScheduledTriggerWorkflow(params) {
	const { tenantId, projectId, agentId, scheduledTriggerId, triggerName } = params;
	const scopes = {
		tenantId,
		projectId,
		agentId
	};
	const payload = {
		tenantId,
		projectId,
		agentId,
		scheduledTriggerId
	};
	logger.info({
		tenantId,
		projectId,
		agentId,
		scheduledTriggerId
	}, "Starting scheduled trigger workflow");
	const workflow = await getOrCreateScheduledWorkflow({
		tenantId,
		projectId,
		agentId,
		scheduledTriggerId,
		triggerName
	});
	const workflowRunId = (await start(scheduledTriggerRunnerWorkflow, [payload])).runId;
	const ref = getProjectScopedRef(tenantId, projectId, "main");
	const resolvedRef = await resolveRef(manageDbClient_default)(ref);
	if (!resolvedRef) throw new Error(`Failed to resolve ref for project ${projectId}`);
	await withRef(manageDbPool_default, resolvedRef, async (db) => {
		await updateScheduledWorkflowRunId(db)({
			scopes,
			scheduledWorkflowId: workflow.id,
			workflowRunId,
			status: "running"
		});
	});
	logger.info({
		tenantId,
		projectId,
		agentId,
		scheduledTriggerId,
		workflowRunId,
		scheduledWorkflowId: workflow.id
	}, "Scheduled trigger workflow started");
	return workflowRunId;
}
/**
* Signal a workflow runner to stop by clearing its runner ID.
*/
async function signalStopScheduledTriggerWorkflow(params) {
	const { tenantId, projectId, agentId, scheduledTriggerId } = params;
	const scopes = {
		tenantId,
		projectId,
		agentId
	};
	logger.info({
		tenantId,
		projectId,
		agentId,
		scheduledTriggerId
	}, "Signaling scheduled trigger workflow to stop");
	const ref = getProjectScopedRef(tenantId, projectId, "main");
	const resolvedRef = await resolveRef(manageDbClient_default)(ref);
	if (!resolvedRef) {
		logger.warn({
			tenantId,
			projectId,
			agentId,
			scheduledTriggerId
		}, "Failed to resolve ref, cannot signal workflow stop");
		return;
	}
	await withRef(manageDbPool_default, resolvedRef, async (db) => {
		const workflow = await getScheduledWorkflowByTriggerId(db)({
			scopes,
			scheduledTriggerId
		});
		if (workflow) await updateScheduledWorkflowRunId(db)({
			scopes,
			scheduledWorkflowId: workflow.id,
			workflowRunId: null
		});
	});
	logger.info({
		tenantId,
		projectId,
		agentId,
		scheduledTriggerId
	}, "Scheduled trigger workflow stop signaled");
}
/**
* Restart a workflow runner (signal old to stop and start new).
* Used when trigger configuration changes.
*/
async function restartScheduledTriggerWorkflow(params) {
	const { tenantId, projectId, agentId, scheduledTriggerId, triggerName } = params;
	logger.info({
		tenantId,
		projectId,
		agentId,
		scheduledTriggerId
	}, "Restarting scheduled trigger workflow");
	return startScheduledTriggerWorkflow({
		tenantId,
		projectId,
		agentId,
		scheduledTriggerId,
		triggerName
	});
}
/**
* Handle trigger creation - start workflow if enabled.
*/
async function onTriggerCreated(trigger) {
	if (!trigger.enabled) {
		logger.info({ scheduledTriggerId: trigger.id }, "Trigger created but disabled, not starting workflow");
		return;
	}
	await startScheduledTriggerWorkflow({
		tenantId: trigger.tenantId,
		projectId: trigger.projectId,
		agentId: trigger.agentId,
		scheduledTriggerId: trigger.id,
		triggerName: trigger.name
	});
}
/**
* Handle trigger update - restart workflow if needed.
*/
async function onTriggerUpdated(params) {
	const { trigger, previousEnabled, scheduleChanged } = params;
	if (!previousEnabled && !trigger.enabled) return;
	if (previousEnabled && !trigger.enabled) {
		await signalStopScheduledTriggerWorkflow({
			tenantId: trigger.tenantId,
			projectId: trigger.projectId,
			agentId: trigger.agentId,
			scheduledTriggerId: trigger.id
		});
		return;
	}
	if (!previousEnabled && trigger.enabled) {
		const cancelledCount = await cancelPastPendingInvocationsForTrigger(runDbClient_default)({
			scopes: {
				tenantId: trigger.tenantId,
				projectId: trigger.projectId,
				agentId: trigger.agentId
			},
			scheduledTriggerId: trigger.id
		});
		if (cancelledCount > 0) logger.info({
			scheduledTriggerId: trigger.id,
			cancelledCount
		}, "Cancelled past pending invocations on trigger re-enable");
		await startScheduledTriggerWorkflow({
			tenantId: trigger.tenantId,
			projectId: trigger.projectId,
			agentId: trigger.agentId,
			scheduledTriggerId: trigger.id,
			triggerName: trigger.name
		});
		return;
	}
	if (scheduleChanged) {
		const cancelledCount = await cancelPendingInvocationsForTrigger(runDbClient_default)({
			scopes: {
				tenantId: trigger.tenantId,
				projectId: trigger.projectId,
				agentId: trigger.agentId
			},
			scheduledTriggerId: trigger.id
		});
		if (cancelledCount > 0) logger.info({
			scheduledTriggerId: trigger.id,
			cancelledCount
		}, "Cancelled pending invocations on schedule change");
		await restartScheduledTriggerWorkflow({
			tenantId: trigger.tenantId,
			projectId: trigger.projectId,
			agentId: trigger.agentId,
			scheduledTriggerId: trigger.id,
			triggerName: trigger.name
		});
	}
}
/**
* Handle trigger deletion - signal workflow to stop.
* The workflow will be automatically deleted via cascade when the trigger is deleted.
*/
async function onTriggerDeleted(trigger) {
	await signalStopScheduledTriggerWorkflow({
		tenantId: trigger.tenantId,
		projectId: trigger.projectId,
		agentId: trigger.agentId,
		scheduledTriggerId: trigger.id
	});
}

//#endregion
export { onTriggerCreated, onTriggerDeleted, onTriggerUpdated, restartScheduledTriggerWorkflow, signalStopScheduledTriggerWorkflow, startScheduledTriggerWorkflow };