package com.dcsoft.system.face.service.impl;

import java.io.File;
import java.util.*;

import com.dcsoft.common.core.domain.R;
import com.dcsoft.common.core.exception.ServiceException;
import com.dcsoft.common.core.utils.DateUtils;
import com.dcsoft.common.core.utils.StringUtils;
import com.dcsoft.common.core.utils.bean.BeanValidators;
import com.dcsoft.common.core.utils.file.FileUtils;
import com.dcsoft.common.core.web.domain.AjaxResult;
import com.dcsoft.common.security.utils.SecurityUtils;
import com.dcsoft.system.api.RemoteFileService;
import com.dcsoft.system.api.domain.SysFile;
import com.dcsoft.system.api.domain.SysUser;
import com.dcsoft.system.face.domain.FaceImage;
import com.dcsoft.system.face.domain.FaceRule;
import com.dcsoft.system.face.domain.FaceStudent;
import com.dcsoft.system.face.mapper.FaceImageMapper;
import com.dcsoft.system.face.mapper.FaceRuleMapper;
import com.dcsoft.system.face.service.HumanService;
import com.dcsoft.system.face.service.MsgService;
import com.dcsoft.system.utils.PictureUtils;
import com.dcsoft.system.utils.ZipUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.dcsoft.system.face.mapper.FaceStudentMapper;
import com.dcsoft.system.face.service.IFaceStudentService;
import org.springframework.web.multipart.MultipartFile;

/**
 * 学生信息Service业务层处理
 *
 * @author nichun
 * @date 2023-03-30
 */
@Service
public class FaceStudentServiceImpl implements IFaceStudentService {
    @Autowired
    private FaceStudentMapper faceStudentMapper;

    //@Value("${image.excelShortPath}")
    public String excelShortPath;

    @Autowired
    private RemoteFileService  remoteFileService;


    @Autowired
    private FaceImageMapper faceImageMapper;

    @Autowired
    private HumanService humanService;

    @Autowired
    private MsgService msgService;

    @Autowired
    private FaceRuleMapper faceRuleMapper;


    /**
     * 查询学生信息
     *
     * @param id 学生信息主键
     * @return 学生信息
     */
    @Override
    public FaceStudent selectFaceStudentById(Long id)
    {
        return faceStudentMapper.selectFaceStudentById(id);
    }

    /**
     * 查询学生信息列表
     *
     * @param faceStudent 学生信息
     * @return 学生信息
     */
    @Override
    public List<FaceStudent> selectFaceStudentList(FaceStudent faceStudent)
    {
        return faceStudentMapper.selectFaceStudentList(faceStudent);
    }

    /**
     * 新增学生信息
     *
     * @param faceStudent 学生信息
     * @return 结果
     */
    @Override
    public int insertFaceStudent(FaceStudent faceStudent)
    {
        faceStudent.setCreateTime(DateUtils.getNowDate());
        //对接中台上安硬件接口
        if(StringUtils.isNotEmpty(faceStudent.getImgs())){
            faceStudent.setSync("1");
            String sync=humanService.syncFace(faceStudent);
        }
        //判断是否进行人工审核还是自动审核,如果自动审核则核验通过，如果手动审核则是未核验
        List<FaceRule> faceRule=faceRuleMapper.selectFaceRuleList(new FaceRule());
        if(faceRule.size()>0){
            if(StringUtils.isNotEmpty(faceStudent.getImgs())){
                if("1".equals(faceRule.get(0).getShms())){
                    faceStudent.setErification("1");
                }else{
                    faceStudent.setErification("0");
                }
            }else{
                faceStudent.setErification("0");
            }
        }
        return faceStudentMapper.insertFaceStudent(faceStudent);
    }

