package com.xueyi.system.digitalmans.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.xueyi.common.core.constant.basic.SqlConstants;
import com.xueyi.common.core.constant.digitalman.InitConstants;
import com.xueyi.common.core.constant.digitalman.MessageConstants;
import com.xueyi.common.web.entity.service.impl.BaseServiceImpl;
import com.xueyi.message.api.transfer.feign.RemoteTransferService;
import com.xueyi.system.api.device.domain.po.DmDeviceTenantMergePo;
import com.xueyi.system.api.digitalmans.domain.dto.DmDigitalmanWorktimeDto;
import com.xueyi.system.api.digitalmans.domain.dto.DmModelDto;
import com.xueyi.system.api.digitalmans.domain.dto.DmSyncDigitalmanDto;
import com.xueyi.system.api.digitalmans.domain.po.DmDigitalmanExtPo;
import com.xueyi.system.api.digitalmans.domain.po.DmDigitalmanPo;
import com.xueyi.system.api.digitalmans.domain.po.DmManDevicePo;
import com.xueyi.system.api.resource.domain.po.DmResourcesPo;
import com.xueyi.system.device.service.IDmDeviceTenantMergeService;
import com.xueyi.system.digitalmans.domain.dto.DmDigitalmanDto;
import com.xueyi.system.digitalmans.domain.dto.DmDigitalmanExtDto;
import com.xueyi.system.digitalmans.domain.model.DmDigitalmanConverter;
import com.xueyi.system.digitalmans.domain.query.DmDigitalmanQuery;
import com.xueyi.system.digitalmans.manager.IDmDigitalmanManager;
import com.xueyi.system.digitalmans.mapper.DmDigitalmanExtMapper;
import com.xueyi.system.digitalmans.mapper.DmDigitalmanMapper;
import com.xueyi.system.digitalmans.mapper.DmManDeviceMapper;
import com.xueyi.system.digitalmans.service.IDmDigitalmanExtService;
import com.xueyi.system.digitalmans.service.IDmDigitalmanService;
import com.xueyi.system.digitalmans.service.IDmModelService;
import com.xueyi.system.digitalmans.service.IDmSkillService;
import com.xueyi.system.resource.domain.dto.DmResourcesDto;
import com.xueyi.system.resource.domain.dto.DmScreenOffDto;
import com.xueyi.system.resource.domain.query.DmScreenOffQuery;
import com.xueyi.system.resource.service.IDmResourcesService;
import com.xueyi.system.resource.service.IDmScreenOffService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 数字人基础管理 服务层处理
 *
 * @author xueyi
 */
@Service
public class DmDigitalmanServiceImpl extends BaseServiceImpl<DmDigitalmanQuery, DmDigitalmanDto, IDmDigitalmanManager> implements IDmDigitalmanService {

    @Autowired
    DmDigitalmanExtMapper dmDigitalmanExtMapper;

    @Autowired
    DmDigitalmanMapper dmDigitalmanMapper;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    IDmDeviceTenantMergeService deviceTenantMergeService;

    @Autowired
    IDmDigitalmanExtService dmDigitalmanExtService;

    @Autowired
    IDmSkillService dmSkillService;

    @Autowired
    IDmModelService dmModelService;

    @Autowired
    DmManDeviceMapper dmManDeviceMapper;

    @Autowired
    DmDigitalmanExtMapper digitalmanExtMapper;

    @Autowired
    RemoteTransferService transferService;

    @Autowired
    IDmResourcesService dmResourcesService;

    @Autowired
    IDmScreenOffService screenOffService;
    /**
     * 查询数字人基础对象列表 | 数据权限
     *
     * @param dmDigitalman 数字人基础对象
     * @return 数字人基础对象集合
     */

