package com.ruoyi.rocketmq.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.enums.MsgEnum;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.rocketmq.domain.DeviceMessage;
import com.ruoyi.rocketmq.domain.RmAgentManagement;
import com.ruoyi.rocketmq.domain.RmNetworkInterface;
import com.ruoyi.rocketmq.domain.vo.AgentUpdateMsgVo;
import com.ruoyi.rocketmq.domain.vo.AgentUpdateVo;
import com.ruoyi.rocketmq.domain.vo.PolicyTypeVo;
import com.ruoyi.rocketmq.domain.vo.PolicyVo;
import com.ruoyi.rocketmq.mapper.RmAgentManagementMapper;
import com.ruoyi.rocketmq.mapper.RmNetworkInterfaceMapper;
import com.ruoyi.rocketmq.model.ProducerMode;
import com.ruoyi.rocketmq.producer.MessageProducer;
import com.ruoyi.rocketmq.service.IRmAgentManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * Agent管理Service业务层处理
 * 
 * @author gyt
 * @date 2025-09-15
 */
@Service
@Slf4j
public class RmAgentManagementServiceImpl implements IRmAgentManagementService 
{
    @Autowired
    private RmAgentManagementMapper rmAgentManagementMapper;
    @Autowired
    private RmNetworkInterfaceMapper rmNetworkInterfaceMapper;
    @Value("${fileDictory.filePath}")
    private String filePath;

//    private static String COMMAND = "nohup /usr/local/tongran/deploy.sh restart > /dev/null 2>&1 &";
    private static String COMMAND = "nohup /data/saas-income/houduan/tr-client-test/deploy.sh restart > /dev/null 2>&1 &";
    @Autowired
    private ProducerMode producerMode;

    /**
     * 查询Agent管理
     * 
     * @param id Agent管理主键
     * @return Agent管理
     */
    @Override
    public RmAgentManagement selectRmAgentManagementById(Long id)
    {
        return rmAgentManagementMapper.selectRmAgentManagementById(id);
    }

    /**
     * 查询Agent管理列表
     * 
     * @param rmAgentManagement Agent管理
     * @return Agent管理
     */
    @Override
    public List<RmAgentManagement> selectRmAgentManagementList(RmAgentManagement rmAgentManagement)
    {
        List<RmAgentManagement> managementList = rmAgentManagementMapper.selectRmAgentManagementList(rmAgentManagement);
        for (RmAgentManagement agentManagement : managementList) {
            if(agentManagement.getClientId()!=null){
                // 设置管理网公网ip
                RmNetworkInterface queryParam = new RmNetworkInterface();
                queryParam.setClientId(agentManagement.getClientId());
                // 使用Optional处理可能的NPE，并筛选bindIp为2或3的接口
                RmNetworkInterface networkInterface = Optional.ofNullable(rmNetworkInterfaceMapper.selectRmNetworkInterfaceList(queryParam))
                        .map(list -> list.stream()
                                .filter(ni -> "2".equals(ni.getBindIp()) || "3".equals(ni.getBindIp()))
                                .findFirst()
                                .orElse(null))
                        .orElseGet(() -> {
                            return new RmNetworkInterface(); // 返回空对象避免NPE
                        });
                agentManagement.setManagePublicIp(networkInterface.getPublicIp());
            }
        }
        return managementList;
    }

    /**
     * 新增Agent管理
     * 
     * @param rmAgentManagement Agent管理
     * @return 结果
     */
    @Override
    public int insertRmAgentManagement(RmAgentManagement rmAgentManagement)
    {
        rmAgentManagement.setCreateTime(DateUtils.getNowDate());
        return rmAgentManagementMapper.insertRmAgentManagement(rmAgentManagement);
    }

