import {
	INodeType,
	INodeTypeDescription,
	IExecuteFunctions,
	INodeExecutionData,
	NodeConnectionType,
	IHttpRequestMethods,
	IDataObject,
} from 'n8n-workflow';

export class _RestOutput implements INodeType {
	description: INodeTypeDescription = {
		displayName: 'RestOutput',
		name: 'restOutput',
		group: ['transform'],
		version: 1,
		description: 'Выполняет HTTP-запрос по URI из METADATA или из поля URI',
		defaults: {
			name: 'RestOutput',
		},
		inputs: [NodeConnectionType.Main],
		outputs: [NodeConnectionType.Main],
		properties: [
			{
				displayName: 'Динамическая настройка',
				name: 'useDynamicUri',
				type: 'boolean',
				default: true,
				description: 'Брать URI из METADATA или использовать указанный ниже',
			},
			{
				displayName: 'URI',
				name: 'staticUri',
				type: 'string',
				default: '',
				displayOptions: {
					show: {
						useDynamicUri: [false],
					},
				},
			},
			{
				displayName: 'Метод',
				name: 'method',
				type: 'options',
				options: [
					{ name: 'GET', value: 'GET' },
					{ name: 'POST', value: 'POST' },
					{ name: 'PUT', value: 'PUT' },
					{ name: 'DELETE', value: 'DELETE' },
				],
				default: 'GET',
			},
			{
				displayName: 'Headers',
				name: 'headers',
				type: 'fixedCollection',
				typeOptions: { multipleValues: true },
				default: {},
				options: [
					{
						name: 'header',
						displayName: 'Header',
						values: [
							{ name: 'key', displayName: 'Key', type: 'string', default: '' },
							{ name: 'value', displayName: 'Value', type: 'string', default: '' },
						],
					},
				],
			},
		],
	};

	async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
		const item = this.getInputData()[0]; // один элемент
		const useDynamicUri = this.getNodeParameter('useDynamicUri', 0) as boolean;
		const staticUri = useDynamicUri ? undefined : this.getNodeParameter('staticUri', 0) as string;
		const method = this.getNodeParameter('method', 0) as IHttpRequestMethods;
		const headersInput = this.getNodeParameter('headers', 0, []) as { header: Array<{ key: string; value: string }> };

		const workflowName = this.getWorkflow().name;
		const nodeInfo = this.getNode();
		const fromNode = nodeInfo.type.split('.').pop()!;
		const idField = nodeInfo.name;

		const headerObj: Record<string, string> = {};
		for (const header of headersInput.header || []) {
			if (header.key) {
				headerObj[header.key] = header.value;
			}
		}

		interface CustomMetadata extends IDataObject {
			HTTPoutput?: {
				uri?: string;
			};
		}

		const metadata = item.json?.METADATA as CustomMetadata | undefined;
		const uri = useDynamicUri ? metadata?.HTTPoutput?.uri : staticUri;

		if (!uri) {
			throw new Error('URI не задан ни в METADATA, ни вручную');
		}

		const response = await this.helpers.httpRequest({
			method,
			url: uri,
			headers: headerObj,
			json: true,
		});

		return [[
			{
				json: {
					DATA: {
						body: response,
						headers: [],
						status_code: 200,
					},
					METADATA: {
						chain: workflowName,
						from: fromNode,
						id: idField,
						time: Date.now(),
					},
				},
			},
		]];
	}
}
