package tech.easyflow.ai.service.impl;

import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import tech.easyflow.ai.entity.BotMcp;
import tech.easyflow.ai.mapper.BotMcpMapper;
import tech.easyflow.ai.service.BotMcpService;
import org.springframework.stereotype.Service;
import tech.easyflow.common.cache.RedisLockExecutor;

import javax.annotation.Resource;
import java.time.Duration;
import java.math.BigInteger;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 *  服务层实现。
 *
 * @author wangGangQiang
 * @since 2026-01-05
 */
@Service
public class BotMcpServiceImpl extends ServiceImpl<BotMcpMapper, BotMcp>  implements BotMcpService{

    private static final String BOT_BINDING_LOCK_KEY_PREFIX = "easyflow:lock:bot:binding:";
    private static final Duration LOCK_WAIT_TIMEOUT = Duration.ofSeconds(2);
    private static final Duration LOCK_LEASE_TIMEOUT = Duration.ofSeconds(10);

    @Resource
    private RedisLockExecutor redisLockExecutor;

    @Override
    @Transactional
    public void updateBotMcpToolIds(BigInteger botId, List<Map<String, List<List<String>>>> mcpSelectedData) {
        redisLockExecutor.executeWithLock(BOT_BINDING_LOCK_KEY_PREFIX + botId, LOCK_WAIT_TIMEOUT, LOCK_LEASE_TIMEOUT, () -> {
            this.remove(QueryWrapper.create().eq(BotMcp::getBotId, botId));
            if (mcpSelectedData == null || mcpSelectedData.isEmpty()) {
                return;
            }

            Set<String> uniqueTools = new LinkedHashSet<>();
            for (Map<String, List<List<String>>> mcpItem : mcpSelectedData) {
                for (Map.Entry<String, List<List<String>>> entry : mcpItem.entrySet()) {
                    String mcpId = entry.getKey();
                    List<List<String>> toolList = entry.getValue();
                    if (toolList == null || toolList.isEmpty()) {
                        continue;
                    }

                    for (List<String> toolInfo : toolList) {
                        if (toolInfo == null || toolInfo.size() < 2) {
                            continue;
                        }
                        String toolName = toolInfo.get(0);
                        String toolDesc = toolInfo.get(1);
                        if (toolName == null) {
                            continue;
                        }
                        String uniqueKey = mcpId + "|" + toolName;
                        if (!uniqueTools.add(uniqueKey)) {
                            continue;
                        }
                        BotMcp botMcp = new BotMcp();
                        botMcp.setBotId(botId);
                        botMcp.setMcpId(new BigInteger(mcpId));
                        botMcp.setMcpToolName(toolName);
                        botMcp.setMcpToolDescription(toolDesc);
                        this.save(botMcp);
                    }
                }
            }
        });
    }
}
