package com.sptg.gateway.controller.implement;

import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.sptg.ad.api.feigns.AdPushTaskFeign;
import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.beans.ResultEnum;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.constant.UserFlagConstant;
import com.sptg.common.core.entity.DispatchTask;
import com.sptg.common.core.util.Base64DecodeMultipartFileUtils;
import com.sptg.common.security.annotation.Security;
import com.sptg.common.security.enums.DataFormatEnum;
import com.sptg.common.security.service.SecurityServiceInterface;
import com.sptg.device.api.entity.Device;
import com.sptg.device.api.feigns.DeviceFeign;
import com.sptg.estate.api.dto.DeviceTestDto;
import com.sptg.estate.api.dto.UserInfoDto;
import com.sptg.estate.api.entity.DeviceTest;
import com.sptg.estate.api.entity.GuestAuthorize;
import com.sptg.estate.api.entity.User;
import com.sptg.estate.api.feigns.DeviceTestFeign;
import com.sptg.permissions.api.entity.Account;
import com.sptg.permissions.api.feigns.ConfFeign;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * title: DeviceTestController
 * package: com.sptg.estate.biz.service
 * description: 实施小程序-设备检测控制器
 *
 *               
 *                      
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/app/device/test")
public class DeviceTestController {

    private final SecurityServiceInterface<Account> securityServiceInterface;
    private final DeviceTestFeign deviceTestFeign;
    private final DeviceFeign deviceFeign;
    private final FastFileStorageClient fastFileStorageClient;
    private final ConfFeign confFeign;
    private final AdPushTaskFeign adPushTaskFeign;
    /**
     * 功能描述: 统计设备检测数量
     * @return ResultBean<hashMap> 返回结果
     *               
     *                      
     */
    @PostMapping(value = "/count")
    @Security(format = DataFormatEnum.JSON)
    public Map<String,Object> count(){
        Map<String,Object> hashMap = new HashMap<>(3);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "获取结果失败");
        try {
            //获取登录账号
            Account account = this.securityServiceInterface.getOnLineUser();
            // 统计项目数量
            ResultBean<Integer> resultBean = this.deviceTestFeign.countByOrgPosition(account.getOrgPosition());
            if(resultBean.getCode().equals(ResultEnum.SUCCESS.getCode())){
                hashMap.put("result_code", 1);
                hashMap.put("result_msg", "获取成功");
                hashMap.put("count", resultBean.getData());
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }

    /**
     * 功能描述: 根据序列号查下检测记录
     * @return ResultBean<hashMap> 返回结果
     *               
     *                      
     */
    @PostMapping(value = "/findBySerialNumber")
    @Security(format = DataFormatEnum.JSON)
    public Map<String,Object> findBySerialNumber(@RequestBody Map<String,String> map){
        Map<String,Object> hashMap = new HashMap<>(3);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "获取结果失败");
        try {
            String serialNumber = map.get("serialNumber");
            ResultBean<DeviceTest> resultBean = this.deviceTestFeign.findBySerialNumber(serialNumber);
            if(resultBean.getCode().equals(ResultEnum.SUCCESS.getCode())){
                hashMap.put("result_code", 1);
                hashMap.put("result_msg", "获取成功");
                hashMap.put("deviceTest", resultBean.getData());
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }


    /**
     * 功能描述: 设备检测--开门密码下发
     * @param  map{
     *             serialNumber  ;  设备序列号
     *             password      :  密码
     *      }
     * @return ResultBean<hashMap> 返回结果
     *               
     *                     
     */
    @PostMapping(value = "/passwordIssued")
    @Security(format = DataFormatEnum.JSON)
    public Map<String,Object> passwordIssued(@RequestBody Map<String,String> map){
        Map<String,Object> hashMap = new HashMap<>(3);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "密码下发失败");
        try {
            String serialNumber = map.get("serialNumber");
            String password = map.get("password");
            GuestAuthorize ga = new GuestAuthorize();
            ga.setPassword(Integer.valueOf(password));
            ga.setId(IdWorker.getId());
            ga.setGuestType(OperationConstant.THREE);
            ga.setValidCount(10);
            ga.setEnableType(OperationConstant.ZERO);
            ga.setBeginDate(new Date());
            Calendar calendar = Calendar.getInstance();
            // 密码使用期限，当前时间--- 当前时间加12个小时
            calendar.add(Calendar.HOUR, +12);
            ga.setEndDate(calendar.getTime());
            //构建下发数据
            DispatchTask task = new DispatchTask();
            task.setSerialNumber(serialNumber);
            task.setData(ga);
            Map<String,String> logMap = new HashMap<>();
            //密码
            if (null != ga.getPassword()){
                logMap.put("password",ga.getPassword().toString());
            }else {
                logMap.put("password",null);
            }
            //有效期开始时间
            SimpleDateFormat format = new SimpleDateFormat();
            if (null != ga.getBeginDate()){
                logMap.put("beginTime",format.format(ga.getBeginDate()));
            }else {
                logMap.put("beginTime",null);
            }
            //有效期结束时间
            if (null != ga.getEndDate()){
                logMap.put("endTime",format.format(ga.getEndDate()));
            }else {
                logMap.put("endTime",null);
            }
            ResultBean<Boolean> resultBean = deviceFeign.pushTestOpenDoorPwd(task,logMap);
            if(resultBean.getCode().equals(ResultEnum.SUCCESS.getCode()) && resultBean.getData()){
                hashMap.put("result_code", 1);
                hashMap.put("result_msg", "密码下发成功");
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }

    /**
     * 功能描述: 设备检测 -- 一键开门
     * @param  map{
     *             serialNumber  ;  设备序列号
     *      }
     * @return ResultBean<hashMap> 返回结果
     *               
     *                     
     */
    @PostMapping(value = "/openDoor")
    @Security(format = DataFormatEnum.JSON)
    public Map<String,Object> openDoor(@RequestBody Map<String,String> map){
        Map<String,Object> hashMap = new HashMap<>(3);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "开门失败");
        try {
            String serialNumber = map.get("serialNumber");
            Device device = deviceFeign.getEntityBySerialNumber(serialNumber);
            if(device!=null){
                //特殊用户id --数据库不存在
                device.setUserId(UserFlagConstant.TEST_USER_FLAG + "88888888");
                ResultBean<Boolean> resultBean = this.deviceFeign.openDoor(device);
                if(resultBean.getCode().equals(ResultEnum.SUCCESS.getCode()) && resultBean.getData()){
                    hashMap.put("result_code", 1);
                    hashMap.put("result_msg", "开门成功");
                }
            }else{
                hashMap.put("result_msg", "未获取到对应的设备记录");
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }

    /**
     * 功能描述: 设备检测 -- 广告下发送
     * @param  map{
     *             serialNumber  ;  设备序列号
     *      }
     * @return ResultBean<hashMap> 返回结果
     *               
     *                     
     */
    @PostMapping(value = "/adIssued")
    @Security(format = DataFormatEnum.JSON)
    public Map<String,Object> adIssued(@RequestBody Map<String,String> map){
        Map<String,Object> hashMap = new HashMap<>(3);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "下发广告失败");
        try {
            String serialNumber = map.get("serialNumber");
            Device device = deviceFeign.getEntityBySerialNumber(serialNumber);
            if(device!=null){
                ResultBean<Boolean> resultBean = this.adPushTaskFeign.adIssued(device.getId());
                if(resultBean.getCode().equals(ResultEnum.SUCCESS.getCode()) && resultBean.getData()){
                    hashMap.put("result_code", 1);
                    hashMap.put("result_msg", "广告下发成功");
                }
            }else{
                hashMap.put("result_msg", "未获取到对应的设备记录");
            }

        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }

    /**
     * 功能描述: 设备检测 -- 人脸下发
     * @param  map{
     *             serialNumber  ;  设备序列号
     *      }
     * @return ResultBean<hashMap> 返回结果
     *               
     *                     
     */
    @PostMapping(value = "/pushTestFace")
    @Security(format = DataFormatEnum.JSON)
    public Map<String,Object> pushTestFace(@RequestBody Map<String,String> map){
        Map<String,Object> hashMap = new HashMap<>(3);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "人脸下发失败");
        try {
            String serialNumber = map.get("serialNumber");
            String base64Str = map.get("base64Str");
            if(serialNumber!=null && base64Str!=null){
                MultipartFile multipartFile  = Base64DecodeMultipartFileUtils.base64ToMultipart(Base64DecodeMultipartFileUtils.imageFormatToPng(base64Str));
                /*
                 * 返回的对象storePath
                 *  storePath.fullPath = "group1/M00/00/00/wKgAYlvpNveAQ9jgAACQxvfzaOY198.jpg"
                 *  storePath.group = "group1"
                 *  storePath.path = "M00/00/00/wKgAYlvpNveAQ9jgAACQxvfzaOY198.jpg"
                 */
                StorePath storePath = fastFileStorageClient.uploadFile(
                        multipartFile.getInputStream(),multipartFile.getSize(),
                        FilenameUtils.getExtension(multipartFile.getOriginalFilename()),null);
                String fastDfsServer = this.confFeign.getFileServerHost();
                //图片的md5值
                String md5Hex = DigestUtils.md5Hex(multipartFile.getInputStream());

                List<Map<String,Object>> faceCodeList = new ArrayList<>();
                Map<String,Object> user = new HashMap<>(2);
                user.put("imgSrc", fastDfsServer+storePath.getFullPath());
                user.put("imgMd5", md5Hex);
                faceCodeList.add(user);
                UserInfoDto dto = new UserInfoDto();
                dto.setId("888888");
                dto.setFaceCodeList(faceCodeList);
                //构建下发数据
                DispatchTask dispatchTask = new DispatchTask();
                dispatchTask.setSerialNumber(serialNumber);
                dispatchTask.setData(dto);

                ResultBean<Boolean> resultBean = deviceFeign.pushTestFace(dispatchTask);
                if(resultBean.getCode().equals(ResultEnum.SUCCESS.getCode()) && resultBean.getData()){
                    hashMap.put("result_code", 1);
                    hashMap.put("result_msg", "人脸下发成功");
                }
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }


    /**
     * 功能描述: 添加设备检测
     * @param deviceTest
     * @return ResultBean<hashMap> 返回结果
     *               
     *                     
     */
    @PostMapping(value = "/insert")
    @Security(format = DataFormatEnum.JSON)
    public Map<String,Object> insert(@RequestBody DeviceTest deviceTest){
        Map<String,Object> hashMap = new HashMap<>(3);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "添加失败");
        try {
            if(deviceTest.getDeviceInstallationId()==null){
                hashMap.put("result_msg", "设备安装记录id不能为空");
                return hashMap;
            }
            if(StringUtils.isBlank(deviceTest.getSerialNumber())){
                hashMap.put("result_msg", "设备序列号不能为空");
                return hashMap;
            }
            //获取登录账号
            Account account = this.securityServiceInterface.getOnLineUser();
            deviceTest.setCreateDate(new Date());
            deviceTest.setCreateAccountId(account.getId());
            deviceTest.setCreateName(account.getUserName());
            deviceTest.setCheckState(OperationConstant.ZERO);
            deviceTest.setOrgId(account.getOrgId());
            deviceTest.setRootOrgId(account.getRootOrgId());
            deviceTest.setOrgPosition(account.getOrgPosition());
            ResultBean<Boolean> resultBean = this.deviceTestFeign.insertEntity(deviceTest);
            if(resultBean.getCode().equals(ResultEnum.SUCCESS.getCode()) && resultBean.getData()){
                hashMap.put("result_code", 1);
                hashMap.put("result_msg", "添加成功");
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }

    /**
     * 查询设备检测列表(分页)
     * @param page {
     *              current         :    当前页码,
     *              size            :    登录密码
     *
     *            }
     * @param deviceTestDto{
     *            residentialName   :    项目名称
     *         }
     * @return
     *               
     *                     
     */
    @PostMapping(value = "/showList")
    @Security(format = DataFormatEnum.JSON)
    public Map<String,Object> showList(@RequestBody DeviceTestDto deviceTestDto, @RequestBody Page<DeviceTest> page){
        Map<String,Object> hashMap = new HashMap<>(3);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "获取数据失败");
        try {
            //获取当前登陆用户
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            deviceTestDto.setOrgPosition(onLineUser.getOrgPosition());
            deviceTestDto.setPage(page);
            ResultBean<Page<DeviceTest>> resultBean = this.deviceTestFeign.showList(deviceTestDto);
            if(resultBean.getCode().equals(ResultEnum.SUCCESS.getCode())){
                hashMap.put("list", resultBean.getData().getRecords());
                hashMap.put("result_code", 1);
                hashMap.put("result_msg", "成功");
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }

    /**
     * 功能描述:审核状态
     * @param dto
     * {
     *     id:检测id
     *     checkState:审核状态：0-待审核 1-审核通过 2-审核不通过
     *     checkOpinion:审核不通过原因，当checkState = 2有值
     * }
     * @return
     *               
     *                      
     */
    @PostMapping(value = "/checkState")
    public Map<String,Object> checkState(@RequestBody  DeviceTestDto dto){
        Map<String,Object> hashMap = new HashMap<>(3);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "审核失败");
        try {
            //获取审核人信息
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            dto.setCheckName(onLineUser.getUserName());
            dto.setCheckAccountId(onLineUser.getId());
            dto.setCheckDate(new Date());
            ResultBean<Boolean> resultBean = this.deviceTestFeign.checkState(dto);
            if(resultBean.getCode().equals(ResultEnum.SUCCESS.getCode()) &&  resultBean.getData()){
                hashMap.put("result_msg", "审核成功");
                hashMap.put("result_code", 1);
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }

    /**
     * 根据设备安装记录id获取设备检测审核通过的记录
     * @param map {
     *              deviceInstallationIds         :    设备安装记录id
     *
     *            }
     *
     *               
     *                     
     */
    @PostMapping(value = "/findByDeviceInstallationIds")
    @Security(format = DataFormatEnum.JSON)
    public Map<String,Object> findByDeviceInstallationIds(@RequestBody Map<String,String> map){
        Map<String,Object> hashMap = new HashMap<>(3);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "获取数据失败");
        try {
            String deviceInstallationIds = map.get("deviceInstallationIds");
            String[] ids = deviceInstallationIds.split(",");
            List<Long> list = new ArrayList<>();
            for(String id : ids){
                list.add(Long.valueOf(id));
            }
            ResultBean<DeviceTest> resultBean = this.deviceTestFeign.findByDeviceInstallationIds(list);
            if(resultBean.getCode().equals(ResultEnum.SUCCESS.getCode())){
                hashMap.put("list", resultBean.getList());
                hashMap.put("result_code", 1);
                hashMap.put("result_msg", "成功");
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }
}
