package com.bonus.bracelet.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.shaded.com.google.common.collect.Maps;
import com.bonus.bracelet.mapper.BraceletMapper;
import com.bonus.bracelet.mapper.DeviceMapper;
import com.bonus.bracelet.mapper.ResourceFileMapper;
import com.bonus.bracelet.service.IBraceletService;
import com.bonus.bracelet.service.IDeviceService;
import com.bonus.common.core.constant.HttpStatus;
import com.bonus.common.core.constant.SecurityConstants;
import com.bonus.common.core.domain.R;
import com.bonus.common.core.utils.UploadCheckUtils;
import com.bonus.common.core.utils.uuid.IdUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.entity.bracelet.vo.*;
import com.bonus.common.entity.file.ResourceFileVo;
import com.bonus.system.api.RemoteFileService;
import com.bonus.system.api.domain.SysFile;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * BraceletServiceImpl 手环管理
 */
@Service(value = "IBraceletService")
@Slf4j
public class BraceletServiceImpl implements IBraceletService {

    @Resource(name = "BraceletMapper")
    private BraceletMapper braceletMapper;

    @Resource
    private RemoteFileService remoteFileService;

    @Resource(name = "ResourceFileMapper")
    private ResourceFileMapper resourceFileMapper;

    @Override
    public List<BraceletVo> getBraceletLists(BraceletVo data) {
        List<BraceletVo> list = new ArrayList<>();
        try {
            list = braceletMapper.getBraceletLists(data);
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return list;
    }

    @Override
    public List<BraceletVo> getShBindLists(BraceletVo data) {
        List<BraceletVo> list = new ArrayList<>();
        List<BraceletVo> listFilter =   new ArrayList<>();
        try {
            list = braceletMapper.getShBindLists(data);
            for (int i = 0; i < list.size(); i++) {
                if(list.get(i).getShPersonName()==null || list.get(i).getShPersonName().equals("")){
                    list.get(i).setShStatus(1);
                }else{
                    list.get(i).setShStatus(0);
                }
            }
            if(data.getShStatus()!=null){
                listFilter = list.stream().filter(bracelet -> data.getShStatus()==(bracelet.getShStatus())).collect(Collectors.toList());
            }else{
                listFilter = list;
            }

        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return listFilter;
    }

    @Override
    public List<BraceletVo> getShBindNoLists(BraceletVo data) {
        List<BraceletVo> list = new ArrayList<>();
        try {
            list = braceletMapper.getShBindNoLists(data);
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return list;
    }

    @Override
    public List<ShboxVo> getShboxLists(ShboxVo data) {
        List<ShboxVo> list = new ArrayList<>();
        try {
            list = braceletMapper.getShboxLists(data);

        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return list;
    }

    @Override
    public List<ShboxVo> getShboxallLists(ShboxVo data) {
        List<ShboxVo> list = new ArrayList<>();
        try {
            list = braceletMapper.getShboxallLists(data);
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return list;
    }

    @Override
    public List<ShboxVo> getShboxBindLists(ShboxVo data) {
        List<ShboxVo> list = new ArrayList<>();
        try {
            list = braceletMapper.getShboxBindLists(data);

        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return list;
    }

    /**
     * 新增手环信息
     * @param vo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addSh(ShboxVo vo) {
        try {
            if(vo.getShboxBindNum()!=null && vo.getShboxCapacity()!=null)
            {
                if(vo.getShboxBindNum()>=vo.getShboxCapacity()){
                    return AjaxResult.error("手环箱绑定数量已满，请重新选择");
                }
            }
            BraceletVo result = braceletMapper.isCodeExist(vo);

            if (result != null) {
                return AjaxResult.error("手环编号已存在，请重新输入");
            }
            if(vo.getShboxId()==null){
                vo.setShStatus(1);
            }else{
                vo.setShStatus(0);
            }
            int num =  braceletMapper.addSh(vo);
            if(num==1){
                return AjaxResult.success();
            }
            return AjaxResult.error("手环信息新增失败");
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }

    /**
     *  新增设备属性信息
     * @param file
     * @param params
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addAttribute(MultipartFile file, String params) {
        // 文件ID
        String delFileId = null;
        try {
            AttributeVo vo = JSON.parseObject(params, AttributeVo.class);
            AttributeVo resultOne = braceletMapper.isDataCodeExist(vo);
            if (resultOne != null) {
                return AjaxResult.error("该设备的级联编号已存在，请重新输入");
            }

            if(file!=null){
                // 校验文件、上传文件
                String isVerify = UploadCheckUtils.uploadImgVerify(file);
                if (StringUtils.isNotBlank(isVerify)) {
                    return AjaxResult.error(isVerify);
                }
                int num =  braceletMapper.addAttribute(vo);
                if(num!=1){
                    return AjaxResult.error("设备属性数据新增失败");
                }
                delFileId = uploadFile(file,vo);
            }else{
                int num =  braceletMapper.addAttribute(vo);
                if(num!=1){
                    return AjaxResult.error("设备属性数据新增失败");
                }
            }
            return AjaxResult.success("新增成功");
        } catch (Exception e) {
            log.error("新增设备属性", e);
            // 添加失败-删除文件
            if (StringUtils.isNotEmpty(delFileId)) {
                remoteFileService.delFile(delFileId, SecurityConstants.INNER);
            }
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }

    /**
     * 修改设备属性信息
     * @param file
     * @param params
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult editAttribute(MultipartFile file, String params) {
        // 文件ID
        String delFileId = null;
        try {
            AttributeVo vo = JSON.parseObject(params, AttributeVo.class);
            AttributeVo resultOne = braceletMapper.isEditDataCodeExist(vo);
            if (resultOne != null) {
                return AjaxResult.error("该设备的级联编号已存在，请重新输入");
            }
            if(vo.getDelFileId() != null && vo.getDelFileId()!=""){
                braceletMapper.deleteFileId(vo.getDelFileId());
                remoteFileService.delFile(vo.getDelFileId(),SecurityConstants.INNER);
            }
            if(file!=null){
                // 校验文件、上传文件
                String isVerify = UploadCheckUtils.uploadImgVerify(file);
                if (StringUtils.isNotBlank(isVerify)) {
                    return AjaxResult.error(isVerify);
                }
                int num =  braceletMapper.editAttribute(vo);
                if(num!=1){
                    return AjaxResult.error("设备属性数据修改失败");
                }
                delFileId = uploadFile(file,vo);
            }else{
                int num =  braceletMapper.editAttribute(vo);
                braceletMapper.editFilePath(vo);
                if(num!=1){
                    return AjaxResult.error("设备属性数据修改失败");
                }
            }
            return AjaxResult.success("修改成功");
        } catch (Exception e) {
            log.error("修改设备属性", e);
            // 添加失败-删除文件
            if (StringUtils.isNotEmpty(delFileId)) {
                remoteFileService.delFile(delFileId, SecurityConstants.INNER);
            }
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }

    /**
     * 删除设备属性
     *
     * @param id
     * @return 结果
     */
    @Override
    public AjaxResult delDeviceAttribute(Long id)
    {
        try {
            int num = 0;
            num =  braceletMapper.deleteFile(id);
            int num2 = braceletMapper.getFile(id);
            if(num2!=0){
                braceletMapper.deleFileSource(id);
                String filePath = braceletMapper.selectFilePathById(id);
                remoteFileService.delFile(filePath,SecurityConstants.INNER);
            }
            if(num==1){
                return AjaxResult.success();
            }
            return AjaxResult.error("设备属性信息删除失败");
        } catch (Exception e) {
            log.error(e.toString(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }


    /**
     * 新增手环箱子信息
     * @param vo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addBox(ShboxVo vo) {
        try {
            ShboxVo result =  braceletMapper.isBoxCodeExistTemp(vo);
            if (result != null) {
                return AjaxResult.error("手环箱编号已存在，请重新输入");
            }
            ShboxVo result2 =  braceletMapper.isBoxNameExistTemp(vo);
            if (result2 != null) {
                return AjaxResult.error("手环箱名称已存在，请重新输入");
            }
            int num =  braceletMapper.addBox(vo);
            if(num==1){
                return AjaxResult.success();
            }
            return AjaxResult.error("手环箱信息新增失败");
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }

    /**
     * 手环绑定选择页面绑定手环信息
     * @param vo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addShBind(ShboxVo vo) {
        try {
            if(vo.getShboxBindNum()>=vo.getShboxCapacity()){
                return AjaxResult.error("手环箱绑定数量已满，请重新选择");
            }
            int num =  braceletMapper.addShBind(vo);
            if(num==1){
                return AjaxResult.success();
            }
            return AjaxResult.error("手环绑定失败");
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }

    /**
     * 解除绑定
     * @param vo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delSh(BraceletVo vo) {
        try {
            int result = braceletMapper.delSh(vo);
            if(result==1){
                return AjaxResult.success();
            }
            return AjaxResult.error("解除绑定失败");
        } catch (Exception e) {
            log.error(e.toString(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult editSh(ShboxVo vo) {
        try {
            if(vo.getShboxBindNum()!=null && vo.getShboxCapacity()!=null){
                if(vo.getShboxBindNum()>=vo.getShboxCapacity()){
                    return AjaxResult.error("手环箱绑定数量已满，请重新选择");
                }
            }
            BraceletVo result = braceletMapper.isCodeEditExist(vo);
            if (result != null) {
                return AjaxResult.error("手环编号已存在，请重新输入");
            }
            if(vo.getShboxId()!=0){
                vo.setBidTime(new Date());
            }else{
                vo.setBidTime(null);
            }
           int num =  braceletMapper.updateSh(vo);
            if(num==1){
                return AjaxResult.success();
            }
            return AjaxResult.error("手环信息修改失败");
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult editBox(ShboxVo vo) {
        try {
            ShboxVo result =  braceletMapper.isBoxCodeExist(vo);
            if (result != null) {
                return AjaxResult.error("手环箱编号已存在，请重新输入");
            }
            ShboxVo result2 =  braceletMapper.isBoxNameExist(vo);
            if (result2 != null) {
                return AjaxResult.error("手环箱名称已存在，请重新输入");
            }
            int num =  braceletMapper.updateShbox(vo);
            if(num==1){
                return AjaxResult.success();
            }
            return AjaxResult.error("手环箱信息修改失败");
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delShById(int shId) {
        try {
            int result = braceletMapper.delShById(shId);
            if(result==1){
                return AjaxResult.success();
            }
            return AjaxResult.error("手环信息删除失败");
        } catch (Exception e) {
            log.error(e.toString(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delShboxById(int shboxId) {
        try {
            int result = braceletMapper.delShboxById(shboxId);
            if(result==1){
                return AjaxResult.success();
            }
            return AjaxResult.error("手环箱信息删除失败");
        } catch (Exception e) {
            log.error(e.toString(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
    }

    /**
     * 根据手环箱id获得详细信息
     * @param shboxId
     * @return
     */
    @Override
    public AjaxResult selectBoxById(Integer shboxId) {
        try {
            ShboxVo vo = braceletMapper.selectBoxById(shboxId);
            return AjaxResult.success(vo);
        } catch (Exception e) {
            log.error("手环箱详情", e);
            return AjaxResult.error();
        }
    }

    /**
     * 根据手环箱id获得刷新详细信息
     * @param shboxId
     * @return
     */
    @Override
    public AjaxResult selectBoxNewById(Integer shboxId) {
        Map<String,Integer> map= Maps.newHashMap();
        try {
            ShboxVo vo = braceletMapper.selectBoxNewById(shboxId);
            if(!Objects.isNull(vo)){
                Integer  num=vo.getShboxCapacity()-vo.getShboxBindNum();
                map.put("boxNum",num);
            }else{
                map.put("boxNum",0);
                return AjaxResult.error();
            }
            return AjaxResult.success(map);
        } catch (Exception e) {
            map.put("boxNum",0);
            log.error(e.toString(), e);
            return AjaxResult.error();
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult bindSh(int shboxId,int[] shIds) {
        if(shIds.length==0){
            return AjaxResult.error("请至少选择一个要绑定的手环");
        }
        try {
            for (int i = 0; i < shIds.length; i++) {
                int shId = shIds[i];
                braceletMapper.bindSh(shboxId,shId);
            }
        } catch (Exception e) {
            log.error(e.toString(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("绑定失败");
        }
        return AjaxResult.success("绑定成功");
    }

    /**
     * 设备属性列表
     * @param data
     * @return
     */
    @Override
    public List<AttributeVo> getDeviceAttributeLists(AttributeVo data) {
        List<AttributeVo> list = new ArrayList<>();
        try {
            list = braceletMapper.getDeviceAttributeLists(data);
            for (AttributeVo vo : list) {
                vo = handleData(vo);
            }

        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return list;
    }

    /**
     * 根据id获取设备属性
     * @param dto
     * @return
     */
    @Override
    public AjaxResult getAttributeInfo(AttributeVo dto) {
        try {
            AttributeVo vo = braceletMapper.getAttributeInfo(dto);
            AttributeVo handleData = handleData(vo);
            return AjaxResult.success(handleData);
        } catch (Exception e) {
            log.error("设备属性详情", e);
            return AjaxResult.error();
        }
    }


    public AttributeVo handleData(AttributeVo vo) {
        R<SysFile> result = remoteFileService.getImgBase64(vo.getFilePath(), SecurityConstants.INNER);
        if (result != null && result.getCode() == HttpStatus.SUCCESS && result.getData() != null) {
            String jsonString = JSON.toJSONString(result.getData());
            JSONObject item = JSON.parseObject(jsonString);
            String base64 = item.getString("url");
            vo.setBase64Url(base64);
        }
        return vo;
    }

    public ResourceFileVo setResourceFileData(JSONObject item, AttributeVo vo) {
        ResourceFileVo fileVo = new ResourceFileVo();
        String resourceId = IdUtils.simpleUUID();
        fileVo.setFileType(1);
        fileVo.setFilePath(item.getString("fileId"));
        fileVo.setFileSuffix(item.getString("suffix"));
        fileVo.setFileName(item.getString("fileName"));
        fileVo.setSourceId(vo.getId() + "");
        fileVo.setSourceType("7");
        return fileVo;
    }

    public String uploadFile(MultipartFile file, AttributeVo vo) {
        R result = remoteFileService.singleUploadFile(file, SecurityConstants.INNER);
        if (result != null && result.getCode() == HttpStatus.ERROR) {
            log.error("图标照片上传失败");
            return null;
        } else if (result != null && result.getCode() == HttpStatus.SUCCESS && result.getData() != null) {
            String jsonString = JSON.toJSONString(result.getData());
            JSONObject item = JSON.parseObject(jsonString);
            if (item != null) {
                vo.setFilePath(item.getString("fileId"));
                braceletMapper.setFilePath(vo);
                ResourceFileVo fileVo = setResourceFileData(item, vo);
                resourceFileMapper.addFile(fileVo);
            }
            return item.getString("fileId");
        }
        return null;
    }
}