    @Autowired
    private DmDigitalmanConverter dmDigitalmanConverter;
    @Override
    //@DataScope(userAlias = "createBy", mapperScope = {"DmDigitalmanMapper"})
    public List<DmDigitalmanDto> selectListScope(DmDigitalmanQuery dmDigitalman) {
        List<DmDigitalmanDto> resultL = null;
        QueryWrapper<DmDigitalmanExtPo> wrapper = new QueryWrapper<>();
        if (null != dmDigitalman.getDeptId() || null != dmDigitalman.getDeviceId() || null != dmDigitalman.getIsOnline()) {
            if (null != dmDigitalman.getDeviceId()) {
                wrapper.eq("device_id", dmDigitalman.getDeviceId());
            }
            if (null != dmDigitalman.getDeptId()) {
                wrapper.eq("dept_id", dmDigitalman.getDeptId());
            }
            if (null != dmDigitalman.getIsOnline()) {
                wrapper.eq("is_online", dmDigitalman.getIsOnline());
            }
            List<DmDigitalmanExtPo> extPoList = dmDigitalmanExtMapper.selectList(wrapper);
            List<String> manCodes = null;
            if (extPoList.size()>0) {
                manCodes = extPoList.stream().map(DmDigitalmanExtPo::getManCode).collect(Collectors.toList());
            }

            if (null != manCodes) {
                QueryWrapper<DmDigitalmanPo> tmpWrapper = new QueryWrapper<DmDigitalmanPo>();
                tmpWrapper.lambda().in(DmDigitalmanPo::getManCode, manCodes);
                resultL = dmDigitalmanMapper.selectList(tmpWrapper).stream().map(item->dmDigitalmanConverter.mapperDto(item)).toList();
                if (StringUtils.isNotEmpty(dmDigitalman.getName())) {
                    resultL = resultL.stream().filter(item->item.getName().equalsIgnoreCase(dmDigitalman.getName())).collect(Collectors.toList());;
                }
            }
        } else {
            resultL = super.baseManager.selectList(dmDigitalman);
        }
        // 对数字人进行子遍历
        Page<DmDigitalmanDto> result = new Page<>();

        if (null != resultL) {
            resultL.forEach(item-> {
                addDevInfo(item);
                result.add(item);

            });
            if (resultL instanceof Page<DmDigitalmanDto>) {
                result.setTotal(((Page<DmDigitalmanDto>)resultL).getTotal());
            }
        }
        return result;
//        // 绑定数字人与组织
//        List<DmDigitalmanDto> list = null;
//        List<String> mancodeList = null;
//        DmDigitalmanExtPo digitalmanExtQuery = new DmDigitalmanExtQuery();
//        digitalmanExtQuery.setDeptId(dmDigitalman.getDeptId());
//        digitalmanExtQuery.setDeviceId(dmDigitalman.getDeviceId());
//        if (dmDigitalman.getDeptId() == null) {
//            if (StringUtils.isNotEmpty(dmDigitalman.getDeviceId())) {
//                List<DmDigitalmanExtPo> digitalmanExtList = dmDigitalmanExtMapper.selectList(Wrappers.query(digitalmanExtQuery));
//                if (digitalmanExtList != null) {
//                    mancodeList = digitalmanExtList.stream().map(DmDigitalmanExtPo::getManCode).collect(Collectors.toList());
//                }
//                List<DmDigitalmanDto> d2list = new ArrayList<>();
//                if (mancodeList !=null && mancodeList.size() > 0){
//                    mancodeList.forEach(item-> {
//                        DmDigitalmanDto tmpDto = dmDigitalmanMapper.selectByCode(item);
//                        d2list.add(tmpDto);
//                    });
//                    list = d2list;
//                }
//                else {
//                    return new ArrayList<>();
//                }
//                list.forEach(item->addDevInfo(item));
//                return list;
//            }
//
//            list = baseManager.selectList(dmDigitalman);
//            list.forEach(item-> addDevInfo(item));
//            return list;
//        }
//
//        if (dmDigitalman!= null) {
//            List<DmDigitalmanExtPo> digitalmanExtList = null;
//            if (StringUtils.isNotEmpty(dmDigitalman.getDeviceId())) {
//                digitalmanExtList = dmDigitalmanExtMapper.selectList(Wrappers.<DmDigitalmanExtPo>query().lambda()
//                        .eq(DmDigitalmanExtPo::getDeptId,dmDigitalman.getDeptId())
//                        .eq(DmDigitalmanExtPo::getDeviceId, dmDigitalman.getDeviceId()));
//            } else {
//                digitalmanExtList = dmDigitalmanExtMapper.selectList(Wrappers.<DmDigitalmanExtPo>query().lambda()
//                        .eq(DmDigitalmanExtPo::getDeptId,dmDigitalman.getDeptId()));
//            }
//            if (digitalmanExtList != null) {
//                mancodeList = digitalmanExtList.stream().map(DmDigitalmanExtPo::getManCode).collect(Collectors.toList());
//            }
//        }
//        List<DmDigitalmanDto> dlist = new ArrayList<>();
//        if (mancodeList !=null && mancodeList.size() > 0){
//              mancodeList.forEach(item-> dlist.add(dmDigitalmanMapper.selectByCode(item)));
//              list = dlist;
//          }
//        else {
//            return new ArrayList<>();
//        }
//        list.forEach(item->addDevInfo(item));
//        return list;
    }

