package com.qiuguo.iot.third.service;

import com.qiuguo.iot.base.enums.YesNo;
import com.qiuguo.iot.third.enums.ChinesePartSpeechEnum;
import com.qiuguo.iot.base.enums.DeviceTypeEnum;
import com.qiuguo.iot.base.utils.StringUtils;
import com.qiuguo.iot.data.entity.device.DeviceUserBindEntity;
import com.qiuguo.iot.data.entity.system.SystemTalkAnswerConfigEntity;
import com.qiuguo.iot.data.request.device.DeviceUserBindRequest;
import com.qiuguo.iot.data.service.device.DeviceUserBindService;
import com.qiuguo.iot.data.service.system.SystemTalkAnswerConfigService;
import com.qiuguo.iot.third.nlp.NlpKey;
import com.qiuguo.iot.third.nlp.action.Action;
import com.qiuguo.iot.third.nlp.action.ActionTime;
import com.qiuguo.iot.third.nlp.action.Actions;
import com.qiuguo.iot.third.nlp.entity.SystemTalkKeyAndDeviceName;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.*;

@Service
@Slf4j
public class NlpService {
    @Resource
    private LacNlpService liguoNlpService;

    @Resource
    private DeviceUserBindService deviceUserBindService;

    @Resource
    private SystemTalkAnswerConfigService systemTalkAnswerConfigService;

    /**
     * 查询最多设备数量
     */
    private static Integer MAX_COUT = 2000;

    public Mono<Actions> getActionWithLacSingle(Long userId, String text){
        if(userId != null){
            DeviceUserBindRequest request = new DeviceUserBindRequest();
            request.setUserId(userId);
            //涂鸦设备
            request.setDeviceType(DeviceTypeEnum.ELECTRIC_SOCKET.getCode());
            request.setPageSize(MAX_COUT);
            return deviceUserBindService.selectDeviceUserBindsByRequest(request).flatMap(deviceUserBindEntityPagerResult -> {
                if(deviceUserBindEntityPagerResult.getData().size() > 0){
                    /*List<DeviceUserBindEntity> list = deviceUserBindEntityPagerResult.getData();
                    list.sort((a, b) -> {
                        return b.getBindName().length() - a.getBindName().length();
                    });//按照名称由长到短排序*/
                    List<DeviceUserBindEntity> includs = new ArrayList<>();
                    List<SystemTalkAnswerConfigEntity> commands = new ArrayList<>();
                    List<SystemTalkKeyAndDeviceName> systemTalkKeyAndDeviceNameList = new ArrayList<>();
                    int i = 0;
                    for(SystemTalkAnswerConfigEntity entity : systemTalkAnswerConfigService.getCommandList()){
                        SystemTalkKeyAndDeviceName systemTalkKeyAndDeviceName = new SystemTalkKeyAndDeviceName();
                        systemTalkKeyAndDeviceName.setKey(entity.getAskKey());
                        systemTalkKeyAndDeviceName.setType(0);
                        systemTalkKeyAndDeviceName.setIndex(i++);
                        systemTalkKeyAndDeviceNameList.add(systemTalkKeyAndDeviceName);
                    }

                    i = 0;
                    for(DeviceUserBindEntity entity : deviceUserBindEntityPagerResult.getData()){
                        SystemTalkKeyAndDeviceName systemTalkKeyAndDeviceName = new SystemTalkKeyAndDeviceName();
                        systemTalkKeyAndDeviceName.setKey(entity.getBindName());
                        systemTalkKeyAndDeviceName.setType(1);
                        systemTalkKeyAndDeviceName.setIndex(i++);
                        systemTalkKeyAndDeviceNameList.add(systemTalkKeyAndDeviceName);
                    }
                    //字符由长到短排序
                    systemTalkKeyAndDeviceNameList.sort((a, b) ->{
                        return b.getKey().length() - a.getKey().length();
                    });

                    String pText = text;
                    i = 0;
                    int j = 0;
                    for(SystemTalkKeyAndDeviceName sysTalkKeyAndDeviceName :systemTalkKeyAndDeviceNameList){
                        if(pText.indexOf(sysTalkKeyAndDeviceName.getKey()) >= 0){
                            //找到对应的名称
                            if(sysTalkKeyAndDeviceName.getType().equals(YesNo.YES.getCode())){
                                //用户绑定设备名称
                                pText = pText.replace(sysTalkKeyAndDeviceName.getKey(), ">" + (i++) + ">");
                                includs.add(deviceUserBindEntityPagerResult.getData().get(sysTalkKeyAndDeviceName.getIndex()));
                            }else{
                                //是系统自定义动词后的名称
                                pText = pText.replace(sysTalkKeyAndDeviceName.getKey(), "#" + (j++) + "#");
                                commands.add(systemTalkAnswerConfigService.getCommandList().get(sysTalkKeyAndDeviceName.getIndex()));

                            }
                        }
                    }
                    if(includs.size() > 0) {
                        return getActions(pText, text, includs, commands);
                    }

                }
                return getActions(text, text, null, null);
            });
        }
        //20230928日记，后期改成先匹配用户的设备名称，再找动词
        return getActions(text, text, null, null);
    }

