package com.xueyi.system.pass.controller.api;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xueyi.common.core.web.result.R;
import com.xueyi.common.security.annotation.InnerAuth;
import com.xueyi.common.web.constant.ResponseCode;
import com.xueyi.common.web.response.MyResponse;
import com.xueyi.common.web.utils.DateUtils;
import com.xueyi.file.api.domain.SysFile;
import com.xueyi.file.api.feign.RemoteFileService;
import com.xueyi.system.api.pass.domain.dto.DmRecognizedMultiRecordsDto;
import com.xueyi.system.api.pass.domain.dto.DmRecognizedRecordsDto;
import com.xueyi.system.api.pass.domain.po.DmRecognizedRecordsPo;
import com.xueyi.system.api.staff.domain.po.DmStaffPo;
import com.xueyi.system.pass.domain.model.DmRecognizedRecordsConverter;
import com.xueyi.system.pass.mapper.DmRecognizedRecordsMapper;
import com.xueyi.system.pass.service.impl.DmRecognizedRecordsServiceImpl;
import com.xueyi.system.resource.controller.api.BaseApiController;
import com.xueyi.system.resource.domain.dto.DmResourcesDto;
import com.xueyi.system.resource.service.impl.DmResourcesServiceImpl;
import com.xueyi.system.resource.service.impl.FaceServiceImpl;
import com.xueyi.system.staff.mapper.DmStaffMapper;
import com.xueyi.system.staff.service.impl.DmStaffServiceImpl;
import com.xueyi.system.utils.common.ImageUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
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 java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

/**
 * 人员识别管理 业务处理
 *
 * @author xueyi
 */
@RestController
@RequestMapping("/pass/inner-api")
public class DmRecognizedRecordsInnerApiController extends BaseApiController {

    @Autowired
    private DmStaffMapper dmStaffMapper;

    @Autowired
    private RemoteFileService fileService;

    @Autowired
    private DmRecognizedRecordsMapper dmRecognizedRecordsMapper;

    @Autowired
    private DmStaffServiceImpl dmStaffService;

    @Autowired
    ImageUtil imageUtil;

    @Autowired
    private DmResourcesServiceImpl iDmResourcesService;

    @Autowired
    private DmRecognizedRecordsConverter recordsConverter;

    @Autowired
    private FaceServiceImpl faceService;

    @Autowired
    private DmRecognizedRecordsServiceImpl recognizedRecordsService;

