import get from 'lodash/get';
import { resolveRelativePath, Workflow } from 'n8n-workflow';
import type {
	INodeParameterResourceLocator,
	IWorkflowExecuteAdditionalData,
	NodeParameterValueType,
	ILocalLoadOptionsFunctions,
	IWorkflowLoader,
	IWorkflowNodeContext,
	INodeTypes,
} from 'n8n-workflow';

import { LoadWorkflowNodeContext } from './workflow-node-context';

export class LocalLoadOptionsContext implements ILocalLoadOptionsFunctions {
	constructor(
		private nodeTypes: INodeTypes,
		private additionalData: IWorkflowExecuteAdditionalData,
		private path: string,
		private workflowLoader: IWorkflowLoader,
	) {}

	async getWorkflowNodeContext(
		nodeType: string,
		preferActiveVersion: boolean = false,
	): Promise<IWorkflowNodeContext | null> {
		const workflowIdParam = this.getCurrentNodeParameter('workflowId') as
			| INodeParameterResourceLocator
			| undefined;
		const workflowId = workflowIdParam?.value;

		if (typeof workflowId !== 'string' || !workflowId) {
			return null;
		}

		const dbWorkflow = await this.workflowLoader.get(workflowId);

		const selectedWorkflowNode = (
			preferActiveVersion && dbWorkflow.activeVersion
				? dbWorkflow.activeVersion.nodes
				: dbWorkflow.nodes
		).find((node) => node.type === nodeType);

		if (selectedWorkflowNode) {
			const selectedSingleNodeWorkflow = new Workflow({
				id: dbWorkflow.id,
				name: dbWorkflow.name,
				nodes: [selectedWorkflowNode],
				connections: {},
				active: false,
				nodeTypes: this.nodeTypes,
			});

			const workflowAdditionalData = {
				...this.additionalData,
				currentNodeParameters: selectedWorkflowNode.parameters,
			};

			return new LoadWorkflowNodeContext(
				selectedSingleNodeWorkflow,
				selectedWorkflowNode,
				workflowAdditionalData,
			);
		}

		return null;
	}

	getCurrentNodeParameter(parameterPath: string): NodeParameterValueType | object | undefined {
		const nodeParameters = this.additionalData.currentNodeParameters;

		parameterPath = resolveRelativePath(this.path, parameterPath);

		return get(nodeParameters, parameterPath);
	}
}