    /**
     * 修改Agent管理
     * 
     * @param rmAgentManagement Agent管理
     * @return 结果
     */
    @Override
    public int updateRmAgentManagement(RmAgentManagement rmAgentManagement)
    {
        rmAgentManagement.setUpdateTime(DateUtils.getNowDate());
        processAgentUpdateData(rmAgentManagement);
        return 1;
    }
    /**
     * 保存最后更新结果
     *
     * @param rmAgentManagement Agent管理
     * @return 结果
     */
    public void updateRmAgentManagementByHardwareSn(RmAgentManagement rmAgentManagement){
        rmAgentManagementMapper.updateRmAgentManagementBySn(rmAgentManagement);
    }

    /**
     * 批量删除Agent管理
     * 
     * @param ids 需要删除的Agent管理主键
     * @return 结果
     */
    @Override
    public int deleteRmAgentManagementByIds(Long[] ids)
    {
        return rmAgentManagementMapper.deleteRmAgentManagementByIds(ids);
    }

    /**
     * 删除Agent管理信息
     * 
     * @param id Agent管理主键
     * @return 结果
     */
    @Override
    public int deleteRmAgentManagementById(Long id)
    {
        return rmAgentManagementMapper.deleteRmAgentManagementById(id);
    }
    /**
     * 配置更新策略
     * @param rmAgentManagement
     * @return
     */
    @Override
    public int addRmAgentManagement(RmAgentManagement rmAgentManagement) {
        processAgentUpdateData(rmAgentManagement);
        return 1;
    }
    /**
     * 配置更新策略v1.1
     * @param rmAgentManagement
     * @return
     */
    @Override
    public int addUpdatePolicy(RmAgentManagement rmAgentManagement) {
        processAgentData(rmAgentManagement);
        return 1;
    }

    /**
     * 手动立即更新
     * @param rmAgentManagement 更新信息
     * @return
     */
    @Override
    public int updateAgentNow(RmAgentManagement rmAgentManagement) {
        processAgentData(rmAgentManagement);
        return 1;
    }

