package com.jpsoft.shinestar.modules.base.controller;

import com.github.pagehelper.Page;
import com.github.pagehelper.util.StringUtil;
import com.jpsoft.shinestar.config.OSSConfig;
import com.jpsoft.shinestar.modules.base.entity.CompanyInfo;
import com.jpsoft.shinestar.modules.base.entity.DeviceInfo;
import com.jpsoft.shinestar.modules.base.entity.PersonInfo;
import com.jpsoft.shinestar.modules.base.service.CompanyInfoService;
import com.jpsoft.shinestar.modules.base.service.DeviceInfoService;
import com.jpsoft.shinestar.modules.base.service.PersonInfoService;
import com.jpsoft.shinestar.modules.common.utils.OSSUtil;
import com.jpsoft.shinestar.modules.common.utils.PojoUtils;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.common.dto.MessageResult;
import com.jpsoft.shinestar.modules.pacs.dto.IsPersonExistVo;
import com.jpsoft.shinestar.modules.pacs.dto.PacsMsgResult;
import com.jpsoft.shinestar.modules.pacs.dto.PacsResult;
import com.jpsoft.shinestar.modules.pacs.service.IGuardService;
import com.jpsoft.shinestar.modules.uniview.vo.LapiResult;
import com.jpsoft.shinestar.modules.sys.entity.User;
import com.jpsoft.shinestar.modules.base.entity.PersonDeviceRelation;
import com.jpsoft.shinestar.modules.base.service.PersonDeviceRelationService;
import com.jpsoft.shinestar.modules.sys.service.DataDictionaryService;
import com.jpsoft.shinestar.modules.sys.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.*;

@RestController
@RequestMapping("/personDeviceRelation")
@Api(description = "设备和人员绑定")
public class PersonDeviceRelationController {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private PersonDeviceRelationService personDeviceRelationService;

    @Autowired
    private DeviceInfoService deviceInfoService;

    @Autowired
    private UserService userService;

    @Autowired
    private DataDictionaryService dataDictionaryService;

    @Autowired
    private IGuardService guardService;

    @Autowired
    private OSSConfig ossConfig;

    @Autowired
    private PersonInfoService personInfoService;

    @Autowired
    private CompanyInfoService companyInfoService;
    
