/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.dmAccessTraffic.service.impl;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.*;
import me.zhengjie.modules.dm.dmAttendanceRecord.domain.DmAttendanceRecord;
import me.zhengjie.modules.dm.dmAttendanceRecord.repository.DmAttendanceRecordRepository;
import me.zhengjie.modules.dmAccessTraffic.domain.DmAccessTraffic;
import me.zhengjie.modules.dmAccessTraffic.service.dto.CallbackAccessTrafficDto;
import me.zhengjie.modules.dmuser.domain.DmUser;
import me.zhengjie.modules.dmuser.service.DmUserService;
import me.zhengjie.modules.dmuser.service.mapstruct.DmUserMapper;
import me.zhengjie.modules.system.service.dto.DictDetailDto;
import me.zhengjie.modules.system.service.impl.DictDetailServiceImpl;
import me.zhengjie.utils.*;
import lombok.RequiredArgsConstructor;
import me.zhengjie.modules.dmAccessTraffic.repository.DmAccessTrafficRepository;
import me.zhengjie.modules.dmAccessTraffic.service.DmAccessTrafficService;
import me.zhengjie.modules.dmAccessTraffic.service.dto.DmAccessTrafficDto;
import me.zhengjie.modules.dmAccessTraffic.service.dto.DmAccessTrafficQueryCriteria;
import me.zhengjie.modules.dmAccessTraffic.service.mapstruct.DmAccessTrafficMapper;
import me.zhengjie.ykt.domain.DmRoomDevice;
import me.zhengjie.ykt.service.DmRoomDeviceService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author zhirong
* @date 2021-11-22
**/
@Service
@RequiredArgsConstructor
public class DmAccessTrafficServiceImpl implements DmAccessTrafficService {

    private final DmAccessTrafficRepository dmAccessTrafficRepository;
    private final DmAccessTrafficMapper dmAccessTrafficMapper;
    private final DmUserService dmUserService;
    private final DmUserMapper dmUserMapper;
    private final DmRoomDeviceService dmRoomDeviceService;
    private final DmAttendanceRecordRepository dmAttendanceRecordRepository;

    // 查询字典详情
    private final DictDetailServiceImpl dictDetailService;