    /**
     * 处理agen更新数据
     * @param rmAgentManagement
     */
    public void processAgentUpdateData(RmAgentManagement rmAgentManagement){
        // 查询该资源是否已经配置
        RmAgentManagement agentQueryParam = new RmAgentManagement();
        agentQueryParam.setHardwareSn(rmAgentManagement.getHardwareSn());
        List<RmAgentManagement> agentManagements = rmAgentManagementMapper.selectRmAgentManagementList(agentQueryParam);
        if(!agentManagements.isEmpty()){
            // 如果存在，修改
            rmAgentManagement.setLastUpdateTime(DateUtils.getNowDate());
            if("0".equals(rmAgentManagement.getMethod())){
                rmAgentManagement.setScheduledUpdateTime(null);
            }
            rmAgentManagementMapper.updateRmAgentManagementBySn(rmAgentManagement);
        }else{
            // 如果不存在，添加
            rmAgentManagement.setLastUpdateTime(DateUtils.getNowDate());
            if("0".equals(rmAgentManagement.getMethod())){
                rmAgentManagement.setScheduledUpdateTime(null);
            }
            rmAgentManagementMapper.insertRmAgentManagement(rmAgentManagement);
        }
        // 构建更新策略
        AgentUpdateVo agentUpdateVo = new AgentUpdateVo();
        agentUpdateVo.setFileUrl(rmAgentManagement.getFileUrl());
        agentUpdateVo.setFilePath(filePath);
        List<String> commandList = new ArrayList<>();
        commandList.add(COMMAND);
        agentUpdateVo.setCommands(JSONObject.toJSONString(commandList));
        agentUpdateVo.setMethod(rmAgentManagement.getMethod());
        if(rmAgentManagement.getMethod() == 1){
            Date scheduledUpdateTime = rmAgentManagement.getScheduledUpdateTime();
            long scheduledTime = scheduledUpdateTime.toInstant().getEpochSecond();
            agentUpdateVo.setPolicyTime(scheduledTime);
        }
        try {
            DeviceMessage deviceMessage = new DeviceMessage();
            deviceMessage.setClientId(rmAgentManagement.getHardwareSn());
            deviceMessage.setDataType(MsgEnum.Agent版本更新.getValue());
            deviceMessage.setData(JSONObject.toJSONString(agentUpdateVo));
            MessageProducer messageProducer = new MessageProducer();

            messageProducer.sendAsyncProducerMessage(
                    producerMode.getAgentTopic(),
                    "",
                    "",
                    JSONObject.toJSONString(deviceMessage)
            );
        } catch (Exception e) {
            log.error("发送设备配置失败，deviceId: {}", rmAgentManagement.getHardwareSn(), e);
        }
    }
    /**
     * 处理agen更新数据
     * @param rmAgentManagement
     */
    public void processAgentData(RmAgentManagement rmAgentManagement){
        String clientIds = rmAgentManagement.getDeployDevice();
        String[] clientIdArr = clientIds.split("\n");
        for (String clientId : clientIdArr) {
            // 创建新的对象，避免污染原始数据
            RmAgentManagement currentAgent = new RmAgentManagement();
            // 复制原始对象的属性
            BeanUtils.copyProperties(rmAgentManagement, currentAgent);
            // 设置当前循环的 clientId
            currentAgent.setClientId(clientId);
            currentAgent.setDeployDevice(clientId);
            // 查询该资源是否已经配置
            RmAgentManagement agentQueryParam = new RmAgentManagement();
            agentQueryParam.setClientId(clientId);
            List<RmAgentManagement> agentManagements = rmAgentManagementMapper.selectRmAgentManagementList(agentQueryParam);
            if(!agentManagements.isEmpty()){
                // 如果存在，修改
                currentAgent.setLastUpdateTime(DateUtils.getNowDate());
                if("0".equals(rmAgentManagement.getMethod())){
                    currentAgent.setScheduledUpdateTime(null);
                }
                rmAgentManagementMapper.updateRmAgentManagement(currentAgent);
            }else{
                // 如果不存在，添加
                currentAgent.setLastUpdateTime(DateUtils.getNowDate());
                if("0".equals(rmAgentManagement.getMethod())){
                    currentAgent.setScheduledUpdateTime(null);
                }
                rmAgentManagementMapper.insertRmAgentManagement(currentAgent);
            }
            // 构建更新策略
            AgentUpdateMsgVo agentUpdateMsgVo = new AgentUpdateMsgVo();
            agentUpdateMsgVo.setFileUrl(rmAgentManagement.getFileUrl());
            agentUpdateMsgVo.setFileMd5(rmAgentManagement.getFileMd5());
            agentUpdateMsgVo.setMethod(rmAgentManagement.getMethod());
            if(rmAgentManagement.getMethod() == 1){
                Date scheduledUpdateTime = rmAgentManagement.getScheduledUpdateTime();
                long scheduledTime = scheduledUpdateTime.toInstant().getEpochSecond();
                agentUpdateMsgVo.setPolicyTime(scheduledTime);
            }
            try {
                PolicyVo<AgentUpdateMsgVo> policyVo = new PolicyVo();
                List<AgentUpdateMsgVo> list = new ArrayList<>();
                list.add(agentUpdateMsgVo);
                policyVo.setContents(list);
                String policyVoStr = JSONObject.toJSONString(policyVo);
                PolicyTypeVo policyTypeVo = new PolicyTypeVo();
                policyTypeVo.setVersions(policyVoStr);
                String configJson = JSONObject.toJSONString(policyTypeVo);
                DeviceMessage deviceMessage = new DeviceMessage();
                deviceMessage.setClientId(clientId);
                deviceMessage.setDataType(MsgEnum.获取最新策略应答.getValue());
                deviceMessage.setData(configJson);
                MessageProducer messageProducer = new MessageProducer();

                messageProducer.sendAsyncProducerMessage(
                        producerMode.getAgentTopic(),
                        "",
                        "",
                        JSONObject.toJSONString(deviceMessage)
                );
            } catch (Exception e) {
                log.error("发送设备配置失败，deviceId: {}", rmAgentManagement.getHardwareSn(), e);
            }
        }
    }
}
