package com.goomood.phm.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.goomood.common.constant.Constants;
import com.goomood.common.exception.ServiceException;
import com.goomood.common.utils.StringUtils;

import com.goomood.framework.config.ServerConfig;
import com.goomood.phm.domain.KGraphClause;
import com.goomood.phm.domain.KGraphEntity;
import com.goomood.phm.domain.KGraphTask;
import com.goomood.phm.domain.TechData;
import com.goomood.phm.domain.dto.CataiDTO;
import com.goomood.phm.domain.dto.ExtraKGraphTaskDTO;
import com.goomood.phm.domain.dto.ExtraKGraphTaskStatusDTO;
import com.goomood.phm.domain.dto.ReturnCatAiDTO;
import com.goomood.phm.enums.GraphStatus;
import com.goomood.phm.mapper.KGraphTaskMapper;
import com.goomood.phm.mapper.TechDataMapper;
import com.goomood.phm.service.IKGraphClauseService;
import com.goomood.phm.service.IKGraphEntityService;
import com.goomood.phm.service.IKGraphTaskService;
import com.goomood.phm.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.*;

/**
 * 知识图谱任务Service业务层处理
 *
 * @author wyj
 * @date 2025-07-21
 */
@Service
@Slf4j
public class KGraphTaskServiceImpl implements IKGraphTaskService {
    @Resource
    private KGraphTaskMapper kGraphTaskMapper;
    @Resource
    private IKGraphClauseService kGraphClauseService;
    @Resource
    private IKGraphEntityService kGraphEntityService;
    @Resource
    private TechDataMapper techDataMapper;
    @Resource
    private ServerConfig serverConfig;

    @Value("${kgqa.ask-url}")
    private String askUrl;

    @Value("${kgqa.clause-url}")
    private String clauseUrl;