    @Override
    public void addDevInfo(DmDigitalmanDto dto) {
        DmDigitalmanExtPo po = dmDigitalmanExtMapper.selectOne(
                Wrappers.<DmDigitalmanExtPo>query().lambda()
                        .eq(DmDigitalmanExtPo::getManCode, dto.getManCode())
                        .last(SqlConstants.LIMIT_ONE));
        if (po == null) {
            return;
        }
        dto.setDeptId(po.getDeptId());
        if (po.getDeviceId() == null || po.getDeviceId().equalsIgnoreCase("")) {
            // 设备未激活
            dto.setIsOnline(Integer.parseInt(InitConstants.DEVICE_ACTIVATE_STATUS_NOT_ACTIVATE));
        } else {
            dto.setIsOnline(Integer.parseInt(transferService.getDeviceOnlineStatus(po.getDeviceId()).get("msg").toString()));
        }
        dto.setSetSpace(dto.getSetSpace());
        dto.setDeviceId(po.getDeviceId());
        // 获取心跳时间戳
        String timestamp = redisTemplate.opsForValue().get(MessageConstants.REDIS_GROUP_HEADER + po.getDeviceId() + ":" + MessageConstants.HEART_BEAT_SYNC);
        System.currentTimeMillis();
        if (timestamp == null || timestamp.equalsIgnoreCase("")) {
            timestamp = "0";
        }
//        dto.setIsOnline(System.currentTimeMillis() - Long.parseLong(timestamp) > 60 * 1000 ? 0 : 1);
    }

    @Override
    public DmDigitalmanDto selectById(Serializable id) {
        return super.selectById(id);
    }

    @Override
    public DmDigitalmanWorktimeDto selectWorktimeById(Serializable id) {
        return super.baseManager.getWorkTimeInfo(id);
    }

    @Override
    public int worktimeUpdate(DmDigitalmanWorktimeDto dto) {
        DmDigitalmanWorktimeDto originDto = super.baseManager.getWorkTimeInfo(dto.getId());
        originDto.setWorkdayHourStart(dto.getWorkdayHourStart());
        originDto.setWorkdayHourEnd(dto.getWorkdayHourEnd());
        originDto.setWeekendHourStart(dto.getWeekendHourStart());
        originDto.setWeekendHourEnd(dto.getWeekendHourEnd());
        int row = super.baseManager.worktimeUpdate(originDto);
        return row;
    }