    /**
     * 修改学生信息
     *
     * @param faceStudent 学生信息
     * @return 结果
     */
    @Override
    public int updateFaceStudent(FaceStudent faceStudent)
    {
        faceStudent.setUpdateTime(DateUtils.getNowDate());
        //对接中台上安硬件接口
        if(StringUtils.isNotEmpty(faceStudent.getImgs())){
            faceStudent.setSync("2");
            String sync=humanService.syncFace(faceStudent);
        }
        if(StringUtils.isEmpty(faceStudent.getImgs())){
            faceStudent.setErification("0");
        }
        return faceStudentMapper.updateFaceStudent(faceStudent);
    }

    /**
     * 批量删除学生信息
     *
     * @param ids 需要删除的学生信息主键
     * @return 结果
     */
    @Override
    public int deleteFaceStudentByIds(Long[] ids)
    {
        //对接中台上安硬件接口
        for(long id:ids){
            FaceStudent faceStudent=faceStudentMapper.selectFaceStudentById(id);
            if(StringUtils.isNotEmpty(faceStudent.getImgs())){
                faceStudent.setSync("3");
                String sync=humanService.syncFace(faceStudent);
            }
            faceImageMapper.deleteFaceImageByStuId(faceStudent.getStuId());
        }
        return faceStudentMapper.deleteFaceStudentByIds(ids);
    }

    /**
     * 删除学生信息信息
     *
     * @param id 学生信息主键
     * @return 结果
     */
    @Override
    public int deleteFaceStudentById(Long id)
    {
        FaceStudent faceStudent=faceStudentMapper.selectFaceStudentById(id);
        if(StringUtils.isNotEmpty(faceStudent.getImgs())){
            faceStudent.setSync("3");
            String sync=humanService.syncFace(faceStudent);
        }
        faceImageMapper.deleteFaceImageByStuId(faceStudent.getStuId());
        return faceStudentMapper.deleteFaceStudentById(id);
    }

    @Override
    public StringBuffer importPicture(MultipartFile picture, Boolean isUpdateSupport) throws Exception {
        String qrCodeZIPName = UUID.randomUUID() + ".zip";
        StringBuffer sb = new StringBuffer();
        File file= FileUtils.byte2File(picture.getBytes(), excelShortPath,qrCodeZIPName);
        String s1=file.getName();
        String prefix = qrCodeZIPName.substring(qrCodeZIPName.lastIndexOf("."));
        int num = prefix.length();//得到后缀名长度
        String s2 = s1.substring(0, s1.length() - num);//得到文件名。去掉了后缀
        List<FaceStudent> getOriginalPic = ZipUtil.getOriginalPic(excelShortPath + s1, excelShortPath + s2);
        List<FaceStudent> peopleDtoList =new ArrayList<>();
        List<String> errorList = new ArrayList<String>();
        List<String> existCode = new ArrayList<String>();
        for (int j = 0; j < getOriginalPic.size(); j++) {
            String fileName = getOriginalPic.get(j).getImgs();
            String fix = fileName.substring(fileName.lastIndexOf("."));
            int number = fix.length();//得到后缀名长度
            String fileOtherName = fileName.substring(0, fileName.length() - number);//得到文件名。去掉了后缀
            //根据文件名查找学工信息
            FaceStudent student=faceStudentMapper.selectFaceStudentByStuId(fileOtherName);
            if (student!=null) {
                //这里是存进数据库的url
                MultipartFile files=PictureUtils.getMultipartFile(getOriginalPic.get(j).getFile());
                if(isUpdateSupport){//是否核验人脸算法 是的话走人脸算法核验，有限流功能
                    R<SysFile> fileNames =remoteFileService.uploadMinio(files,student.getStuId());
                    student.setImgs(fileNames.getData().getUrl());
                    if(StringUtils.isEmpty(fileNames.getData().getUrl())){
                        errorList.add(fileOtherName);
                    }else{
                        peopleDtoList.add(student);
                    }
                }else{
                    R<SysFile> fileNames =remoteFileService.uploadMinios(files,student.getStuId());
                    student.setImgs(fileNames.getData().getUrl());
                    if(StringUtils.isEmpty(fileNames.getData().getUrl())){
                        errorList.add(fileOtherName);
                    }else{
                        peopleDtoList.add(student);
                    }
                }
            }else{
                existCode.add(fileOtherName);
            }
        }

        if (existCode != null && existCode.size() > 0) {
            sb.append("学工号为 " + existCode + " 的学号不存在数据库。");
        }
        if (errorList != null && errorList.size() > 0) {
            sb.append("学工号为 " + errorList + " 的图片不存在或没有人脸。");
        }
        List<String> errorString = batchAdd(peopleDtoList);
        if (errorString.size() == 0) {
            return sb;
        } else {
            sb.append("失败学工号列表：" + errorString);
        }
        return sb;
    }
    private List<String> batchAdd(List<FaceStudent> peopleDtoList) {
        List<String> errorString = new LinkedList<String>();
        if (peopleDtoList.size() > 0 && peopleDtoList != null) {
            for (FaceStudent faceStudent : peopleDtoList) {
                faceStudentMapper.updateFaceStudent(faceStudent);
                FaceImage faceImage=new FaceImage();
                faceImage.setImgs(faceStudent.getImgs());
                faceImage.setStuId(faceStudent.getStuId());
                faceImage.setLabel("0");//工作照
                faceImageMapper.insertFaceImage(faceImage);
                //这里可以判断数据库是否有重叠数据，和一些具体业务
            }
            //
           /* if (this.saveBatch(peopleModels)) {
                for (PeopleModel peopleModel : peopleModels) {
                    //这里可以做一些外接设备的业务处理
                    //errorString.add(peopleModel.getCode());
                }
            } else {
                errorString.add("保存数据库失败");
            }*/
        }
        return errorString;
    }

