package com.xueyi.nlt.nlt.controller;


import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xueyi.common.cache.utils.SourceUtil;
import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.common.core.web.result.R;
import com.xueyi.common.core.web.validate.V_A;
import com.xueyi.common.core.web.validate.V_E;
import com.xueyi.common.log.annotation.Log;
import com.xueyi.common.log.enums.BusinessType;
import com.xueyi.common.security.annotation.Logical;
import com.xueyi.common.security.annotation.RequiresPermissions;
import com.xueyi.common.web.entity.controller.BaseController;
import com.xueyi.nlt.api.netty.domain.vo.DmWebSocketMessageVo;
import com.xueyi.nlt.api.nlt.domain.vo.DmLandingLlmVo;
import com.xueyi.nlt.api.nlt.domain.vo.DmRecognitionVo;
import com.xueyi.nlt.api.nlt.feign.RemoteIntentService;
import com.xueyi.nlt.api.nlt.feign.RemoteLandingLlmService;
import com.xueyi.nlt.api.nlt.feign.RemoteQAService;
import com.xueyi.nlt.netty.client.WebSocketClient;
import com.xueyi.nlt.nlt.domain.dto.DmIntentDto;
import com.xueyi.nlt.nlt.domain.query.DmIntentQuery;
import com.xueyi.nlt.api.nlt.domain.vo.DmIntentVo;
import com.xueyi.nlt.nlt.domain.vo.IntentTemplateVo;
import com.xueyi.nlt.api.nlt.domain.vo.TaskKnowledgeVo;
import com.xueyi.nlt.nlt.service.IDmIntentService;
import com.xueyi.nlt.nlt.template.GenerativeKnowledgeTemplate;
import com.xueyi.nlt.nlt.template.MeetingOrderTemplate;
import com.xueyi.system.api.digitalmans.domain.dto.DmManDeviceDto;
import com.xueyi.system.api.digitalmans.feign.RemoteDigitalmanService;
import com.xueyi.system.api.digitalmans.feign.RemoteManDeviceService;
import com.xueyi.system.api.digitalmans.feign.RemoteQuestionanswersService;
import com.xueyi.system.api.model.Source;
import com.xueyi.system.api.organize.domain.dto.SysEnterpriseDto;
import com.xueyi.system.api.organize.feign.RemoteEnterpriseService;
import com.xueyi.tenant.api.tenant.domain.dto.TeTenantDto;
import com.xueyi.tenant.api.tenant.feign.RemoteTenantService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.xueyi.common.core.constant.digitalman.SkillConstants.SkillType;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/intent")
public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDto, IDmIntentService> {

    private static final Logger log = LoggerFactory.getLogger(DmIntentController.class);
    @Autowired
    IDmIntentService dmIntentService;

    @Autowired
    WebSocketClient webSocketClient;

    /** 定义节点名称 */
    @Override
    protected String getNodeName() {
        return "意图管理 ";
    }


    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate2;



    @Autowired
    private RemoteManDeviceService manDeviceService;

    @Autowired
    private RemoteIntentService remoteIntentService;
    
    @Autowired
    private MeetingOrderTemplate meetingOrderTemplate;

    @Autowired
    private GenerativeKnowledgeTemplate generativeKnowledgeTemplate;

    @Autowired
    private RemoteQuestionanswersService questionanswersService;

    @Autowired
    RemoteEnterpriseService enterpriseService;

    @Autowired
    RemoteLandingLlmService remoteLandingLlmService;

    @Autowired
    RemoteQAService remoteQAService;

    @Autowired
    RemoteDigitalmanService remoteDigitalmanService;
    /**
     * 意图请求
     列表
     */
    @PostMapping("/api/conversation")
    @ResponseBody
    public AjaxResult conversationApi(@RequestBody DmIntentVo intent) {
        log.info("交互对象：{}", intent.toString());
        redisTemplate.opsForValue().increment("dashboard:server", 1);
        // 获取今天日期，并格式化成yyyy-MM-dd
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String today = sdf.format(new Date());
        redisTemplate.opsForValue().increment(("dashboard:server-chart:" + today), 1);
        R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(intent.getDevId());
        Source source = SourceUtil.getSourceCache(manDeviceDtoR.getData().getStrategyId());
        R<JSONObject> jsonObjectR = remoteIntentService.conversationInner(intent,  manDeviceDtoR.getData().getTId(), source.getMaster(), SecurityConstants.INNER);
        IntentTemplateVo voResult = new IntentTemplateVo();
        voResult.setMsg("");
        if (jsonObjectR.getData() != null) {
            voResult.setTarget(1);
        } else {
            voResult.setTarget(0);
        }
        voResult.setFormat(jsonObjectR.getData());
        return AjaxResult.success(voResult);
    }

    /**
     * 意图请求
     列表
     */
    @PostMapping("/api/say_hello")
    @ResponseBody
    public AjaxResult sayHelloApi(@RequestBody DmRecognitionVo recognition) {
        log.info(recognition.toString());
        redisTemplate.opsForValue().increment("dashboard:recognition", 1);

        redisTemplate.opsForValue().increment("dashboard:conversation-times", 1);
        JSONObject joResult = new JSONObject();
        joResult.put("msg","");
        joResult.put("target",0);
        if (StringUtils.isNotEmpty(recognition.getRegistered()) && recognition.getRegistered().equals("1")) {

            Map cntMap = redisTemplate.opsForHash().entries("group:nlp" + ":" + recognition.getPersonId());
            //遍历key和value
            for (Object key : cntMap.keySet()) {
                String value = (String) cntMap.get(key);
                if (String.valueOf(key).equals("meeting")) {
                    JSONObject jo = JSONObject.parseObject(value);
                    // 判断是否在30分钟内
                    System.out.println("timestamp:" + jo.get("timestamp"));
                    System.out.println("currenttime:" + System.currentTimeMillis());
                    if(jo.containsKey("timestamp") &&
                            Double.valueOf(String.valueOf(jo.get("timestamp"))) - System.currentTimeMillis() < 1800000) {
                        joResult.put("msg",jo.get("content"));
                        joResult.put("target",1);
                        redisTemplate.opsForHash().delete("group:nlp" + ":" + recognition.getPersonId(), "meeting");
                        redisTemplate.opsForValue().increment("dashboard:conversation-duration", jo.get("content").toString().length() / 4);
                        return AjaxResult.success(joResult);
                    } else if (Double.valueOf(String.valueOf(jo.get("timestamp"))) - System.currentTimeMillis() < 0) {
                        redisTemplate.opsForHash().delete("group:nlp" + ":" + recognition.getPersonId(), "meeting");
                    }
                } else {
                    joResult.put("msg",value);
                    redisTemplate.opsForValue().increment("dashboard:conversation-duration", value.toString().length() / 4);
                    joResult.put("target",1);
                    redisTemplate.opsForHash().delete("group:nlp" + ":" + recognition.getPersonId(),key);
                    return AjaxResult.success(joResult);
                }
            }
        }
        redisTemplate.opsForValue().increment("dashboard:conversation-duration", 3);
        return AjaxResult.success(joResult);
    }

    /**
     * 知识库问答请求
     */
    @PostMapping("/api/searchQA")
    @ResponseBody
    public AjaxResult searchQA(@RequestBody DmIntentVo intent) {
        log.info("交互对象：{}",intent.toString());
        redisTemplate.opsForValue().increment("dashboard:recognition", 1);
        JSONObject joResult = new JSONObject();
        joResult.put("msg","");
        joResult.put("target",0);
        DmLandingLlmVo vo = new DmLandingLlmVo();
        vo.setCategory("bj_unicom");
        vo.addDmLlm("user", intent.getContent());
        JSONObject testJ = new JSONObject();
        testJ.put("category","bj_unicom");
        JSONArray ja1 = new JSONArray();
        JSONObject jo = new JSONObject();
        jo.put("role","user");
        jo.put("content",intent.getContent());
        ja1.add(jo);
        testJ.put("messages",ja1);
        R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(intent.getDevId());
        Source source = SourceUtil.getSourceCache(manDeviceDtoR.getData().getStrategyId());
        return remoteQAService.query(manDeviceDtoR.getData().getManCode(),intent.getContent(),manDeviceDtoR.getData().getTId());

//        JSONArray ja = JSONArray.parseArray(resultJson.get("data").toString());
//
//        if (ja.size() > 0) {
//            joResult.put("msg",ja.getJSONObject(0).get("text"));
//            joResult.put("target",1);
//        }
//        return AjaxResult.success(joResult);
    }

    /**
     * 联动北方大模型请求
     */
    @PostMapping("/api/searchQuestionAnswer")
    @ResponseBody
    public AjaxResult searchQuestionAnswer(@RequestBody DmIntentVo intent) {
        log.info("交互对象：{}",intent.toString());
        redisTemplate.opsForValue().increment("dashboard:recognition", 1);
        JSONObject joResult = new JSONObject();
        joResult.put("msg","");
        joResult.put("target",0);
        DmLandingLlmVo vo = new DmLandingLlmVo();
        vo.setCategory("bj_unicom");
        vo.addDmLlm("user", intent.getContent());
        JSONObject testJ = new JSONObject();
        testJ.put("category","bj_unicom");
        JSONArray ja1 = new JSONArray();
        JSONObject jo = new JSONObject();
        jo.put("role","user");
        jo.put("content",intent.getContent());
        ja1.add(jo);
        testJ.put("messages",ja1);
        JSONObject resultJson = remoteLandingLlmService.query(testJ);
        JSONArray ja = resultJson.getJSONArray("data");

        if (ja.size() > 0) {
            joResult.put("msg",ja.getJSONObject(0).get("text"));
            joResult.put("target",1);
        }
        return AjaxResult.success(joResult);
    }


    /**
     * 意图请求列表
     */
    @PostMapping("/inner/conversation")
    @ResponseBody
    public R<JSONObject> conversationInner(@RequestBody DmIntentVo intent) {
        JSONObject joResult = null;
        if (StringUtils.isEmpty(intent.getSkillCode())) {
            // 调用知识库问答
            AjaxResult qaAjax = searchQA(intent);
            return R.ok(JSONObject.from(qaAjax.get("data")));
        }
        SkillType.BOOK_MEETING_ROOM.getCode();
        // 判断skill code的值
        if (SkillType.BOOK_MEETING_ROOM.getCode().equals(intent.getSkillCode())) {
            // 获取名称为"meeting-order"的BaseTemplate的实例
            redisTemplate.opsForValue().increment("dashboard:meeting", 1);
            joResult = meetingOrderTemplate.handle(intent.getDevId(),intent.getContent());
        } else if (SkillType.CREATE_VISITOR_INFO.getCode().equals(intent.getSkillCode())) {
            // 访客预定
            redisTemplate.opsForValue().increment("dashboard:create_visitor_info", 1);
        } else if (SkillType.REGISTER_VISITOR.getCode().equals(intent.getSkillCode())) {
            // 访客登记
            redisTemplate.opsForValue().increment("dashboard:register_visitor", 1);
        } else if (SkillType.BROADCAST_DISPLAY.getCode().equals(intent.getSkillCode())) {
            // 播报展示
            redisTemplate.opsForValue().increment("dashboard:broadcast_display", 1);
        } else if (SkillType.OPEN_DOOR.getCode().equals(intent.getSkillCode())) {
            // 开门记录
            redisTemplate.opsForValue().increment("dashboard:open_door", 1);
        }
        return R.ok(joResult);
    }

    /**
     * 意图请求
     列表
     */
    @PostMapping("/inner/sendMessage")
    @ResponseBody
    public R<Object> sendMessage(@RequestBody DmWebSocketMessageVo message) {

        log.info("websocket sendMessage:{}", message);
        if (message == null || message.getFormat() == null) {
            return R.fail("参数为空");
        }
        JSONObject jo = message.getFormat();
        SimpleDateFormat dateFormat3 = new SimpleDateFormat("MM-dd");
        Double timestamp = Double.valueOf((String)jo.get("timestamp"));
        String meetingRoom = jo.getString("meetingRoom");
        Date date = new Date(timestamp.longValue());
        if (message.getSkillCode().equals("1")) {
            String prefix = "假设你是一名公司前台，你看到在你们公司工作的\\"+ jo.getString("orderName")+ "\\，请你从个人角度提醒他参加\\" +
                    dateFormat3.format(timestamp) + "\\在\\" + meetingRoom + "\\的会，要求语气友好。输出只包含你要对他说的话，在20字左右。";
            webSocketClient.sendMsg(prefix);
            // 设置缓存
            redisTemplate2.opsForValue().set("gpt:websocket" + ":" + "1", message);
        }
        return R.ok();
    }

    /**
     * 意图请求
     列表
     */
    @PostMapping("/inner/taskGenerativeKnowledge")
    @ResponseBody
    public R<Object> taskGenerativeKnowledge() {

        // 从列表中获取知识库任务
        TaskKnowledgeVo vo = (TaskKnowledgeVo) redisTemplate2.opsForList().leftPop("group:task");
        log.info("交互对象：{}",vo.toString());
        if (vo == null) {
            return R.ok(null,"没有任务");
        }
        JSONObject joResult = generativeKnowledgeTemplate.handle(null,vo.getContent());

        if (joResult == null) {
            redisTemplate2.opsForList().rightPush("group:task", vo);
            return R.ok(null,"任务处理失败，重新放入队列");
        }

        R<SysEnterpriseDto> enterpriseDtoR = enterpriseService.getInfo(vo.getTenantId());
        if (enterpriseDtoR.isFail()) {
            log.warn("任务执行失败：{}",vo);
        }
        Source source = SourceUtil.getSourceCache(enterpriseDtoR.getData().getStrategyId());
        questionanswersService.batchInsertInner(vo.getManId(), JSONArray.from(joResult.get("questions")),vo.getTenantId(),source.getMaster(),SecurityConstants.INNER);

        return R.ok(null,"处理成功");
    }

    /**
     * 查询意图管理
     列表
     */
    @Override
    @GetMapping("/list")
    @RequiresPermissions(Auth.DM_INTENT_LIST)
    public AjaxResult list(DmIntentQuery intent) {
        return super.list(intent);
    }

    /**
     * 查询意图管理
     详细
     */
    @Override
    @GetMapping(value = "/{id}")
    @RequiresPermissions(Auth.DM_INTENT_SINGLE)
    public AjaxResult getInfo(@PathVariable Serializable id) {
        return super.getInfo(id);
    }

    /**
     * 意图管理
     新增
     */
    @Override
    @PostMapping
    @RequiresPermissions(Auth.DM_INTENT_ADD)
    @Log(title = "意图管理", businessType = BusinessType.INSERT)
    public AjaxResult add(@Validated({V_A.class}) @RequestBody DmIntentDto intent) {
        return super.add(intent);
    }

    /**
     * 意图管理
     修改
     */
    @Override
    @PutMapping
    @RequiresPermissions(Auth.DM_INTENT_EDIT)
    @Log(title = "意图管理", businessType = BusinessType.UPDATE)
    public AjaxResult edit(@Validated({V_E.class}) @RequestBody DmIntentDto intent) {
        return super.edit(intent);
    }

    /**
     * 意图管理
     修改状态
     */
    @Override
    @PutMapping("/status")
    @RequiresPermissions(value = {Auth.DM_INTENT_EDIT, Auth.DM_INTENT_ES}, logical = Logical.OR)
    @Log(title = "意图管理", businessType = BusinessType.UPDATE_STATUS)
    public AjaxResult editStatus(@RequestBody DmIntentDto intent) {
        return super.editStatus(intent);
    }

    /**
     * 意图管理
     批量删除
     */
    @Override
    @DeleteMapping("/batch/{idList}")
    @RequiresPermissions(Auth.DM_INTENT_DEL)
    @Log(title = "意图管理", businessType = BusinessType.DELETE)
    public AjaxResult batchRemove(@PathVariable List<Long> idList) {
        return super.batchRemove(idList);
    }

    /**
     * 获取意图管理
     选择框列表
     */
    @Override
    @GetMapping("/option")
    public AjaxResult option() {
        return super.option();
    }



    interface Auth {
        /** 系统 - 意图管理
         管理 - 列表 */
        String DM_INTENT_LIST = "nlt:intent:list";
        /** 系统 - 意图管理
         管理 - 详情 */
        String DM_INTENT_SINGLE = "nlt:intent:single";
        /** 系统 - 意图管理
         管理 - 新增 */
        String DM_INTENT_ADD = "nlt:intent:add";
        /** 系统 - 意图管理
         管理 - 修改 */
        String DM_INTENT_EDIT = "nlt:intent:edit";
        /** 系统 - 意图管理
         管理 - 修改状态 */
        String DM_INTENT_ES = "nlt:intent:es";
        /** 系统 - 意图管理
         管理 - 删除 */
        String DM_INTENT_DEL = "nlt:intent:delete";
    }
}
