# Copyright (c) 2025, JINGROW
# License: MIT. See LICENSE

import jingrow
from jingrow.utils.jinja import render_template


def get_all_ai_agents():
	"""获取所有启用的事件驱动Ai Agent，支持按PageType和Module分组"""
	agents_list = jingrow.get_all(
		"Ai Agent",
		fields=["name", "agent_name", "trigger_mode", "event_type", "target_pagetype", "target_module", "condition"],
		filters={"enabled": True, "trigger_mode": "Event Trigger"},
	)

	agents = {}
	for agent in agents_list:
		if agent.target_pagetype:
			# 按PageType分组
			agents.setdefault(agent.target_pagetype, []).append(agent)
		elif agent.target_module:
			# 按Module分组，key为module:xxx
			key = f"module:{agent.target_module.strip().lower()}"
			agents.setdefault(key, []).append(agent)
	return agents


def run_agent(pg, method):
	"""运行Ai Agent事件驱动机制，支持pagetype和module分组并行触发（合并去重），condition支持Jinja2表达式。防止链式重复触发。"""
	jingrow_flags = jingrow.local.flags

	if jingrow_flags.in_import or jingrow_flags.in_patch or jingrow_flags.in_install or jingrow_flags.in_migrate:
		return

	ai_agents = jingrow.cache.get_value("ai_agents", get_all_ai_agents)

	# 获取pagetype分组
	agents_by_pagetype = ai_agents.get(pg.pagetype, []) or []

	# 获取module分组
	module_name = getattr(jingrow.get_meta(pg.pagetype), "module", None)
	agents_by_module = []
	if module_name:
		key = f"module:{module_name.strip().lower()}"
		agents_by_module = ai_agents.get(key, []) or []

	# 合并去重
	agents_for_pg = {agent.name: agent for agent in agents_by_pagetype + agents_by_module}.values()
	if not agents_for_pg:
		return

	event_list = ["on_update", "after_insert", "on_submit", "on_cancel", "on_trash"]
	if not pg.flags.in_insert:
		event_list.append("on_change")
		event_list.append("before_update_after_submit")

	for agent in agents_for_pg:
		event = method if method in event_list else None
		if event and agent.event_type == event:
			cache_key = f"ai_agent_filled:{pg.pagetype}:{pg.name}:{agent.name}:{event}"
			if jingrow.cache.get_value(cache_key):
				continue
			trigger_agent = False
			if not agent.condition:
				trigger_agent = True
			else:
				try:
					result = render_template(agent.condition, {"pg": pg})
					if str(result).strip().lower() in ("true", "1", "yes"):
						trigger_agent = True
				except Exception:
					trigger_agent = False
			if trigger_agent:
				_add_agent_to_queue(agent, pg)
				try:
					jingrow.cache.set_value(cache_key, True, expires_in_sec=30)
				except Exception:
					pass


def _add_agent_to_queue(agent, pg):
	"""将Ai Agent添加到执行队列"""
	if not getattr(jingrow.local, "_ai_agent_queue", None):
		jingrow.local._ai_agent_queue = []
		jingrow.db.after_commit.add(flush_ai_agent_execution_queue)

	jingrow.local._ai_agent_queue.append(jingrow._dict(pg=pg, agent=agent))


def flush_ai_agent_execution_queue():
	"""清空Ai Agent执行队列，将所有待执行的Agent加入后台任务"""
	if not getattr(jingrow.local, "_ai_agent_queue", None):
		return

	uniq_agents = set()
	unique_last_instances = []

	# 反转队列
	jingrow.local._ai_agent_queue.reverse()

	# 去重：基于 (agent.name, pg.name) 
	# 'pg' 保存最后一个实例的值
	for execution in jingrow.local._ai_agent_queue:
		key = (execution.agent.get("name"), execution.pg.get("name"))
		if key not in uniq_agents:
			uniq_agents.add(key)
			unique_last_instances.append(execution)

	# 清空原队列，以便下次正确计算
	del jingrow.local._ai_agent_queue

	# 再次反转，恢复原始执行顺序
	unique_last_instances.reverse()

	for instance in unique_last_instances:
		# 将Ai Agent执行任务加入后台队列
		jingrow.enqueue(
			"jingrow.ai.pagetype.ai_agent.ai_agent.enqueue_ai_agent",
			pg=instance.pg,
			agent_name=instance.agent.get("name"),
			now=jingrow.flags.in_test,
			queue="default",
		)


def clear_ai_agent_cache():
	"""清空Ai Agent缓存"""
	jingrow.cache.delete_value("ai_agents")