    //手机端获取学生信息，通过学工号和证件号获取
    @Override
    public FaceStudent getStudent(FaceStudent faceStudent) {
        return faceStudentMapper.getStudent(faceStudent);
    }

    @Override
    public AjaxResult top() {
        List<Map<String,Object>> list=faceStudentMapper.top();
        return AjaxResult.success(list);
    }

    @Override
    public AjaxResult topChart() {
        List<Map<String,Object>> list=faceStudentMapper.topChart();
        return AjaxResult.success(list);
    }

    @Override
    public AjaxResult getGather() {
        List<Map<String,Object>> list=faceStudentMapper.getGather();
        return AjaxResult.success(list);
    }

    /**
     * 导入用户数据
     *
     * @param userList 用户数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    public String importStudent(List<FaceStudent> userList, Boolean isUpdateSupport, String operName)
    {
        if (StringUtils.isNull(userList) || userList.size() == 0)
        {
            throw new ServiceException("导入用户数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (FaceStudent user : userList)
        {
            try
            {
                // 验证是否存在这个用户
                FaceStudent u = faceStudentMapper.selectFaceStudentByStuId(user.getStuId());
                if (StringUtils.isNull(u))
                {
                    user.setCreateBy(operName);
                    this.insertFaceStudent(user);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、学工号 " + user.getStuId() + " 导入成功");
                }
                else if (isUpdateSupport)
                {
                    user.setUpdateBy(operName);
                    this.updateFaceStudent(user);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、学工号 " + user.getStuId() + " 更新成功");
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、学工号 " + user.getStuId() + " 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、学工号 " + user.getStuId() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }


    /**
     * 批量删除学生信息
     *
     * @param ids 需要删除的学生信息主键
     * @return 结果
     */
    @Override
    public int examineStudentByIds(Long[] ids,String erification)
    {
        Map<String,Object> map=new HashMap<>();
        map.put("id",ids);
        map.put("erification",erification);
        //发送消息给人员说审核是否通过
        String accounts="";
        for(Long id:ids){
            FaceStudent student=faceStudentMapper.selectFaceStudentById(id);
            accounts+=student.getStuId()+";";
        }
        if(StringUtils.isNotEmpty(accounts)){
            accounts=accounts.substring(0,accounts.length()-1);
        }
        map.put("accounts",accounts);
        String msg=msgService.sendDing(map);

        return faceStudentMapper.examineStudentByIds(map);
    }

}