    @Override
    public DmSyncDigitalmanDto syncDigitalman(String manCode, String timestamp) {
        return super.baseManager.syncDigitalmanInfo(manCode,timestamp);
    }

    @Override
    public DmDigitalmanExtPo selectExt(String devId) {
        DmDigitalmanExtPo po = dmDigitalmanExtMapper.selectOne(
                Wrappers.<DmDigitalmanExtPo>query().lambda()
                        .eq(DmDigitalmanExtPo::getDeviceId, devId).last(SqlConstants.LIMIT_ONE));
        return po;
    }

    @Override
    public int initDigitalman(String snCode) {
        DmDeviceTenantMergePo mergePo = deviceTenantMergeService.selectByDevSn(snCode);
//        DmManDevicePo po = dmManDeviceMapper.selectOne(Wrappers.<DmManDevicePo>query().lambda()
//                .eq(DmManDevicePo::getManCode, snCode));
        DmManDevicePo po = dmManDeviceMapper.selectInfoBySecret(snCode);
        if (po != null) {
            //绑定设备id
            DmDigitalmanExtPo dep = digitalmanExtMapper.selectOne(Wrappers.<DmDigitalmanExtPo>query().lambda()
                    .eq(DmDigitalmanExtPo::getManCode, snCode));
            if (dep != null) {
                // 数字人已初始化，进行数字人-设备号关联
                dep.setDeviceId(mergePo.getDevId());
                digitalmanExtMapper.updateById(dep);
                return 0;
            }
        }
        //同步数字人
        DmDigitalmanDto digitalmanDto = new DmDigitalmanDto();
        digitalmanDto.setManCode(mergePo.getDevSn());
        digitalmanDto.setName(InitConstants.DEFAULT_NAME);
        digitalmanDto.setNickName(InitConstants.DEFAULT_NAME);
        // 初始化数字人
        super.insert(digitalmanDto);


        // 初始化数字人设备好
        DmDigitalmanExtDto dto = new DmDigitalmanExtDto();
        dto.setManCode(digitalmanDto.getManCode());
        dto.setSnCode(mergePo.getDevId());
        dto.setDeviceId(mergePo.getDevId());
        dmDigitalmanExtService.insert(dto);


        // 添加数字人技能
        dmSkillService.batchInitInsert(digitalmanDto);


        // 添加展示页
        DmModelDto modelDto = new DmModelDto();
        modelDto.setName(digitalmanDto.getName());
        modelDto.setManId(digitalmanDto.getId());
        modelDto.setCurrentSuit(InitConstants.DEFAULT_CLOTH.longValue());
        modelDto.setIconId(InitConstants.DEFAULT_ICON_ID);
        modelDto.setCurrentBackground(InitConstants.DEFAULT_BACKGROUND_ID);
        modelDto.setCurrentSuit(InitConstants.DEFAULT_MODEL.longValue());

        // 添加模型
        DmResourcesDto resourcesDto = new DmResourcesDto();
        resourcesDto.setUrl(InitConstants.DEFAULT_MODEL_URL);
        resourcesDto.setType(DmResourcesPo.TYPE_PIC);
        resourcesDto.setName("model");
        dmResourcesService.initAdd(resourcesDto);
        modelDto.setCurrentModel(resourcesDto.getId());
        modelDto.setResourceId(resourcesDto.getId());

        // 添加背景
        resourcesDto = new DmResourcesDto();
        resourcesDto.setUrl(InitConstants.DEFAULT_BACKGROUND_URL);
        resourcesDto.setType(DmResourcesPo.TYPE_PIC);
        resourcesDto.setName("background");
        dmResourcesService.initAdd(resourcesDto);
        modelDto.setCurrentBackground(resourcesDto.getId());
        modelDto.setBackgroundContain(String.valueOf(modelDto.getCurrentBackground()));
        // 添加logo
        resourcesDto = new DmResourcesDto();
        resourcesDto.setUrl(InitConstants.DEFAULT_ICON_URL);
        resourcesDto.setType(DmResourcesPo.TYPE_PIC);
        resourcesDto.setName("logo");
        dmResourcesService.initAdd(resourcesDto);
        modelDto.setIconId(resourcesDto.getId());
        modelDto.setIconPos("0");

        // 添加衣服
        resourcesDto = new DmResourcesDto();
        resourcesDto.setUrl(InitConstants.DEFAULT_CLOTH_URL);
        resourcesDto.setType(DmResourcesPo.TYPE_PIC);
        resourcesDto.setName("suit");
        dmResourcesService.initAdd(resourcesDto);
        modelDto.setCurrentSuit(resourcesDto.getId());
        modelDto.setSuitContain(modelDto.getCurrentSuit() + "");
        int cur = 1;
        String screenOffContain = "";
        // 添加展示页
        List<DmScreenOffDto> screenOffDtos = screenOffService.selectList(new DmScreenOffQuery());
        if (screenOffDtos == null ||screenOffDtos.size() == 0) {
            for (String item : InitConstants.DEFAULT_SCREEN_OFF_URLs) {
                resourcesDto = new DmResourcesDto();
                resourcesDto.setUrl(item);
                resourcesDto.setType(DmResourcesPo.TYPE_PIC);
                resourcesDto.setName("screen_off");
                // 插入一张展示页
                DmScreenOffDto screenOffDto = new DmScreenOffDto();
                screenOffDto.setName("展示页"+ cur++);
                dmResourcesService.initAdd(resourcesDto);
                Long rId = resourcesDto.getId();
                screenOffDto.setResourceId(rId);
                screenOffService.insert(screenOffDto);
                modelDto.setCurrentScreenOff(rId);
                screenOffContain += "," + rId;
            }
        }
        else {
            for (DmScreenOffDto dto1 : screenOffDtos) {
                screenOffContain += "," + dto1.getResourceId();
                modelDto.setCurrentScreenOff(dto1.getResourceId());
            }
            modelDto.setScreenOffContain(screenOffContain.substring(1));
        }

        modelDto.setScreenOffContain(screenOffContain.substring(1));
        dmModelService.insert(modelDto);
        // 添加工作时间
        DmDigitalmanWorktimeDto worktimeDto = new DmDigitalmanWorktimeDto();
        worktimeDto.setId(digitalmanDto.getId());
        worktimeDto.setWorkdayHourStart(InitConstants.WORKDAY_START);
        worktimeDto.setWorkdayHourEnd(InitConstants.WORKDAY_END);
        worktimeDto.setWeekendHourStart(InitConstants.WEEKEND_START);
        worktimeDto.setWeekendHourEnd(InitConstants.WEEKEND_END);
        this.worktimeUpdate(worktimeDto);
        return 0;
    }

    @Override
    public List<String> selectRegisteredDevices() {
        List<DmDigitalmanExtPo> dmDigitalmanPoList = dmDigitalmanExtMapper.selectList(Wrappers.<DmDigitalmanExtPo>query().lambda()
                .isNotNull(DmDigitalmanExtPo::getDeviceId));
        return dmDigitalmanPoList.stream().map(DmDigitalmanExtPo::getDeviceId)
                .filter(Objects::nonNull)
                .filter(str->!str.isEmpty())
                .collect(Collectors.toList());
    }

    @Override
    public boolean syncRegisteredDevice(String deviceId) {
        DmDigitalmanExtPo po = dmDigitalmanExtMapper.selectOne(Wrappers.<DmDigitalmanExtPo>query().lambda()
                .eq(DmDigitalmanExtPo::getDeviceId,deviceId));
        if (po != null) {
            po.setIsOnline(Integer.parseInt(transferService.getDeviceOnlineStatus(deviceId).get("msg").toString()));
            dmDigitalmanExtMapper.updateById(po);
            return true;
        }
        return false;
    }
}