    @ApiOperation(value="添加设备和人员绑定")
    @Transactional(rollbackFor = Exception.class)
    @PostMapping("add")
    public MessageResult<PersonDeviceRelation> add(@RequestBody PersonDeviceRelation personDeviceRelation,@RequestAttribute String subject){
        MessageResult<PersonDeviceRelation> msgResult = new MessageResult<>();

        try {
            int affectCount = 0;
            Boolean isWrite = true;
            if(personDeviceRelation.getIsWrite() != null){
                isWrite = personDeviceRelation.getIsWrite();
            }

            PersonDeviceRelation item = personDeviceRelationService.findByDeviceIdAndPersonId(personDeviceRelation.getDeviceId(), personDeviceRelation.getPersonId());

            if(item == null) {
                personDeviceRelation.setId(UUID.randomUUID().toString());
                personDeviceRelation.setDelFlag(false);
                personDeviceRelation.setCreateBy(subject);
                personDeviceRelation.setCreateTime(new Date());
                personDeviceRelation.setIsBound(false);//绑定设备默认true

                affectCount = personDeviceRelationService.insert(personDeviceRelation);
            }


            if (affectCount > 0) {
                if(isWrite) {
                    //往设备库传输人脸信息
                    PersonInfo personInfo = personInfoService.get(personDeviceRelation.getPersonId());
                    //如果人员照片不为空
                    if (StringUtils.isNotEmpty(personInfo.getFaceImageUrl())) {
                        DeviceInfo deviceInfo = deviceInfoService.get(personDeviceRelation.getDeviceId());
                        if (!deviceInfo.getIsOnline()) {
                            throw new Exception("无法绑定,设备不在线!");
                        }

                        List<PacsResult> pacsResults = guardService.addPersonToDevices(personDeviceRelation.getPersonId(), personDeviceRelation.getDeviceId());

                        for (int i = 0; i < pacsResults.size(); i++) {
                            PacsResult lapiMsgResult = pacsResults.get(i);

                            if (lapiMsgResult.isSuccess()) {
                                msgResult.setResult(true);
                            } else {
                                throw new Exception("添加失败:" + lapiMsgResult.getMsg());
                            }
                        }
                    } else {
                        //throw new Exception("添加失败:人员没有上传照片" );
                        //没有照片 可以只进行数据绑定 不进行设备操作
                    }
                }
                msgResult.setResult(true);
                msgResult.setData(personDeviceRelation);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库添加失败");
            }
        }
        catch(Exception ex){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error(ex.getMessage(),ex);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="人员与设备批量绑定")
    @PostMapping("batchBindDevice")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "personId",value = "人员ID", required = true,paramType = "query"),
            @ApiImplicitParam(name = "devices",value = "设备ID（多个设备）", required = true, paramType = "query"),
            @ApiImplicitParam(name = "isWrite",value = "是否需要上传照片到设备", required = true, paramType = "query")
    })
    public MessageResult<Integer> batchBindDevice(Long personId,String devices,
      @RequestParam(value = "isWrite", defaultValue = "true")Boolean isWrite,
      @RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();
        int affectCount = 0;

        try {
            HSSFWorkbook workbook = new HSSFWorkbook();
            HSSFSheet sheet = workbook.createSheet();

            if(StringUtil.isNotEmpty(devices)){
               String[] deviceArray = devices.split(",");

               for (String deviceId:deviceArray) {
                   PersonDeviceRelation item = personDeviceRelationService.findByDeviceIdAndPersonId(deviceId,personId);

                   if(item == null) {
                       item = new PersonDeviceRelation();
                       item.setId(UUID.randomUUID().toString());
                       item.setDeviceId(deviceId);
                       item.setPersonId(personId);
                       item.setDelFlag(false);
                       item.setCreateBy(subject);
                       item.setCreateTime(new Date());
                       item.setIsBound(false);//绑定设备默认false

                       affectCount += personDeviceRelationService.insert(item);
                   }else{
                       String personName = "";
                       PersonInfo personInfo = item.getPersonInfo();

                       if (personInfo != null) {
                           personName = personInfo.getName();
                       }

                       HSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1);
                       HSSFCell cell1 = row.createCell(0);
                       cell1.setCellValue(personName);

                       HSSFCell cell2 = row.createCell(1);
                       cell2.setCellValue(item.getDeviceInfo().getAliasName());

                       HSSFCell cell3 = row.createCell(2);
                       cell3.setCellValue("添加失败:");

                       HSSFCell cell4 = row.createCell(3);
                       cell4.setCellValue("已绑定该设备");
                   }
               }
            }

            if (affectCount > 0) {
                if (isWrite) {
                    //往设备库传输人脸信息
                    //批量操作
                    int addCount = 0;
                    //往设备库传输人脸信息
                    PersonInfo personInfo = personInfoService.get(personId);

                    //如果人员照片不为空
                    if (StringUtils.isNotEmpty(personInfo.getFaceImageUrl())) {
                        String[] deviceArr = devices.split(",");

                        for (String deviceId : deviceArr) {
                            DeviceInfo deviceInfo = deviceInfoService.get(deviceId);
                            PacsResult pacsResult = guardService.addPersonToDevice(personId,deviceId);

                            if (pacsResult.isSuccess()) {
                                msgResult.setResult(true);
                            } else {
                                String personName = "";

                                if (personInfo != null) {
                                    personName = personInfo.getName();
                                }

                                HSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1);

                                HSSFCell cell1 = row.createCell(0);
                                cell1.setCellValue(personName);

                                HSSFCell cell2 = row.createCell(1);
                                cell2.setCellValue(deviceInfo.getAliasName());

                                HSSFCell cell3 = row.createCell(2);
                                cell3.setCellValue("添加失败:");

                                HSSFCell cell4 = row.createCell(3);
                                cell4.setCellValue(pacsResult.getMsg());

                                //删除绑定关系
                                PersonDeviceRelation personDeviceRelation = personDeviceRelationService.findByDeviceIdAndPersonId(deviceId, personId);
                                personDeviceRelation.setDelFlag(true);
                                personDeviceRelation.setUpdateBy(subject);
                                personDeviceRelation.setUpdateTime(new Date());
                                personDeviceRelation.setIsBound(false);

                                personDeviceRelationService.update(personDeviceRelation);
                                addCount++;
                            }
                        }
                    }
//
                    if (addCount > 0) {
                        //异常数量大于0,表示有部分数据同步失败
                        msgResult.setResult(false);
                        //保存失败信息
                        ByteArrayOutputStream output = new ByteArrayOutputStream();
                        workbook.write(output);
                        byte[] buffer = output.toByteArray();
                        ByteArrayInputStream input = new ByteArrayInputStream(buffer);
                        String downloadUrl = OSSUtil.upload(ossConfig, "import", "error.xls", input);
                        msgResult.setMessage(downloadUrl);
                    } else {
                        //异常数量为0,表示全部同步成功
                        msgResult.setResult(true);
                        msgResult.setData(affectCount);
                    }
                } else {
                    msgResult.setResult(true);
                    msgResult.setData(affectCount);
                }
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("人员与0个设备绑定成功！");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }



    @ApiOperation(value="多个人员与设备批量绑定")
    @PostMapping("batchBindPerson")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "persons",value = "人员ID(多个人员)", required = true,paramType = "query"),
            @ApiImplicitParam(name = "deviceId",value = "设备ID", required = true, paramType = "query"),
            @ApiImplicitParam(name = "isWrite",value = "是否同步到设备", required = true, paramType = "query")
    })
    public MessageResult<Integer> batchBindPerson(
                                    String persons,
                                    String deviceId,
                                    @RequestParam(value="isWrite",defaultValue="false")  Boolean isWrite,
                                    @RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();
        int affectCount = 0;

        try {
            HSSFWorkbook workbook = new HSSFWorkbook();
            HSSFSheet sheet =workbook.createSheet();

            //同步异常数量
            int addCount = 0;

            if(StringUtil.isNotEmpty(persons)){
                DeviceInfo deviceInfo = deviceInfoService.get(deviceId);

                String[] personArray = persons.split(",");

                for (String strPersonId:personArray) {

                    long personId = Long.parseLong(strPersonId);

                    PersonDeviceRelation item = personDeviceRelationService.findByDeviceIdAndPersonId(deviceId,personId);

                    if(item == null) {
                        item = new PersonDeviceRelation();
                        item.setId(UUID.randomUUID().toString());
                        item.setDeviceId(deviceId);
                        item.setPersonId(personId);
                        item.setDelFlag(false);
                        item.setCreateBy(subject);
                        item.setCreateTime(new Date());
                        item.setIsBound(false);//绑定设备默认false

                        affectCount += personDeviceRelationService.insert(item);
                        //往设备库传输人脸信息
                        //批量操作

                        PersonInfo personInfo = personInfoService.get(personId);

//                        //如果人员照片为空
                        if(StringUtils.isEmpty(personInfo.getFaceImageUrl())){
                            continue;
                        }

                        if(isWrite) {
                            PacsResult pacsResult = guardService.addPersonToDevice(personId, deviceId);

                            if (pacsResult.isSuccess()) {
                                msgResult.setResult(true);
                            } else {
                                HSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1);
                                HSSFCell cell1 = row.createCell(0);
                                cell1.setCellValue(personInfo.getName());

                                HSSFCell cell2 = row.createCell(1);
                                cell2.setCellValue(deviceInfo.getAliasName());

                                HSSFCell cell3 = row.createCell(2);
                                cell3.setCellValue("添加失败:");

                                HSSFCell cell4 = row.createCell(3);
                                cell4.setCellValue(pacsResult.getMsg());

                                //删除绑定关系
                                item.setDelFlag(true);
                                item.setUpdateBy(subject);
                                item.setUpdateTime(new Date());
                                item.setIsBound(false);//绑定设备默认true
                                personDeviceRelationService.update(item);
                                addCount++;
                            }
                        }
                    }
                }
            }

            if (affectCount > 0) {
                if(addCount > 0){
                    //异常数量大于0,表示有部分数据同步失败
                    msgResult.setResult(false);
                    //保存失败信息
                    ByteArrayOutputStream output = new ByteArrayOutputStream();
                    workbook.write(output);
                    byte[] buffer = output.toByteArray();
                    ByteArrayInputStream input = new ByteArrayInputStream(buffer);
                    String downloadUrl = OSSUtil.upload(ossConfig,"import","error.xls",input);
                    msgResult.setMessage(downloadUrl);
                }else {
                    //异常数量为0,表示全部同步成功
                    msgResult.setResult(true);
                    msgResult.setData(affectCount);
                }
            } else {
                msgResult.setResult(true);
                //msgResult.setMessage("有0个人员与设备绑定成功！");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="多个人员与设备批量解除绑定")
    @PostMapping("batchUnBindPerson")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "persons",value = "人员ID(多个人员)", required = true,paramType = "query"),
            @ApiImplicitParam(name = "deviceId",value = "设备ID", required = true, paramType = "query")
    })
    public MessageResult<Integer> batchUnBindPerson(String persons,String deviceId,@RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();
        int affectCount = 0;

        try {
            if(StringUtil.isNotEmpty(persons)){

                String[] personArray = persons.split(",");

                for (String strPersonId:personArray) {

                    long personId = Long.parseLong(strPersonId);

                    PersonDeviceRelation item = personDeviceRelationService.findByDeviceIdAndPersonId(deviceId,personId);

                    if(item != null) {
                        if(item.getIsBound()!=null && item.getIsBound()) {
                            //删除设备上的信息
                            List<PacsMsgResult> pacsMsgResultList = guardService.deletePersonFromDevice(personId, deviceId);

                            if (pacsMsgResultList.size() > 0 && pacsMsgResultList.get(0).isSuccess()) {
                                item.setDelFlag(true);
                                item.setUpdateBy(subject);
                                item.setUpdateTime(new Date());
                                item.setIsBound(false);//绑定设备默认true

                                affectCount += personDeviceRelationService.update(item);
                            }
                        }
                        else{
                            item.setDelFlag(true);
                            item.setUpdateBy(subject);
                            item.setUpdateTime(new Date());
                            item.setIsBound(false);//绑定设备默认true

                            affectCount += personDeviceRelationService.update(item);
                        }
                    }
                }
            }

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(affectCount);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("解绑失败！");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="获取人员和设备绑定信息")
    @GetMapping("edit/{id}")
    public MessageResult<PersonDeviceRelation> edit(@PathVariable("id") String id){
        MessageResult<PersonDeviceRelation> msgResult = new MessageResult<>();

        try {
            PersonDeviceRelation personDeviceRelation = personDeviceRelationService.get(id);

            if (personDeviceRelation != null) {
                msgResult.setResult(true);
                msgResult.setData(personDeviceRelation);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库不存在该记录!");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="更新设备和人员绑定")
    @PostMapping("update")
    public MessageResult<PersonDeviceRelation> update(@RequestBody PersonDeviceRelation personDeviceRelation,@RequestAttribute String subject){
        MessageResult<PersonDeviceRelation> msgResult = new MessageResult<>();

        try {
            personDeviceRelation.setUpdateBy(subject);
            personDeviceRelation.setUpdateTime(new Date());
            
            int affectCount = personDeviceRelationService.update(personDeviceRelation);

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(personDeviceRelation);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库更新失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

	@ApiOperation(value="删除设备和人员绑定")
    @PostMapping("delete/{id}")
    public MessageResult<Integer> delete(@PathVariable("id") String id,@RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();

        try {
            int affectCount = 0;
            PersonDeviceRelation personDeviceRelation = personDeviceRelationService.get(id);

            //删除设备上的信息
            List<PacsMsgResult> pacsMsgResultList = guardService.deletePersonFromDevice(personDeviceRelation.getPersonId(), personDeviceRelation.getDeviceId());

            if (pacsMsgResultList.size() > 0 && pacsMsgResultList.get(0).isSuccess()) {
                personDeviceRelation.setDelFlag(true);
                personDeviceRelation.setUpdateBy(subject);
                personDeviceRelation.setUpdateTime(new Date());

                /**删除同时删除设备**/
                affectCount = personDeviceRelationService.update(personDeviceRelation);
            }

            msgResult.setResult(true);
            msgResult.setData(affectCount);
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }


    @ApiOperation(value="批量删除")
    @PostMapping("batchDelete")
    public MessageResult<Integer> batchDelete(@RequestBody List<String> idList,@RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();

        try {
            int affectCount = 0;

            for (String id : idList) {
                PersonDeviceRelation personDeviceRelation = personDeviceRelationService.get(id);
                personDeviceRelation.setDelFlag(true);
                personDeviceRelation.setUpdateBy(subject);
                personDeviceRelation.setUpdateTime(new Date());

                /**删除同时删除设备**/
                //affectCount = personDeviceRelationService.updateDevicePerson(personDeviceRelation);

                affectCount = personDeviceRelationService.update(personDeviceRelation);
            }


            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(affectCount);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("删除失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="列表")
    @RequestMapping(value = "pageList",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceId",value = "设备ID",  paramType = "query"),
            @ApiImplicitParam(name = "personId",value = "人员ID",  paramType = "query"),
            @ApiImplicitParam(name = "deviceName",value = "设备名称",  paramType = "query")
    })
    public MessageResult<Map> pageList(
            String deviceId,String personId,String deviceName,
            @RequestParam(value="pageIndex",defaultValue="1") int pageIndex,
            @RequestParam(value="pageSize",defaultValue="20") int pageSize,
            @RequestAttribute String subject){

        //当前用户ID
        System.out.println(subject);

        MessageResult<Map> msgResult = new MessageResult<>();

        Map<String,Object> searchParams = new HashMap<>();
        List<Sort> sortList = new ArrayList<>();
        sortList.add(new Sort("create_time","desc"));

        if (StringUtils.isNotEmpty(deviceId)) {
            searchParams.put("deviceId",deviceId);
        }

        if (StringUtils.isNotEmpty(personId)) {
            searchParams.put("personId",personId);
        }

        if (StringUtils.isNotEmpty(deviceName)) {
            searchParams.put("deviceName","%" + deviceName + "%");
        }

        Page<PersonDeviceRelation> page = personDeviceRelationService.pageSearch(searchParams,pageIndex,pageSize,true,sortList);

//        for(PersonDeviceRelation pdr : page.getResult()){
//            DeviceInfo  di = pdr.getDeviceInfo();
//            PersonInfo personInfo = pdr.getPersonInfo();
//            String faceDbId = "";
//            Boolean isWrite = false;
//            try {
//                //查找人脸ID
//                faceDbId = guardService.getFaceDbId(di,personInfo.getCompanyName());
//                //查询人员是否成功写入设备
//                isWrite = guardService.isPersonImageExist(personInfo,di,faceDbId);
//
//            }catch (Exception e){
//                isWrite = false;
//            }
//
//            pdr.setIsWrite(isWrite);
//        }


        msgResult.setResult(true);
        msgResult.setData(PojoUtils.pageWrapper(page));

        return msgResult;
    }


    @ApiOperation(value="根据人员ID查询设备列表")
    @RequestMapping(value = "listByPersonId",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "personId",value = "人员ID",paramType = "query")
    })
    public MessageResult<List<PersonDeviceRelation>> listByPersonId(Long personId){

        MessageResult<List<PersonDeviceRelation>> msgResult = new MessageResult<>();

        List<PersonDeviceRelation> personDeviceRelationList = personDeviceRelationService.findByPersonId(personId);

        msgResult.setResult(true);
        msgResult.setData(personDeviceRelationList);

        return msgResult;
    }



    @ApiOperation(value="根据设备ID查询人员列表")
    @RequestMapping(value = "listByDeviceId",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceId",value = "设备ID",paramType = "query")
    })
    public MessageResult<List<PersonDeviceRelation>> listByDeviceId(String deviceId){

        MessageResult<List<PersonDeviceRelation>> msgResult = new MessageResult<>();

        List<PersonDeviceRelation> personDeviceRelationList = personDeviceRelationService.findByDeviceId(deviceId);

        msgResult.setResult(true);
        msgResult.setData(personDeviceRelationList);

        return msgResult;
    }


    @ApiOperation(value="人员解绑所有设备")
    @RequestMapping(value = "unbindDevice",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "personId",value = "人员ID",paramType = "query")
    })
    public MessageResult<Integer> unbindDevice(Long personId,@RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();

        try{
            List<PersonDeviceRelation> personDeviceRelationList = personDeviceRelationService.findByPersonId(personId);

            int affectCount = 0;

            for (PersonDeviceRelation personDeviceRelation: personDeviceRelationList){
                List<PacsMsgResult> pacsMsgResultList = guardService.deletePersonFromDevice(personId, personDeviceRelation.getDeviceId());

                if (pacsMsgResultList.size() > 0 && pacsMsgResultList.get(0).isSuccess()) {
                    personDeviceRelation.setDelFlag(true);
                    personDeviceRelation.setUpdateBy(subject);
                    personDeviceRelation.setUpdateTime(new Date());
                    affectCount += personDeviceRelationService.update(personDeviceRelation);
                }
            }

            //删除所有设备上的信息
//            new Thread(()->{
//                try {
//                    guardService.deletePerson(personId);
//                }
//                catch (Exception ex){
//                    logger.error(ex.getMessage(),ex);
//                }
//            }).start();

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(affectCount);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("删除失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="人员解绑选择的设备")
    @RequestMapping(value = "unbindSelectDevice",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "personId",value = "人员ID",paramType = "query"),
            @ApiImplicitParam(name = "deviceIds",value = "设备编号集合",paramType = "query")
    })
    public MessageResult<Integer> unbindSelectDevice(Long personId,String deviceIds,@RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();

        try{
            if(StringUtils.isEmpty(deviceIds)){
                throw new Exception("未选择设备!");
            }

            int affectCount = 0;

            String[] deviceIdList = deviceIds.split(",");
            for(String deviceId : deviceIdList){
                PersonDeviceRelation personDeviceRelation = personDeviceRelationService.findByDeviceIdAndPersonId(deviceId,personId);
                if(personDeviceRelation == null){
                    continue;
                }

                List<PacsMsgResult> pacsMsgResultList = guardService.deletePersonFromDevice(personId, deviceId);

                if (pacsMsgResultList.size() > 0 && pacsMsgResultList.get(0).isSuccess()) {
                    personDeviceRelation.setDelFlag(true);
                    personDeviceRelation.setUpdateBy(subject);
                    personDeviceRelation.setUpdateTime(new Date());
                    personDeviceRelationService.update(personDeviceRelation);
                    affectCount++;
                }

                //删除所有设备上的信息
//                new Thread(()->{
//                    try {
//                        guardService.deletePersonFromDevice(personId,deviceId);
//                    }
//                    catch (Exception ex){
//                        logger.error(ex.getMessage(),ex);
//                    }
//                }).start();
            }

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(affectCount);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("删除失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }


    @ApiOperation(value="人员查询是否绑定设备")
    @RequestMapping(value = "isUnbindDeviceList",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "personId",value = "人员ID",required = true ,paramType = "query"),
            @ApiImplicitParam(name = "deviceNo",value = "设备编号",required = true ,paramType = "query"),
            @ApiImplicitParam(name = "deviceName",value = "设备名称",required = true ,paramType = "query")
    })
    public MessageResult<Map> isUnbindDeviceList(
            Long personId,
            @RequestParam(value="deviceNo",defaultValue="") String deviceNo,
            @RequestParam(value="deviceName",defaultValue="") String deviceName,
            @RequestParam(value="pageIndex",defaultValue="1") int pageIndex,
            @RequestParam(value="pageSize",defaultValue="20") int pageSize,@RequestAttribute String subject){

        MessageResult<Map> msgResult = new MessageResult<>();

        User user = userService.get(subject);

        Map<String,Object> searchParams = new HashMap<>();

        //系统管理员
        boolean isSysAdmin = userService.hasRole(subject,"SYSADMIN");

        if(!isSysAdmin){
            String userCompanyId = user.getCompanyId();

            List<DeviceInfo> deviceInfoList = deviceInfoService.findByCompanyId(userCompanyId);
            List<String> deviceIdList = new ArrayList<String>();
            if(deviceInfoList.size() > 0) {
                for (DeviceInfo deviceInfo : deviceInfoList) {
                    deviceIdList.add(deviceInfo.getId());
                }
            }else{
                deviceIdList.add("-1");
            }

            searchParams.put("deviceIdList",deviceIdList);
        }

        //searchParams.put("companyId",user.getCompanyId());

        if(StringUtils.isNotEmpty(deviceNo)){
            searchParams.put("deviceNo","%" + deviceNo + "%");
        }
        if(StringUtils.isNotEmpty(deviceName)){
            searchParams.put("aliasName","%" + deviceName + "%");
        }

        List<Sort> sortList = new ArrayList<>();

        if(personId != null){
            searchParams.put("isBoundPersonId",personId);
            sortList.add(new Sort("is_bind","desc"));
        }
        sortList.add(new Sort("is_online","desc"));
        sortList.add(new Sort("create_time","desc"));

        Page<DeviceInfo> page = deviceInfoService.pageSearch(searchParams,pageIndex,pageSize,true,sortList);

        for (DeviceInfo deviceInfo:page) {
//            PersonDeviceRelation item = personDeviceRelationService.findByDeviceIdAndPersonId(deviceInfo.getId(),personId);
//            if(item == null){
//                deviceInfo.setIsBindPerson(false);
//            }
//            else{
//                deviceInfo.setIsBindPerson(true);
//            }
            String typeN = dataDictionaryService.findNameByCatalogNameAndValue("设备类型",deviceInfo.getType());
            deviceInfo.setTypeN(typeN);
        }

        msgResult.setResult(true);
        msgResult.setData(PojoUtils.pageWrapper(page));

        return msgResult;

    }

    @ApiOperation(value="设备人员列表")
    @RequestMapping(value = "devicePersonList",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name",value = "姓名", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "idCard",value = "身份证", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "phone",value = "手机号", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "parentId",value = "上级企业ID", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "subordinate",value = "是否查询下级单位", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "derviceId",value = "设备编号", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "position1",value = "一级位置", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "position2",value = "二级位置", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "position3",value = "三级位置", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "position4",value = "四级位置", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "position5",value = "五级位置", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "faceBound",value = "是否同步", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "isUploadPhoto",value = "是否上传照片", required = false, paramType = "form",dataType = "String")
    })
    public MessageResult<Map> devicePersonList(
            @RequestParam(value="name",defaultValue="") String name,
            @RequestParam(value="idCard",defaultValue="") String idCard,
            @RequestParam(value="phone",defaultValue="") String phone,
            @RequestParam(value="companyCode",defaultValue="")  String companyCode,
            @RequestParam(value="parentId",defaultValue="")  String parentId,
            @RequestParam(value="subordinate",defaultValue="false")  Boolean subordinate,
            @RequestParam(value="deviceId",defaultValue="") String deviceId,
            @RequestParam(value="position1",defaultValue="") String position1,
            @RequestParam(value="position2",defaultValue="") String position2,
            @RequestParam(value="position3",defaultValue="") String position3,
            @RequestParam(value="position4",defaultValue="") String position4,
            @RequestParam(value="position5",defaultValue="") String position5,
            @RequestParam(value="pageIndex",defaultValue="1") int pageIndex,
            @RequestParam(value="pageSize",defaultValue="20") int pageSize,
            @RequestParam(value="isBound",defaultValue="") Integer isBound,
            @RequestParam(value="isUploadPhoto",defaultValue="") String isUploadPhoto,
            @RequestAttribute String subject){

        //当前用户ID
        User user = userService.get(subject);

        CompanyInfo companyInfo = companyInfoService.get(user.getCompanyId());

        MessageResult<Map> msgResult = new MessageResult<>();

        Map<String,Object> searchParams = new HashMap<>();



        if (StringUtils.isNotEmpty(name)) {
            String[] names = name.split(",");
            List nameList = new ArrayList();
            for (String n : names) {
                nameList.add("%"+ n +"%");
            }
            searchParams.put("nameList", nameList);
        }

        if (StringUtils.isNotEmpty(idCard)) {
            searchParams.put("idCard","%" + idCard + "%");
        }

        if (StringUtils.isNotEmpty(phone)) {
            searchParams.put("phone","%" + phone + "%");
        }

        if (StringUtils.isEmpty(companyCode)){
            if (!userService.hasRole(subject,"SYSADMIN")) {
                searchParams.put("companyCode", companyInfo.getCode() + "%");
            }
        }
        else{
            if(subordinate){
                searchParams.put("companyCode", companyCode + "%");
            }
            else {
                searchParams.put("companyCode", companyCode);
            }
        }

        if(StringUtils.isNotEmpty(parentId)){
            CompanyInfo parentCompanyInfo = companyInfoService.get(parentId);

            String parentCode = parentCompanyInfo.getCode();

            if (StringUtils.isEmpty(parentCode)){
                if (!userService.hasRole(subject,"SYSADMIN")) {
                    searchParams.put("companyCode", parentCode + "%");
                }
            }
            else{
                if(subordinate){
                    searchParams.put("companyCode", parentCode + "%");
                }
                else {
                    searchParams.put("companyCode", parentCode);
                }
            }
        }

        if (StringUtils.isNotEmpty(position1)) {
            searchParams.put("position1","%" + position1 + "%");
        }
        if (StringUtils.isNotEmpty(position2)) {
            searchParams.put("position2","%" + position2 + "%");
        }
        if (StringUtils.isNotEmpty(position3)) {
            searchParams.put("position3","%" + position3 + "%");
        }
        if (StringUtils.isNotEmpty(position4)) {
            searchParams.put("position4","%" + position4 + "%");
        }
        if (StringUtils.isNotEmpty(position5)) {
            searchParams.put("position5","%" + position5 + "%");
        }

        if(isBound != null){
            searchParams.put("isBound",isBound);
        }

        if(StringUtils.isNotEmpty(isUploadPhoto)){
            searchParams.put("isUploadPhoto", isUploadPhoto);
        }

        if(StringUtils.isNotEmpty(deviceId)){
            searchParams.put("deviceId", deviceId);
        }

        List<Sort> sortList = new ArrayList<>();
        sortList.add(new Sort("person_id","asc"));

        Page<PersonDeviceRelation> page = personDeviceRelationService.pageSearch(searchParams,pageIndex,pageSize,true,sortList);

//        Page<PersonInfo> page = personInfoService.pageSearch(searchParams,pageIndex,pageSize,true,sortList);
//        Page<PersonInfoDTO> pageDTO = PojoUtils.convertPage(page, PersonInfoDTO.class);
//
//        for(PersonInfoDTO dto : pageDTO.getResult()){
//            List<DeviceInfo> deviceNameList = personDeviceRelationService.findDeviceByPersonId(dto.getId());
//
//            String deviceName = deviceNameList.stream()
//                    .map((device)->device.getAliasName())
//                    .collect(Collectors.joining(","));
//
//            dto.setDeviceName(deviceName);
//        }

        msgResult.setResult(true);
        msgResult.setData(PojoUtils.pageWrapper(page));

        return msgResult;
    }

    @ApiOperation(value="用户和单设备数据同步")
    @PostMapping("devicePersonSync")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "personId", value = "人员ID", required = false, paramType = "form", dataType = "String"),
            @ApiImplicitParam(name = "deviceId", value = "设备ID", required = false, paramType = "form", dataType = "String"),
    })
    public MessageResult<Boolean> devicePersonSync(
            @RequestParam(value="personId",defaultValue="") String personId,
            @RequestParam(value="deviceId",defaultValue="") String deviceId
    ){
        MessageResult<Boolean> msgResult = new MessageResult<>();
        msgResult.setData(true);
        msgResult.setResult(true);
        try {
            PersonInfo personInfo = personInfoService.get(Long.valueOf(personId));
            if (personInfo==null){
                throw new Exception("人员信息不存在!");
            }

            PacsResult pacsResult = guardService.addPersonToDevice(personInfo.getId(),deviceId);

            if (!pacsResult.isSuccess()) {
                throw  new Exception(pacsResult.getMsg());
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="用户和单设备数据同步")
    @PostMapping("devicePersonsSync")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "personIds", value = "人员ID", required = false, paramType = "form", dataType = "String"),
            @ApiImplicitParam(name = "deviceId", value = "设备ID", required = false, paramType = "form", dataType = "String"),
    })
    public MessageResult<Boolean> devicePersonsSync(
            @RequestParam(value="personIds",defaultValue="") List<String> personIds,
            @RequestParam(value="deviceId",defaultValue="") String deviceId
            ){
        MessageResult<Boolean> msgResult = new MessageResult<>();
        msgResult.setData(true);
        msgResult.setResult(true);

        try {
            HSSFWorkbook workbook = new HSSFWorkbook();
            HSSFSheet sheet = workbook.createSheet();

            for(String personId : personIds){
                PersonInfo personInfo = personInfoService.get(Long.valueOf(personId));

                if (personInfo==null){
                    throw new Exception("人员信息不存在!");
                }

                if(!addPersonForDeviceIds(personInfo,deviceId, sheet)){
                    msgResult.setData(false);
                }
            }

            if(!msgResult.getData()){
                ByteArrayOutputStream output = new ByteArrayOutputStream();
                workbook.write(output);
                byte[] buffer = output.toByteArray();
                ByteArrayInputStream input = new ByteArrayInputStream(buffer);
                String downloadUrl = OSSUtil.upload(ossConfig,"import","error.xls",input);

                msgResult.setMessage(downloadUrl);
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="添加设备人员图片")
    private Boolean addPersonForDeviceIds(PersonInfo personInfo,String deviceId, HSSFSheet sheet){
        boolean bl = true;

        try {
            List<PacsResult> msgResultList = guardService.addPersonToDevices(personInfo.getId(),deviceId);

            for (int i = 0; i < msgResultList.size(); i++) {
                PacsResult pacsResult = msgResultList.get(i);

                if (!pacsResult.isSuccess()) {
                    Map resultMap = (Map)pacsResult.getData();
                    HSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1);
                    HSSFCell cell1 = row.createCell(0);
                    cell1.setCellValue(personInfo.getName());
                    HSSFCell cell2 = row.createCell(1);
                    cell2.setCellValue(resultMap.get("deviceAliasName").toString());
                    HSSFCell cell3 = row.createCell(2);
                    cell3.setCellValue("绑定人脸信息失败!");
                    HSSFCell cell4 = row.createCell(3);
                    cell4.setCellValue(pacsResult.getMsg());

                    bl = false;
                }
            }
        }catch(Exception ex) {
            logger.error(ex.getMessage(), ex);
            bl = false;

            HSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1);

            HSSFCell cell1 = row.createCell(0);
            cell1.setCellValue(personInfo.getName());

            HSSFCell cell2 = row.createCell(1);
            cell2.setCellValue("");

            HSSFCell cell3 = row.createCell(2);
            cell3.setCellValue("");

            HSSFCell cell4 = row.createCell(3);
            cell4.setCellValue(ex.getMessage());
        }

        return bl;
    }

    @ApiOperation(value="更新单个用户图片存在状态")
    @RequestMapping(value = "updatePersonIsWrite",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "personId",value = "姓名", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name = "deviceIds",value = "设备ID,逗号分隔", required = false, paramType = "form",dataType = "String"),
    })
    public MessageResult<Boolean> updatePersonIsWrite(
            @RequestParam(value="personId",defaultValue="") Long personId,
            @RequestParam(value="deviceIds",defaultValue="") String deviceIds,
            @RequestAttribute String subject){

        //当前用户ID
        User user = userService.get(subject);

        CompanyInfo companyInfo = companyInfoService.get(user.getCompanyId());

        MessageResult<Boolean> msgResult = new MessageResult<>();
        msgResult.setData(true);
        msgResult.setResult(true);

        Map<String,Object> searchParams = new HashMap<>();

        List<PersonDeviceRelation> pdrList = personDeviceRelationService.findByPersonId(personId);
        for(PersonDeviceRelation pdr : pdrList){
            DeviceInfo  di = pdr.getDeviceInfo();
            //这里查询人员信息实际是在xml中调用personInfoDAO。get方法，注意不要加del_flag=0，否则无法查询到已删除用户
            PersonInfo personInfo = pdr.getPersonInfo();
            String faceDbId = "";
            Boolean isWrite = false;
            try {
//                //查找人脸ID
//                faceDbId = guardService.getFaceDbId(di,personInfo.getCompanyName());
//                //查询人员是否成功写入设备
//                isWrite = guardService.isPersonImageExist(personInfo,di,faceDbId);

                List<IsPersonExistVo> personExistList = guardService.existPersonInDevice(Arrays.asList(personInfo.getId()),di);

                if (personExistList.size()>0){
                    isWrite = personExistList.get(0).getIsPersonExist();
                }
            }catch (Exception e){
                isWrite = false;
            }
            //更新状态
            pdr.setIsBound(isWrite);
            pdr.setUpdateBy(subject);
            pdr.setUpdateTime(new Date());
            personDeviceRelationService.update(pdr);
        }

        msgResult.setResult(true);

        return msgResult;
    }

    @ApiOperation(value="单用户和设备数据同步")
    @PostMapping("devicesPersonSync")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "personId", value = "人员ID", required = false, paramType = "form", dataType = "String"),
            @ApiImplicitParam(name = "deviceIds", value = "设备ID", required = false, paramType = "form", dataType = "String"),
    })
    public MessageResult<Boolean> devicesPersonSync(
            @RequestParam(value="personId",defaultValue="") String personId,
            @RequestParam(value="deviceIds",defaultValue="") String deviceIds
    ){
        MessageResult<Boolean> msgResult = new MessageResult<>();
        msgResult.setData(true);
        msgResult.setResult(true);
        try {
            PersonInfo personInfo = personInfoService.get(Long.valueOf(personId));
            if (personInfo==null){
                throw new Exception("人员信息不存在!");
            }

            List<PacsResult> msgResultList = guardService.addPersonToDevices(personInfo.getId(),deviceIds);

            for (int i = 0; i < msgResultList.size(); i++) {
                PacsResult pacsResult = msgResultList.get(i);

                if (!pacsResult.isSuccess()) {
                    throw  new Exception(pacsResult.getMsg());
                }
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

}