    public Mono<Actions> getActions(String text, String recordText,
                                    List<DeviceUserBindEntity> includs,
                                    List<SystemTalkAnswerConfigEntity> commands) {
        return liguoNlpService.geSingletNlp(text).map(nlp -> {
            Actions actions = new Actions();
            actions.setActions(new ArrayList<>());
            Action action = new Action();

            actions.setRecordText(recordText);
            action.setLbs(new ArrayList<>());
            action.setAsk(actions.getRecordText());
            List<SystemTalkAnswerConfigEntity> systemTalkAnswerConfigEntities = new ArrayList<>();

            for (NlpKey key : nlp.getKeys()
            ) {
                action = ChinesePartSpeechEnum.getEnumWithCode(key.getType()).getAction(systemTalkAnswerConfigService.getSystemTalkWithKeyGroup(),
                        key.getKey(),
                        actions,
                        action,
                        systemTalkAnswerConfigEntities,
                        includs,
                        commands);
                if(actions.getA() + actions.getB() == 2){
                    actions.setA(0);// = 0;
                    actions.setB(0);//b = 0;
                    if(systemTalkAnswerConfigEntities.size() > 0){//指令按照优先级排序
                        systemTalkAnswerConfigEntities.sort(Comparator.comparing(SystemTalkAnswerConfigEntity::getKeyOrder));
                        action.setSystemTalkAnswerConfigEntity(systemTalkAnswerConfigEntities.get(0));
                        actions.setLastSystemTalkAnswerConfigEntity(action.getSystemTalkAnswerConfigEntity());
                        actions.setLastDeviceUserBindEntity(action.getDeviceUserBindEntity());

                        action.setAction(action.getSystemTalkAnswerConfigEntity().getAskKey());
                        systemTalkAnswerConfigEntities.clear();
                    }else if(actions.getLastSystemTalkAnswerConfigEntity() != null){
                        action.setSystemTalkAnswerConfigEntity(actions.getLastSystemTalkAnswerConfigEntity());
                        action.setAction(action.getSystemTalkAnswerConfigEntity().getAskKey());
                        action.setDeviceUserBindEntity(actions.getLastDeviceUserBindEntity());
                    }

                    actions.getActions().add(action);
                    actions.setLastName(action.getName());//lastName = actions.getName();
                    actions.setLastDeviceUserBindEntity(action.getDeviceUserBindEntity());
                    action = new Action();
                    actions.setName("");//name = "";
                    action.setLbs(new ArrayList<>());
                    action.setAsk(actions.getRecordText());

                }

            }
            //下面判断最后一个名词
            if(StringUtils.isNotEmpty(action.getName()) && actions.getA() == 0){
                //这说明已经匹配到设备了,但是没有匹配到动作
                action.setSystemTalkAnswerConfigEntity(actions.getLastSystemTalkAnswerConfigEntity());
                action.setAction(action.getSystemTalkAnswerConfigEntity().getAskKey());
                actions.setLastSystemTalkAnswerConfigEntity(null);
                actions.setLastName("");
                actions.setLastDeviceUserBindEntity(null);
                actions.setB(1);//b = 1;
                actions.setA(1);
            }else if(StringUtils.isNotEmpty(actions.getName())){
                //中途拼接到一些词，还未匹配到看是否有识别到名词
                //先看是否为自定义指令
                SystemTalkAnswerConfigEntity entity = systemTalkAnswerConfigService.getSystemTalkWithKey(actions.getName());
                if(entity != null){
                    systemTalkAnswerConfigEntities.add(entity);
                    actions.setA(1);//a = 1;
                }else{//这里没雨匹配到设备，需要执行时查询数据库
                    action.setName(actions.getName());//.add(name);
                    actions.setB(1);//b = 1;
                    actions.setLastSystemTalkAnswerConfigEntity(null);
                    actions.setLastName("");
                    actions.setLastDeviceUserBindEntity(null);
                }
            }else if(actions.getA() == 1){
                //匹配到动作，但是没有设备名称
                if(StringUtils.isNotEmpty(actions.getLastName())){//如果还有多就用最后一次匹配到的设备信息
                    action.setName(actions.getLastName());//.add(lastName);
                    action.setDeviceUserBindEntity(actions.getLastDeviceUserBindEntity());
                    actions.setB(1);//b = 1;
                }
            }
            if(systemTalkAnswerConfigEntities.size() > 0){//指令按照优先级排序
                systemTalkAnswerConfigEntities.sort(Comparator.comparing(SystemTalkAnswerConfigEntity::getKeyOrder));
                action.setSystemTalkAnswerConfigEntity(systemTalkAnswerConfigEntities.get(0));
                action.setAction(action.getSystemTalkAnswerConfigEntity().getAskKey());
            }else if(actions.getLastSystemTalkAnswerConfigEntity() != null){
                action.setSystemTalkAnswerConfigEntity(actions.getLastSystemTalkAnswerConfigEntity());
                action.setAction(action.getSystemTalkAnswerConfigEntity().getAskKey());
                action.setDeviceUserBindEntity(actions.getLastDeviceUserBindEntity());
            }
            if(actions.getA() + actions.getB() > 0){
                actions.getActions().add(action);
            }
            return actions;
        });
    }
}