    @Autowired
    private ElasticsearchClient esClient;
    @InnerAuth
    @PostMapping(value = "/upload-pass")
    public JSONObject upload(@RequestBody DmRecognizedRecordsDto recognizedRecordsDto) {
        String deviceId = recognizedRecordsDto.getDevId();
        BigDecimal timestamp = recognizedRecordsDto.getTimestamp();
        Long userId = recognizedRecordsDto.getUserId();
        String imgBase64 = recognizedRecordsDto.getImgbase64();
        String sign = recognizedRecordsDto.getSign();
        Integer type = recognizedRecordsDto.getType();//1:staff;2:stranger

        MyResponse myResponse = commonCheck(deviceId, timestamp.doubleValue(), sign);
        if (myResponse.getStatus() != 0) {
            return myResponse.toJSON();
        }

        DmRecognizedRecordsPo cr = recordsConverter.mapperPo(recognizedRecordsDto);

        try {
            cr.setRecognizedTime(DateUtils.parseLongToDate(timestamp.longValue()));
        } catch (ParseException e) {
            e.printStackTrace();
            return output(ResponseCode.ILLEGAL_PARAMETER, "timestamp").toJSON();
        }
        if (!type.equals(DmRecognizedRecordsDto.TYPE_STRANGER)) {
            DmStaffPo emp = dmStaffMapper.selectById(userId);
            if (ObjectUtils.anyNotNull(emp)) {
                cr.setUserName(emp.getUserName());
                cr.setDeptId(emp.getDeptId());

                dmStaffService.updateOrInsertAttendance(cr);
            }
        }

        if (StringUtils.isNotEmpty(imgBase64)) {
            R<SysFile> fileResult = fileService.uploadFace(imageUtil.base64ToMultipartFile(imgBase64));
            if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData()))
                return output(ResponseCode.FILE_SERVICE_ERROR).toJSON();
            String url = fileResult.getData().getUrl();
            cr.setFaceUrl(url);
        }

        dmRecognizedRecordsMapper.insert(cr);
        recognizedRecordsService.saveToEs(recordsConverter.mapperDto(cr));

        recognizedRecordsService.setRedisRecognizedCount(1);

        return outputSuccess().toJSON();
    }

    @InnerAuth
    @PostMapping(value = "/upload-multi-pass")
    public JSONObject uploads(@RequestBody DmRecognizedMultiRecordsDto recognizedMultiRecordsDto) {
        String deviceId = recognizedMultiRecordsDto.getDevId();
        BigDecimal timestamp = recognizedMultiRecordsDto.getTimestamp();
        String sign = recognizedMultiRecordsDto.getSign();

        MyResponse myResponse = commonCheck(deviceId, timestamp.doubleValue(), sign);
        if (myResponse.getStatus() != 0) {
            return myResponse.toJSON();
        }

        List<DmRecognizedRecordsDto> dtoList = recognizedMultiRecordsDto.getRecords();

        List<DmRecognizedRecordsPo> crs = new ArrayList<>();
        for (DmRecognizedRecordsDto recognizedRecordsDto : dtoList) {
            Long userId = recognizedRecordsDto.getUserId();
            String imgBase64 = recognizedRecordsDto.getImgbase64();
            Integer type = recognizedRecordsDto.getType();//1:staff;2:stranger
            DmRecognizedRecordsPo cr = recordsConverter.mapperPo(recognizedRecordsDto);

            try {
                cr.setRecognizedTime(DateUtils.parseLongToDate(timestamp.longValue()));
            } catch (ParseException e) {
                e.printStackTrace();
                return output(ResponseCode.ILLEGAL_PARAMETER, "timestamp").toJSON();
            }
            if (type.equals(DmRecognizedRecordsDto.TYPE_STRANGER)) {
                DmStaffPo emp = dmStaffMapper.selectById(userId);
                if (ObjectUtils.anyNotNull(emp)) {
                    cr.setUserName(emp.getUserName());
                    cr.setDeptId(emp.getDeptId());

                    dmStaffService.updateOrInsertAttendance(cr);
                }
            }
            if (StringUtils.isNotEmpty(imgBase64)) {
                R<SysFile> fileResult = fileService.uploadFace(imageUtil.base64ToMultipartFile(imgBase64));
                if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData()))
                    return output(ResponseCode.FILE_SERVICE_ERROR).toJSON();
                String url = fileResult.getData().getUrl();
                DmResourcesDto dmResourcesDto = new DmResourcesDto();
                dmResourcesDto.setType(DmResourcesDto.TYPE_PIC);
                dmResourcesDto.setUrl(url);
                dmResourcesDto.setName("stranger");

                com.alibaba.fastjson.JSONObject json = faceService.getFaceExtraction("", "", imgBase64);

                if (0!=json.getInteger("status")) {
                    return output(-1, json.getString("errMsg")).toJSON();
                } else {
                    JSONArray obj = json.getJSONArray("result").getJSONObject(0).getJSONArray("faces").getJSONObject(0).getJSONArray("feature");
                    dmResourcesDto.setFeature(obj.toJSONString());
                }

                iDmResourcesService.addOne(dmResourcesDto);
                cr.setFaceUrl(url);
                cr.setId(IdUtil.getSnowflakeNextId());
                cr.setResourceId(dmResourcesDto.getId());
            }
//            recognizedRecordsService.saveToEs(recordsConverter.mapperDto(cr));
            crs.add(cr);
        }

        dmRecognizedRecordsMapper.insertBatch(crs);

        return outputSuccess().toJSON();
    }
}