    @Override
    public Map<String,Object> queryAll(DmAccessTrafficQueryCriteria criteria, Pageable pageable){
        Page<DmAccessTraffic> page = dmAccessTrafficRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(dmAccessTrafficMapper::toDto));
    }

    @Override
    public List<DmAccessTrafficDto> queryAll(DmAccessTrafficQueryCriteria criteria){
        return dmAccessTrafficMapper.toDto(dmAccessTrafficRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public DmAccessTrafficDto findById(Long id) {
        DmAccessTraffic dmAccessTraffic = dmAccessTrafficRepository.findById(id).orElseGet(DmAccessTraffic::new);
        ValidationUtil.isNull(dmAccessTraffic.getId(),"DmAccessTraffic","id",id);
        return dmAccessTrafficMapper.toDto(dmAccessTraffic);
    }

    //每天xx点执行
//    @Scheduled(cron = "0 0 2 * * ?")
//    //异步执行,指定线程池(配置类里配置)
//    @Async("threadPoolTaskExecutor1")
//    public void createAccess() throws IOException, ParseException {
//        String url = "http://xxxxx:xxxx/getHistoryRecord";
//        JSONObject generateProcJson = new JSONObject();
//        JSONObject data = new JSONObject();
//        int limit = 20;//页数
//        SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
//        SimpleDateFormat formater2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        Date start = formater2.parse(formater.format(new Date())+ " 00:00:00");
//        Date end = formater2.parse(formater.format(new Date())+ " 23:59:59");
//        System.out.println("开始时间"+start);
//        data.put("dateStart",start);
//        data.put("dateEnd",end);
//        data.put("page",1);//当前页数
//        data.put("limit",limit);
//        data.put("sort","desc");
//        generateProcJson.put("data",data);
//        String generateProcData = BeanMapUtils.sendPost(url,generateProcJson.toString());
//        JSONObject generateProcDataJson = JSONObject.parseObject(generateProcData);//第一层
//        Integer sum = generateProcDataJson.getInteger("sum");//总条数
////        JSONObject data1 = generateProcDataJson.parseObject("data");//第二层
////        JSONArray arr = data1.getJSONArray("data");//第三层集合数据
//        int totalPageNum = (sum +limit - 1) / limit;//总页数
//        for(int i = 1;i<=totalPageNum;i++){//循环总页数
//            //获取当前页数
//            data.put("page",i);//当前页数
//            generateProcJson.put("data",data);
//            String generate = BeanMapUtils.sendPost(url,generateProcJson.toString());
//            JSONObject generatePro = JSONObject.parseObject(generate);
//            JSONObject data2 = generatePro.parseObject("data");//第二层
//            JSONArray arr2 = data2.getJSONArray("data");//第三层集合数据
//            for (int j = 0;j<arr2.size();j++){//
//                JSONObject attendance = arr2.getJSONObject(j);
//                //组装返回数据
//                JSONObject acc = new JSONObject();
//                if (attendance.getString("open")=="true"){
//                    acc.put("accessTime",attendance.getString("date"));
//                    acc.put("cardNumber",attendance.getString("cardID"));
//                    acc.put("userNumber",attendance.getString("userID"));//user
//                    acc.put("roomDevice",attendance.getString("deviceID"));
//                    acc.put("accessPhoto",attendance.getString("picture"));
//                    DmAccessTraffic accessTraffic = JSON.toJavaObject(acc,DmAccessTraffic.class);
//                    create(accessTraffic);
//                }
//            }
//        }
//    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DmAccessTrafficDto create(DmAccessTraffic resources) throws IOException, ParseException {
        return dmAccessTrafficMapper.toDto(dmAccessTrafficRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(DmAccessTraffic resources) {
        DmAccessTraffic dmAccessTraffic = dmAccessTrafficRepository.findById(resources.getId()).orElseGet(DmAccessTraffic::new);
        ValidationUtil.isNull( dmAccessTraffic.getId(),"DmAccessTraffic","id",resources.getId());
        dmAccessTraffic.copy(resources);
        dmAccessTrafficRepository.save(dmAccessTraffic);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            dmAccessTrafficRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<DmAccessTrafficDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        // 查询字典内的用户类型
        List<DictDetailDto> userTypeList = dictDetailService.getDictByName("user_type");
        // 查询字典的出入状态
        List<DictDetailDto> comeGoOutList = dictDetailService.getDictByName("traffic_status");
        // 时间格式化
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        for (DmAccessTrafficDto dmAccessTraffic : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("一卡通卡号", dmAccessTraffic.getCardNumber());
            map.put("人员姓名", dmAccessTraffic.getUser().getName());
//            map.put("人员种类", dmAccessTraffic.getUser().getUsertype());
            for(DictDetailDto userType: userTypeList) {
                if(userType.getValue().equals(dmAccessTraffic.getUser().getUsertype())) {
                    map.put("人员种类", userType.getLabel());
                    break;
                }
            }
            map.put("组织机构", dmAccessTraffic.getUser().getDept().getName());
            map.put("通行时间", sdf.format(dmAccessTraffic.getAccessTime()));
//            map.put("出入", dmAccessTraffic.getComeGoOut());
            for(DictDetailDto comeGoOut: comeGoOutList) {
                if(comeGoOut.getValue().equals(dmAccessTraffic.getComeGoOut().toString())) {
                    map.put("出入", comeGoOut.getLabel());
                    break;
                }
            }
            List<DmRoomDevice> roomDevice = dmRoomDeviceService.findByCode(dmAccessTraffic.getRoomDevice(),null);
            map.put("设备名称", roomDevice.get(0).getName());
            map.put("设备位置", roomDevice.get(0).getBuildAddress());

            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public Map<String, Object> homePageYkt() {
        Map<String, Object> map = new HashMap<>();
        map.put("getCountAccess",dmAccessTrafficRepository.getCountAccess());
        map.put("getAccessGo",dmAccessTrafficRepository.getAccessGo());
        map.put("getAccessOut",dmAccessTrafficRepository.getAccessOut());
        map.put("getAccessCt",dmAccessTrafficRepository.getAccessCt());
        map.put("getAccessRl",dmAccessTrafficRepository.getAccessRl());
        map.put("getAccessQt",dmAccessTrafficRepository.getAccessQt());
        return map;
    }

    @Override
    public List<Map<String, String>> YunUserRequest() {
        return dmAccessTrafficRepository.YunUserRequest();
    }

    @Override
    public DmAccessTraffic callbackAccessTraffic(JSONObject json) {
        String userID = json.getString("userID");
        if(!ObjectUtils.isEmpty(userID) && !StringUtils.equals(userID,"陌生人")) {
            DmUser dmUser = dmUserService.findByUserNumber(json.getString("userID"));
            System.out.println("json!:" + json.toJSONString());
            DmAccessTraffic dmAccessTraffic = new DmAccessTraffic();
//        DmRoomDevice roomDevice = new DmRoomDevice();
//        roomDevice.setId(Long.valueOf(resources.getDeviceID()));
            List<DmRoomDevice> roomDevice = dmRoomDeviceService.findByCode(json.getString("deviceID"), null);
            dmAccessTraffic.setRoomDevice(roomDevice.get(0).getCode());
            dmAccessTraffic.setCardNumber(json.getString("cardID"));

            dmAccessTraffic.setUser(dmUser);
            //dmAccessTraffic.setAccessTime(new Timestamp(System.currentTimeMillis()));
            dmAccessTraffic.setAccessTime(json.getTimestamp("date"));
            DmAccessTraffic newDmAccessTraffic = dmAccessTrafficRepository.save(dmAccessTraffic);
            if(!ObjectUtils.isEmpty(dmUser)) {
                if (StringUtils.equals(dmUser.getUsertype(), "00")) {
                    String erpAttendanceApi = "http://10.22.2.66:8700/attendance-api/device/identify/callback";
                    //组装返回数据
                    JSONObject ertAttendanceJSON = new JSONObject();
                    ertAttendanceJSON.put("deviceKey", newDmAccessTraffic.getRoomDevice());
                    ertAttendanceJSON.put("personId", newDmAccessTraffic.getUser().getUserNumber());
                    //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    ertAttendanceJSON.put("time", newDmAccessTraffic.getAccessTime());
                    ertAttendanceJSON.put("type", "face_0");
                    System.out.println("ertAttendanceJSON:" + ertAttendanceJSON);
                    //ertAttendanceJSON.put("path",list.get("access_photo"));
                    String res = HttpRequest.get(erpAttendanceApi).body(ertAttendanceJSON.toJSONString()).execute().body();
                    System.out.println("res:" + res);
                } else if (StringUtils.equals(dmUser.getUsertype(), "01")) {
                    List<DmAttendanceRecord> dmAttendanceRecords = dmAttendanceRecordRepository.findByUserNumber(dmUser.getId());
                    if (ObjectUtils.isEmpty(dmAttendanceRecords) || dmAttendanceRecords.size() < 2) {
                        DmAttendanceRecord dmAttendanceRecord = new DmAttendanceRecord();
                        dmAttendanceRecord.setDmUser(dmUser);
                        dmAttendanceRecord.setCardNumber(dmUser.getCardId());
                        dmAttendanceRecord.setRoomDevice(roomDevice.get(0).getCode());
                        dmAttendanceRecord.setAttendanceTime(json.getTimestamp("date"));
                        dmAttendanceRecord.setOpen(json.getBoolean("open"));
                        if (json.getBoolean("open")) {
                            dmAttendanceRecordRepository.save(dmAttendanceRecord);
                        }
                    } else if (dmAttendanceRecords.size() >= 2) {
                        DmAttendanceRecord dmAttendanceRecord = new DmAttendanceRecord();
                        dmAttendanceRecord.setId(dmAttendanceRecords.get(0).getId());
                        dmAttendanceRecord.setDmUser(dmUser);
                        dmAttendanceRecord.setCardNumber(dmUser.getCardId());
                        dmAttendanceRecord.setRoomDevice(roomDevice.get(0).getCode());
                        dmAttendanceRecord.setAttendanceTime(json.getTimestamp("date"));
                        dmAttendanceRecord.setOpen(json.getBoolean("open"));
                        if (json.getBoolean("open")) {
                            dmAttendanceRecordRepository.save(dmAttendanceRecord);
                        }
                    }
                }
            }
        }
        return null;
    }

    @Override
    public List<Map<String, String>> queryByAccessTime(String start, String end) {
        return dmAccessTrafficRepository.queryByAccessTime(start,end);
    }

    @Override
    public List<Map<String, String>> queryByRoomDevice(String userNumber, String roomDevice, String accessTime) {
        return dmAccessTrafficRepository.queryByRoomDevice(userNumber,roomDevice,accessTime);
    }
}