import { NodeConnectionTypes, type INodeType, type INodeDataBaseSchema } from '../../Interface'
import Setter from './setter.vue'

export type LLMPromptRole = 'system' | 'user' | 'assistant'

export type LLMPromptItem = {
	role: LLMPromptRole
	content: string
}

export type LLMJsonSchemaType = 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array'

export type LLMJsonSchemaProperty = {
	type: LLMJsonSchemaType | string
	description?: string
	enum?: Array<string | number | boolean>
	items?: LLMJsonSchemaProperty
	properties?: Record<string, LLMJsonSchemaProperty>
	required?: string[]
	additionalProperties?: boolean
}

export type LLMJsonSchema = {
	type: 'object'
	properties: Record<string, LLMJsonSchemaProperty>
	required: string[]
	additionalProperties: boolean
}

export type LLMData = INodeDataBaseSchema & {
	model_id: string
	context: string
	vision_enabled: boolean
	reasoning_tag_separation_enabled: boolean
	structured_output_enabled: boolean
	structured_output: LLMJsonSchema
	prompt_template: LLMPromptItem[]
}

export const DEFAULT_LLM_OUTPUTS: LLMData['outputs'] = [
	{
		name: 'text',
		describe: '生成内容',
		type: 'string'
	},
	{
		name: 'reasoning_content',
		describe: '推理内容',
		type: 'string'
	},
	{
		name: 'usage',
		describe: '模型用量信息',
		type: 'object'
	},
	{
		name: 'structured_output',
		describe: '结构化对象',
		type: 'object'
	}
]

export const DEFAULT_STRUCTURED_OUTPUT: LLMJsonSchema = {
	type: 'object',
	properties: {
		name: {
			type: 'string',
			description: '名称',
			enum: ['name1', 'name2', 'name3']
		}
	},
	required: ['name'],
	additionalProperties: false
}

export const DEFAULT_PROMPT_TEMPLATE: LLMPromptItem[] = [
	{
		role: 'system',
		content: ''
	},
	{
		role: 'user',
		content: ''
	},
	{
		role: 'assistant',
		content: ''
	}
]

export const llmNode: INodeType = {
	version: ['1'],
	displayName: 'LLM',
	name: 'llm',
	Setter,
	description: '调用大语言模型回答问题或者对自然语言进行处理',
	group: 'data',
	icon: 'lucide:brain-circuit',
	iconColor: '#6172F3',
	inputs: [NodeConnectionTypes.main],
	outputs: [NodeConnectionTypes.main],
	validate: (data: LLMData) => {
		if (!data?.model_id) return '请选择模型'
		const hasPrompt = (data.prompt_template || []).some((item) => item.content?.trim())
		return hasPrompt ? false : '请至少填写一条提示词'
	},
	getSubtitle: (data: LLMData) => data?.model_id || '',
	schema: {
		appAgentId: '',
		parentId: '',
		position: {
			x: 20,
			y: 30
		},
		width: 96,
		height: 96,
		selected: false,
		nodeType: 'llm',
		zIndex: 1,
		data: {}
	}
}
