import { ITriggerFunctions } from 'n8n-core';
import { INodeType, INodeTypeDescription, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import axios from 'axios';
import { evolutionApiToolDescription } from './EvolutionApiToolDescription';

export class EvolutionApiAiTool implements INodeType {
	description: INodeTypeDescription = {
		displayName: 'Evolution API AI Tool',
		name: 'evolutionApiAiTool',
		icon: 'file:evolutionApi.svg',
		group: ['transform', 'ai', 'aiTool'],
		version: 1,
		description: 'Use Evolution API to send WhatsApp messages in AI agents',
		subtitle: 'WhatsApp messaging via Evolution API',
		defaults: {
			name: 'Evolution API AI Tool',
		},
		credentials: [
			{
				name: 'evolutionApiApi',
				required: true,
			},
		],
		inputs: ['main'],
		outputs: ['main'],
		properties: [
			...evolutionApiToolDescription,
		],
	};

	// @ts-ignore
	async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
		const items = this.getInputData();
		const returnData: INodeExecutionData[] = [];
		const credentials = await this.getCredentials('evolutionApiApi');
		const baseUrl = credentials.url as string;
		const apiKey = credentials.apiKey as string;

		// Get operation selected by user
		const operation = this.getNodeParameter('operation', 0) as string;

		for (let i = 0; i < items.length; i++) {
			try {
				// Define parameters based on the operation
				if (operation === 'sendMessage') {
					const apiUrl = `${baseUrl}/message/sendText/${this.getNodeParameter('instance', i)}`;
					const number = this.getNodeParameter('phoneNumber', i) as string;
					const message = this.getNodeParameter('message', i) as string;

					// Make API call
					const response = await axios({
						method: 'POST',
						url: apiUrl,
						headers: {
							'Content-Type': 'application/json',
							'apikey': apiKey,
						},
						data: {
							number,
							options: {
								delay: 1200,
							},
							textMessage: {
								text: message,
							},
						},
					});

					returnData.push({
						json: {
							success: true,
							result: response.data,
							message: `Message sent successfully to ${number}`,
						},
					});
				} else if (operation === 'sendMedia') {
					const apiUrl = `${baseUrl}/message/sendMedia/${this.getNodeParameter('instance', i)}`;
					const number = this.getNodeParameter('phoneNumber', i) as string;
					const mediaUrl = this.getNodeParameter('mediaUrl', i) as string;
					const caption = this.getNodeParameter('caption', i) as string;
					const mediaType = this.getNodeParameter('mediaType', i) as string;

					// Make API call
					const response = await axios({
						method: 'POST',
						url: apiUrl,
						headers: {
							'Content-Type': 'application/json',
							'apikey': apiKey,
						},
						data: {
							number,
							options: {
								delay: 1200,
							},
							mediaMessage: {
								mediatype: mediaType,
								media: mediaUrl,
								caption,
							},
						},
					});

					returnData.push({
						json: {
							success: true,
							result: response.data,
							message: `Media message sent successfully to ${number}`,
						},
					});
				} else if (operation === 'getQrCode') {
					const apiUrl = `${baseUrl}/instance/qrcode/${this.getNodeParameter('instance', i)}`;

					// Make API call
					const response = await axios({
						method: 'GET',
						url: apiUrl,
						headers: {
							'Content-Type': 'application/json',
							'apikey': apiKey,
						},
					});

					returnData.push({
						json: {
							success: true,
							result: response.data,
							message: 'QR code retrieved successfully',
						},
					});
				} else {
					throw new Error(`The operation "${operation}" is not supported!`);
				}
			} catch (error) {
				if (this.continueOnFail()) {
					returnData.push({
						json: {
							success: false,
							error: error.message,
						},
					});
					continue;
				}
				throw error;
			}
		}

		return [returnData];
	}
} 