    @Value("${kgqa.extract-url}")
    private String extractUrl;
    //
    @Value("${kgqa.storage-url}")
    private String storageUrl;
    @Value("${server.port:8080}")
    private Long port;
    /**
     * 分页查询知识图谱任务列表
     *
     * @param po 知识图谱任务Bo
     * @return 分页知识图谱任务集合
     */
    @Override
    public List<KGraphTask> selectPage(KGraphTask po) {
        QueryWrapper<KGraphTask> wrapper = new QueryWrapper<>();
        List<KGraphTask> kGraphTasks = kGraphTaskMapper.selectList(wrapper);
        return kGraphTasks;
    }
    /**
     * 查询知识图谱任务
     *
     * @param id 知识图谱任务主键
     * @return 知识图谱任务
     */
    @Override
    public KGraphTask selectById(Long id) {
        return kGraphTaskMapper.selectById(id);
    }
    /**
     * 新增知识图谱任务
     *
     * @param po 知识图谱任务Bo
     * @return 结果:true 操作成功，false 操作失败
     */
    @Override
    public boolean insert(KGraphTask po) {
        int rows = kGraphTaskMapper.insert(po);
        return rows > 0;
    }
    public static String getIpAddress() {
        try {
            //从网卡中获取IP
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = allNetInterfaces.nextElement();
                //用于排除回送接口,非虚拟网卡,未在使用中的网络接口
                if (!netInterface.isLoopback() && !netInterface.isVirtual() && netInterface.isUp()) {
                    //返回和网络接口绑定的所有IP地址
                    Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                    while (addresses.hasMoreElements()) {
                        ip = addresses.nextElement();
                        if (ip instanceof Inet4Address) {
                            return ip.getHostAddress();
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.info("IP地址获取失败{}", e.getMessage());
        }
        return "127.0.0.1";
    }
    /**
     * 处理任务
     *
     * @param po 知识图谱任务Bo
     * @return 结果:true 操作成功，false 操作失败
     */
    @Override
    public boolean proTask(KGraphTask po ) {
        log.info("进入处理：{}", po.getTaskType());
        KGraphTask kGraphTaskVo = this.selectById(po.getId());
        Long ossId = kGraphTaskVo.getOssId();
        TechData techData = techDataMapper.selectTechDataById(ossId);
        String  filePath = Constants.HTTP + getIpAddress() + ":" + port  + techData.getFilePath();
        if(ObjectUtils.isEmpty(kGraphTaskVo)) {
            throw new ServiceException("任务为空，请核实任务ID");
        }
        String result;
        JSONObject jsonObject;
        ExtraKGraphTaskDTO extraGraphTaskVo = new ExtraKGraphTaskDTO();
        switch (po.getTaskType()) {
            case "0":
                updateStatus(po, kGraphTaskVo.getVersion(), GraphStatus.STATUS_1.getCode());
                // 知识图谱执行分句
                Map<String, Object> map = new HashMap<>();
                map.put("filePath", filePath);
                map.put("taskId", po.getId());
                result = HttpUtils.postJson(clauseUrl, map);
                jsonObject = JSON.parseObject(result);
                if (!StringUtils.equals("200", jsonObject.getString("code"))) {
                    throw new ServiceException(jsonObject.getString("msg"));
                }
                break;
            case "2":
                updateStatus(po, kGraphTaskVo.getVersion(), GraphStatus.STATUS_3.getCode());
                // 知识图谱抽取
                KGraphClause kGraphClauseBo = new KGraphClause();
                kGraphClauseBo.setTaskId(po.getId());
                List<KGraphClause> graphClauseVos = kGraphClauseService.selectList(kGraphClauseBo);
                extraGraphTaskVo.setTaskId(po.getId());
                extraGraphTaskVo.setGraphClauseList(graphClauseVos);
                result = HttpUtils.postJson(extractUrl, extraGraphTaskVo);
                jsonObject = JSON.parseObject(result);
                if (!StringUtils.equals("200", jsonObject.getString("code"))) {
                    throw new ServiceException(jsonObject.getString("msg"));
                }
                kGraphClauseBo.setStatus(GraphStatus.STATUS_3.getCode());
                kGraphClauseService.update(kGraphClauseBo);
                break;
            case "4":
                updateStatus(po, kGraphTaskVo.getVersion(), GraphStatus.STATUS_5.getCode());
                // 知识图谱入库
                List<KGraphEntity> graphEntityVos = kGraphEntityService.selectListByTaskId(po.getId());
                extraGraphTaskVo.setTaskId(po.getId());
                extraGraphTaskVo.setOssId(ossId);
                extraGraphTaskVo.setGraphEntityList(graphEntityVos);
                result = HttpUtils.postJson(storageUrl, extraGraphTaskVo);
                jsonObject = JSON.parseObject(result);
                if (!StringUtils.equals("200", jsonObject.getString("code"))) {
                    throw new ServiceException(jsonObject.getString("msg"));
                }
                break;
            default:
                throw new ServiceException("任务类型错误");
        }
        return true;
    }

    /**
     * 修改任务状态
     * @param po
     * @param version
     * @param status
     */
    private void updateStatus(KGraphTask po, Integer version, String status) {
        po.setVersion(version);
        this.update(po);
    }

    /**
     * 修改任务信息状态
     * @param po
     */
    @Override
    public Boolean update(KGraphTask po){
        if (ObjectUtils.isNotEmpty(po) && ObjectUtils.isNotEmpty(po.getId())){
            kGraphTaskMapper.updateById(po);
        }
       return false;
    }

    @Override
    public boolean deleteByIds(Long[] ids) {
        int i = kGraphTaskMapper.deleteBatchIds(Arrays.asList(ids));
        return i>1;
    }

    @Override
    public boolean resultCallback(ExtraKGraphTaskDTO dto) {
        if(ObjectUtils.isNotEmpty(dto.getGraphEntityList())){
            KGraphTask kGraphTaskVo = this.selectById(dto.getTaskId());
            KGraphTask kGraphTaskBo = new KGraphTask();
            kGraphTaskBo.setId(dto.getTaskId());
            kGraphTaskBo.setVersion(kGraphTaskVo.getVersion());
            kGraphTaskBo.setStatus(StringUtils.equals(dto.getTaskType(), "1") ? GraphStatus.STATUS_2.getCode() : GraphStatus.STATUS_4.getCode());
            return this.update(kGraphTaskBo);
        }
        if (StringUtils.equals(dto.getTaskType(), "1")) {
            boolean isSave = kGraphClauseService.saveBatch(dto.getGraphClauseList());
            if (!isSave) {
                return false;
            }

        } else if (StringUtils.equals(dto.getTaskType(), "2")) {
            boolean isSave = kGraphEntityService.saveBatch(dto.getGraphEntityList());
            if (!isSave) {
                return false;
            }
        }
        return false;
    }

    @Override
    public boolean statusCallback(ExtraKGraphTaskStatusDTO extraKGraphTaskStatusDTO) {
        KGraphTask kGraphTaskVo = this.selectById(extraKGraphTaskStatusDTO.getTaskId());
        KGraphTask po = new KGraphTask();
        po.setId(extraKGraphTaskStatusDTO.getTaskId());
        po.setVersion(kGraphTaskVo.getVersion());
        po.setStatus(extraKGraphTaskStatusDTO.getStatus());
        return this.update(po);
    }

    public Object catai(CataiDTO dto) {
        ReturnCatAiDTO returnCatAiDTO = new ReturnCatAiDTO();
        if (ObjectUtils.isNotEmpty(dto)){
            String returnData = HttpUtils.postJson(askUrl, dto);
            JSONObject jsonObject = JSON.parseObject(returnData);
            if(jsonObject.get("code").equals(200)){ // 假设code是数字类型
                JSONObject data = jsonObject.getJSONObject("data");
                if (data != null) {
                    returnCatAiDTO.setUser_id(data.getString("user_id"));
                    returnCatAiDTO.setAnswer(data.getString("answer"));
                    returnCatAiDTO.setOssID(data.getString("ossID"));
                    returnCatAiDTO.setFile_name(data.getString("file_name"));
                    returnCatAiDTO.setGraph(data.getString("graph"));
                }
                return returnCatAiDTO;
            } else {
                throw new ServiceException(jsonObject.getString("msg"));
            }
        }
        return false;
    }
}
