package org.xyzh.ai.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.xyzh.ai.mapper.TbAgentMapper;
import org.xyzh.api.ai.dto.TbAgent;
import org.xyzh.api.ai.service.AgentService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.redis.service.RedisService;
import org.xyzh.common.utils.id.IdUtil;
import org.xyzh.common.auth.utils.LoginUtil;

import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description 智能体服务实现
 * @filename AgentServiceImpl.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-12-17
 */
@DubboService(version = "1.0.0", group = "ai", timeout = 3000, retries = 0)
public class AgentServiceImpl implements AgentService {
    private static final Logger logger = LoggerFactory.getLogger(AgentServiceImpl.class);

    private static final String AGENT_CACHE_PREFIX = "ai:agent:";
    private static final long AGENT_CACHE_TTL = 24 * 60 * 60;

    private final ReentrantLock agentLock = new ReentrantLock();

    @Autowired
    private TbAgentMapper agentMapper;

    @Autowired
    private RedisService redisService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbAgent> addAgent(TbAgent tbAgent) {
        // 1. 参数校验
        if (!StringUtils.hasText(tbAgent.getName())) {
            return ResultDomain.failure("智能体名称不能为空");
        }
        if (!StringUtils.hasText(tbAgent.getApiKey())) {
            return ResultDomain.failure("智能体API Key不能为空");
        }
        if (!StringUtils.hasText(tbAgent.getIntroduce())) {
            return ResultDomain.failure("引导词不能为空");
        }
        if (!StringUtils.hasText(tbAgent.getCategory())) {
            return ResultDomain.failure("分类不能为空");
        }

        // 2. 检查名称是否重复
        int count = agentMapper.countByName(tbAgent.getName(), null);
        if (count > 0) {
            return ResultDomain.failure("智能体名称已存在");
        }

        // 3. 检查ApiKey是否重复
        TbAgent existAgent = agentMapper.selectAgentByApiKey(tbAgent.getApiKey());
        if (existAgent != null) {
            return ResultDomain.failure("该API Key已被使用");
        }

        // 4. 生成ID和流水号
        tbAgent.setOptsn(IdUtil.getOptsn());
        tbAgent.setAgentId(IdUtil.getSnowflakeId());

        // 5. 设置创建者
        String userId = LoginUtil.getCurrentUserId();
        if (StringUtils.hasText(userId)) {
            tbAgent.setCreator(userId);
        }

        // 6. 插入数据库
        int rows = agentMapper.insertAgent(tbAgent);
        if (rows > 0) {
            logger.info("创建智能体成功: agentId={}, name={}", tbAgent.getAgentId(), tbAgent.getName());
            return ResultDomain.success("创建智能体成功", tbAgent);
        }

        return ResultDomain.failure("创建智能体失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbAgent> updateAgent(TbAgent tbAgent) {
        // 1. 参数校验
        if (!StringUtils.hasText(tbAgent.getAgentId())) {
            return ResultDomain.failure("智能体ID不能为空");
        }

        // 2. 检查是否存在
        TbAgent existAgent = agentMapper.selectAgentById(tbAgent.getAgentId());
        if (existAgent == null) {
            return ResultDomain.failure("智能体不存在");
        }

        // 3. 检查名称是否重复（排除自身）
        if (StringUtils.hasText(tbAgent.getName())) {
            int count = agentMapper.countByName(tbAgent.getName(), tbAgent.getAgentId());
            if (count > 0) {
                return ResultDomain.failure("智能体名称已存在");
            }
        }

        // 4. 加锁更新（避免并发问题）
        agentLock.lock();
        try {
            // 5. 设置更新者
            String userId = LoginUtil.getCurrentUserId();
            if (StringUtils.hasText(userId)) {
                tbAgent.setUpdater(userId);
            }

            // 6. 更新数据库
            int rows = agentMapper.updateAgent(tbAgent);
            if (rows > 0) {
                // 7. 返回最新数据
                TbAgent updated = agentMapper.selectAgentById(tbAgent.getAgentId());
                // 8. 更新缓存
                String cacheKey = AGENT_CACHE_PREFIX + tbAgent.getAgentId();
                logger.info("更新智能体成功: agentId={}", tbAgent.getAgentId());
                redisService.set(cacheKey, updated);
                return ResultDomain.success("更新智能体成功", updated);
            }
        } finally {
            agentLock.unlock();
        }

        return ResultDomain.failure("更新智能体失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbAgent> deleteAgent(TbAgent tbAgent) {
        // 1. 参数校验
        if (!StringUtils.hasText(tbAgent.getAgentId())) {
            return ResultDomain.failure("智能体ID不能为空");
        }

        // 2. 检查是否存在
        TbAgent existAgent = agentMapper.selectAgentById(tbAgent.getAgentId());
        if (existAgent == null) {
            return ResultDomain.failure("智能体不存在");
        }

        // 3. 设置更新者
        String userId = LoginUtil.getCurrentUserId();
        if (StringUtils.hasText(userId)) {
            tbAgent.setUpdater(userId);
        }

        // 4. 逻辑删除
        int rows = agentMapper.deleteAgent(tbAgent);
        if (rows > 0) {
            // 5. 删除缓存
            String cacheKey = AGENT_CACHE_PREFIX + tbAgent.getAgentId();
            redisService.delete(cacheKey);

            logger.info("删除智能体成功: agentId={}", tbAgent.getAgentId());
            return ResultDomain.success("删除智能体成功", existAgent);
        }

        return ResultDomain.failure("删除智能体失败");
    }

    /**
     * 根据ID获取智能体（优先从缓存获取，双检加锁）
     */
    public ResultDomain<TbAgent> selectAgentById(String agentId) {
        if (!StringUtils.hasText(agentId)) {
            return ResultDomain.failure("智能体ID不能为空");
        }

        String cacheKey = AGENT_CACHE_PREFIX + agentId;

        // 1. 先从缓存获取
        TbAgent agent = redisService.get(cacheKey, TbAgent.class);
        if (agent != null) {
            return ResultDomain.success("查询成功", agent);
        }

        // 2. 双检加锁
        agentLock.lock();
        try {
            // 再次检查缓存
            agent = redisService.get(cacheKey, TbAgent.class);
            if (agent != null) {
                return ResultDomain.success("查询成功", agent);
            }

            // 3. 从数据库获取
            agent = agentMapper.selectAgentById(agentId);
            if (agent != null) {
                // 4. 写入缓存
                redisService.set(cacheKey, agent);
                return ResultDomain.success("查询成功", agent);
            }

            return ResultDomain.failure("智能体不存在");
        } finally {
            agentLock.unlock();
        }
    }

    /**
     * 根据ApiKey获取智能体
     */
    public TbAgent getAgentByApiKey(String apiKey) {
        if (!StringUtils.hasText(apiKey)) {
            return null;
        }
        return agentMapper.selectAgentByApiKey(apiKey);
    }

    @Override
    public ResultDomain<TbAgent> getAgentPage(PageRequest<TbAgent> pageRequest) {
        TbAgent filter = pageRequest.getFilter();
        PageParam pageParam = pageRequest.getPageParam();

        // 查询总数
        long total = agentMapper.countAgents(filter);
        pageParam.setTotal((int) total);

        // 查询分页数据
        List<TbAgent> list = agentMapper.selectAgentPage(filter, pageParam);

        PageDomain<TbAgent> pageDomain = new PageDomain<>(pageParam, list);
        return ResultDomain.success("查询成功", pageDomain);
    }

    @Override
    public ResultDomain<TbAgent> getAgentList(TbAgent filter) {
        // 查询列表
        List<TbAgent> list = agentMapper.selectAgentList(filter);

        ResultDomain<TbAgent> result = ResultDomain.success("查询成功");
        result.setDataList(list);
        return result;
    }
}
