import type { EndpointType, INodeType, NodeVariable } from '@/nodes/Interface'
import { getNodeDisplayName } from '@/nodes/i18n'
import CustomNodeSetter from './CustomNodeSetter.vue'

interface CustomIdentity {
	type: string
	name: string
	label: string
	description?: string
	icon40?: string
	author: string
}

interface CustomOption {
	label?: string
	value?: string | number | boolean
}

interface CustomParameter {
	name?: string
	label?: string
	description?: string
	llm_description?: string
	type?: string
	required?: boolean
	defaultValue?: unknown
	placeholder?: string
	min?: number
	max?: number
	options?: CustomOption[]
}

export interface CustomNodeSource {
	identity: CustomIdentity
	parameters?: CustomParameter[]
	[key: string]: unknown
}

const DEFAULT_NODE_ICON = 'lucide:puzzle'
const DEFAULT_NODE_ICON_COLOR = '#7c3aed'

const toArray = <T>(value: T[] | undefined): T[] => (Array.isArray(value) ? value : [])

const resolveCustomIcon = (icon40?: string) => {
	const raw = `${icon40 || ''}`.trim()
	if (!raw) {
		return DEFAULT_NODE_ICON
	}

	if (raw.startsWith('data:image/')) {
		return raw
	}

	const compact = raw.replace(/\s+/g, '')
	const isBase64Like = compact.length > 64 && /^[A-Za-z0-9+/=]+$/.test(compact)
	if (isBase64Like) {
		return `data:image/png;base64,${compact}`
	}

	return raw
}

const isEdgeLinkParameter = (parameter: CustomParameter) => {
	return `${parameter.type || ''}`.toLowerCase() === 'edg-link'
}

const buildEdgeLinkPorts = (
	parameters: CustomParameter[],
	data: Record<string, any>
): EndpointType[] => {
	return parameters
		.filter((parameter) => parameter.name && isEdgeLinkParameter(parameter))
		.map(
			(parameter): EndpointType => ({
				id: data?.[parameter.name as string],
				type: 'port',
				label: parameter.label || parameter.name || ''
			})
		)
}

export const toCustomNodeType = (raw: CustomNodeSource): INodeType | null => {
	const nodeType = raw.identity.type
	if (!nodeType) return null

	const parameters = toArray(raw.parameters)

	const outputs = (data: Record<string, any>) => {
		return ['main', ...buildEdgeLinkPorts(parameters, data)]
	}

	return {
		version: ['1'],
		group: 'custom',
		name: nodeType,
		displayName: raw.identity.label,
		description: raw.identity?.description,
		icon: resolveCustomIcon(raw.identity?.icon40),
		iconColor: DEFAULT_NODE_ICON_COLOR,
		Setter: CustomNodeSetter,
		inputs: ['main'],
		outputs,
		parameters,
		author: raw.identity.author,
		schema: {
			appAgentId: '',
			parentId: '',
			position: {
				x: 20,
				y: 30
			},
			width: 96,
			height: 96,
			selected: false,
			nodeType,
			zIndex: 1,
			data: {}
		}
	}
}
