package com.infoepoch.pms.dispatchassistant.domain.langchain.chat;


import com.infoepoch.pms.dispatchassistant.common.component.SnowFlake;
import com.infoepoch.pms.dispatchassistant.common.exception.ValidationException;
import com.infoepoch.pms.dispatchassistant.common.utils.JsonUtils;
import com.infoepoch.pms.dispatchassistant.common.utils.RestTemplateUtils;
import com.infoepoch.pms.dispatchassistant.controller.basic.Auth;
import com.infoepoch.pms.dispatchassistant.domain.basic.store.KeyValueStoreService;
import com.infoepoch.pms.dispatchassistant.domain.basic.user.User;
import com.infoepoch.pms.dispatchassistant.domain.langchain.ChatConstants;
import com.infoepoch.pms.dispatchassistant.domain.langchain.chat.chat.ChatRequest;
import com.infoepoch.pms.dispatchassistant.domain.langchain.chat.knowledgeBaseChat.KnowledgeBaseChatRequest;
import com.infoepoch.pms.dispatchassistant.domain.langchain.history.*;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class ChatService {

    @Autowired
    private RestTemplateUtils restTemplateUtils;

    @Autowired
    private KeyValueStoreService keyValueStoreService;

    @Autowired
    private Auth auth;
    @Autowired
    private IConversationsRepository iConversationsRepository;

    @Autowired
    private IMessagesRepository iMessagesRepository;

    /**
     * 与LLM模型对话
     *
     * @param request 请求
     * @return 请求结果字符串
     */
    public String chat(ChatRequest request) {
        // 从KEY_VALUE_STORE表中获取chat请求地址
        String url = keyValueStoreService.queryValueByKey(ChatConstants.URL_CHAT_CHAT);
        if (url == null)
            throw new ValidationException("请先配置chat请求地址");
        Map<String, Object> param = request.toMap();
        String result = restTemplateUtils.postForString(url, param);
        // 截取字符串
        result = subStringResult(result);
        // 判断请求结果是否报错
        judgeErrorResponse(result);
        return result;
    }

    /**
     * @param request
     * @return
     */
    public String knowledgeChat(KnowledgeBaseChatRequest request) {
        String url = keyValueStoreService.queryValueByKey(ChatConstants.URL_CHAT_KNOWLEDGE_BASE_CHAT);
        if (url == null)
            throw new ValidationException("请先配置知识库chat请求地址");
        Map<String, Object> param = request.toMap();
        String result = restTemplateUtils.postForString(url, param);
        // 截取字符串
        result = subStringResult(result);
        // 判断请求结果是否报错
        judgeErrorResponse(result);
        return result;
    }

    /**
     * 截取result结果字符串
     *
     * @param result
     * @return
     */
    private String subStringResult(String result) {
        if(result.startsWith("data")) {
            return result.substring(result.indexOf("data") + 5, result.length() - 1);
        } else {
            return result;
        }
    }

    /**
     * @param result
     */
    private void judgeErrorResponse(String result) {
        try {
            ErrorResponse response = JsonUtils.jsonToObject(result, ErrorResponse.class);
            if (response.getDetail() != null) {
                StringBuilder errorMessage = new StringBuilder();
                for (ErrorResponse.Detail detail : response.getDetail()) {
                    errorMessage.append(detail.getMsg()).append("；");
                }
                if (StringUtils.isNotBlank(errorMessage.toString())) {
                    throw new ValidationException(errorMessage.toString());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * @param dialogId
     * 新增会话
     */
    public Conversations saveConversations(String dialogId,String question,String aiType) {
        Conversations conversations=null;
        try {
            ConversationsCriteria conversationsCriteria=new ConversationsCriteria();
            conversationsCriteria.setSessionId(dialogId);
            List<Conversations>  conversationsList=iConversationsRepository.selectByCriteria(conversationsCriteria);
           if(conversationsList==null||conversationsList.size()<=0)
           {
               User user=  auth.getUserReq();
               conversations=new Conversations();
               conversations.setId(SnowFlake.instant().nextId().toString());
               conversations.setUserId(user.getId());
               conversations.setUserName(user.getUsername());
               conversations.setName(user.getFullname());
               if(question.length()>15000)
                   conversations.setFirstQuestion(question.substring(0,15000));
               else
                   conversations.setFirstQuestion(question);
               conversations.setAiType(aiType);
               conversations.setSessionId(dialogId);
               conversations.setRecordTime(new Date());
               conversations.setStatus("1");
               iConversationsRepository.insert(conversations);
           }else
               conversations=conversationsList.get(0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conversations;
    }

    //新增问题信息
    public Messages insertQuestionMessage(Conversations conversations,Messages questionMes) {
            //查找当前对话的父对话
           MessagesCriteria messagesCriteria=new MessagesCriteria();
           messagesCriteria.setSessionId(conversations.getSessionId());
           messagesCriteria.setCid(conversations.getId());
           Messages messagesLast=iMessagesRepository.selectOneByCriteria(messagesCriteria);
        if(questionMes.getContent().length()>15000)
            questionMes.setContent(questionMes.getContent().substring(0,15000));
        try {
            if(messagesLast!=null)
            {
                questionMes.setParentMsgId(messagesLast.getId());
                questionMes.setSort(messagesLast.getSort()+1);
            }else
            {
                questionMes.setSort(1);
            }
            String id=SnowFlake.instant().nextId().toString();
            questionMes.setId(id);
            questionMes.setCid(conversations.getId());
            questionMes.setSessionId(conversations.getSessionId());
            questionMes.setRecordTime(new Date());
            iMessagesRepository.insert(questionMes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return questionMes;
    }

    //新增回答信息
    public Messages insertMessage(Conversations conversations,Messages contMes) {
        try {
            String id=SnowFlake.instant().nextId().toString();
            contMes.setId(id);
            contMes.setCid(conversations.getId());
            contMes.setSessionId(conversations.getSessionId());
            contMes.setRecordTime(new Date());
            iMessagesRepository.insert(contMes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return contMes;
    }

    //更新回答信息
    public Messages updateMessage(Messages contMes) {
        try {
            if(contMes.getContent().length()>15000)
                contMes.setContent(contMes.getContent().substring(0,15000));
            iMessagesRepository.update(contMes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return contMes;
    }

    //查询近7天的会话信息
    public List<Map<String,Object>> conversationHistory()
    {
        List<Map<String,Object>> mapList=new ArrayList<>();
        try {
        User user=  auth.getUserReq();
        ConversationsCriteria conversationsCriteria=new ConversationsCriteria();
        conversationsCriteria.setUserId(user.getId());
        conversationsCriteria.setConversationsDays(7);
        List<Conversations>  conversationsList=iConversationsRepository.selectByCriteria(conversationsCriteria);
        if(conversationsList!=null&&conversationsList.size()>0)
        {
            Date todayDate=getToday();
            Date yesterday=getYesterday();
            Map<String,Object>  todayMap=new HashMap<>();
            Map<String,Object>  yesterdayMap=new HashMap<>();
            Map<String,Object>  sevendayMap=new HashMap<>();
            List<Map<String,Object>> todayMapList=new ArrayList<>();
            List<Map<String,Object>> yesterdayMapList=new ArrayList<>();
            List<Map<String,Object>> sevendayMapList=new ArrayList<>();
            todayMap.put("label","今天");
            yesterdayMap.put("label","昨天");
            sevendayMap.put("label","7天内");
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
            for (Conversations conversations:
                    conversationsList) {
                if(conversations.getRecordTime().after(todayDate))
                {
                    Map<String,Object> td=new HashMap<>();
                    td.put("id",conversations.getSessionId());
                    td.put("title",conversations.getFirstQuestion());
                    td.put("time",simpleDateFormat.format(conversations.getRecordTime()));
                    td.put("active",false);
                    td.put("showMenu",false);
                    td.put("selectedExpert",conversations.getAiType());
                    todayMapList.add(td);
                }else if(conversations.getRecordTime().before(todayDate)&&conversations.getRecordTime().after(yesterday))
                {
                    Map<String,Object> yd=new HashMap<>();
                    yd.put("id",conversations.getSessionId());
                    yd.put("title",conversations.getFirstQuestion());
                    yd.put("time",simpleDateFormat.format(conversations.getRecordTime()));
                    yd.put("active",false);
                    yd.put("showMenu",false);
                    yd.put("selectedExpert",conversations.getAiType());
                    yesterdayMapList.add(yd);
                }else
                {
                    Map<String,Object> sd=new HashMap<>();
                    sd.put("id",conversations.getSessionId());
                    sd.put("title",conversations.getFirstQuestion());
                    sd.put("time",simpleDateFormat.format(conversations.getRecordTime()));
                    sd.put("active",false);
                    sd.put("showMenu",false);
                    sd.put("selectedExpert",conversations.getAiType());
                    sevendayMapList.add(sd);
                }
            }
            todayMap.put("items",todayMapList);
            yesterdayMap.put("items",yesterdayMapList);
            sevendayMap.put("items",sevendayMapList);
            mapList.add(todayMap);
            mapList.add(yesterdayMap);
            mapList.add(sevendayMap);
        }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mapList;
    }

    //查询会话内容通过会话id
    public  List<Messages>  conversationMessages(String sessionId)
    {
        List<Messages>  messagesList=new ArrayList<>();
        try {
        MessagesCriteria messagesCriteria=new MessagesCriteria();
        messagesCriteria.setSessionId(sessionId);
       messagesList= iMessagesRepository.selectByCriteria(messagesCriteria);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return messagesList;
    }

    //删除会话内容通过会话id
    public void deleteChat(String sessionId)
    {
        try {
            iMessagesRepository.deleteBySessionId(sessionId);
            iConversationsRepository.deleteBySessionId(sessionId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public Date getToday()
    {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);    // 设置小时为 0
        calendar.set(Calendar.MINUTE, 0);         // 分钟归零
        calendar.set(Calendar.SECOND, 0);         // 秒归零
        calendar.set(Calendar.MILLISECOND, 0);    // 毫秒归零
       return calendar.getTime();
    }

    public Date getYesterday()
    {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, -1);   // 减 1 天
        calendar.set(Calendar.HOUR_OF_DAY, 0);    // 小时归零
        calendar.set(Calendar.MINUTE, 0);         // 分钟归零
        calendar.set(Calendar.SECOND, 0);         // 秒归零
        calendar.set(Calendar.MILLISECOND, 0);    // 毫秒归零
        return calendar.getTime();
    }

    //获取当前用户所在的地市
    public String getAuthRegionName()
    {
        String regionName="";
        try {
            User user = auth.getUserReq();
            String[] rganizationNameList=user.getOrganizationName().split("\\\\");
            if(rganizationNameList.length>=2)
            {
                regionName=rganizationNameList[1];
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return regionName;
    }


    //获取调用地址
    public String getUrl(String selectedExpert)
    {
        String url="http://10.32.41.35:40517/scene_gateway/agent/6809d0895428476bb6789ad70c525c97";
        if("外部专家".equals(selectedExpert))
            url="http://10.32.41.35:40517/scene_gateway/agent/b6d5bceecb5644cf953d9cc859bd36d3";
        return url;
    }

}
