/*
 *  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.quartz.task;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.dmuser.domain.DmUser;
import me.zhengjie.modules.dmuser.repository.DmUserRepository;
import me.zhengjie.modules.system.domain.Dept;
import me.zhengjie.modules.system.domain.Job;
import me.zhengjie.modules.system.domain.Role;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.modules.system.repository.DeptRepository;
import me.zhengjie.modules.system.repository.UserRepository;
import me.zhengjie.modules.system.service.DeptService;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.utils.BeanMapUtils;
import me.zhengjie.utils.SecurityUtils;
import me.zhengjie.utils.StringUtils;
import me.zhengjie.ykt.domain.DmRoomDevice;
import me.zhengjie.ykt.service.DmPlateNumberService;
import me.zhengjie.ykt.service.DmRoomDeviceService;
import me.zhengjie.ykt.service.dto.DmPlateNumberDto;
import me.zhengjie.ykt.service.dto.DmPlateNumberQueryCriteria;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

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

/**
 * ERP 数据同步
 * @author Sky
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class ZkDataSyncTask {

    @Value("${key}")
    private String key;
    @Value("${zkApiUrl}")
    private String zkApiUrl;
    @Value("${headerKey}")
    private String header_key;
    @Value("${deptApi}")
    private String deptApi;
    @Value("${userApi}")
    private String userApi;
    @Value("${deviceInfo}")
    private String deviceInfo;
    @Value("${synchronizationDeviceUrl}")
    private String synchronizationDeviceUrl;
    @Value("${yueUrl}")
    private String yueUrl;

    private final UserRepository userRepository;
    private final DmUserRepository dmUserRepository;
    private final DeptRepository deptRepository;
    private final PasswordEncoder passwordEncoder;
    private final DmAccessTrafficRepository dmAccessTrafficRepository;
    private final UserService userService;
    private final DmRoomDeviceService dmRoomDeviceService;
    private final DmPlateNumberService dmPlateNumberService;

    public void run(){
        log.info("deptsync 执行开始");
        deptSync();
        log.info("deptsync 执行结束");

        log.info("usersync 执行开始");
        userSync();
        log.info("usersync 执行结束");
    }

    public void runDept(){
        log.info("deptsync 执行开始");
        deptSyncAll();
        log.info("deptsync 执行结束");
    }

    public void runUser(){
        log.info("usersync 执行开始");
        userSyncAll();
        log.info("usersync 执行结束");
    }

    public void runAccess(){
        log.info("access 执行开始");
        pushAttendanceData();
        log.info("access 执行结束");
    }

    private void pushAttendanceData(){
        String erpAttendanceApi = "http://10.22.2.65:16000/attendance-api/device/identify/callback";
        List<Map<String,Object>> map = dmAccessTrafficRepository.accessTrf();
        for(int i = 0;i<map.size();i++){
            Map<String,Object> list = map.get(i);
            //组装返回数据
            JSONObject ertAttendanceJSON = new JSONObject();
            ertAttendanceJSON.put("deviceKey",list.get("room_device"));
            ertAttendanceJSON.put("personId",list.get("user_number"));
            ertAttendanceJSON.put("time",list.get("access_time"));
            ertAttendanceJSON.put("type","face_0");
            ertAttendanceJSON.put("path",list.get("access_photo"));
            HttpRequest.get(erpAttendanceApi).body(ertAttendanceJSON.toJSONString()).execute().body();
        }
    }

    private JSONObject getDatas(String api,JSONArray time, int pageNum, int pageSize,int type) {
        Map<String,Object> tokenData = SecurityUtils.getToken(key);
        JSONObject body = new JSONObject();
        body.put("timestamp",tokenData.get("timestamp"));
        body.put("nonce",tokenData.get("nonce"));
        JSONObject query = new JSONObject();
        if(type == 1){
            query.put("updateTime",time);
        }
        body.put("query",query);

        String res = HttpRequest.get(zkApiUrl + api+"?page="+pageNum+"&size="+pageSize)
                .header(header_key, tokenData.get("token").toString())
                .body(body.toString()).execute().body();
        JSONObject json = JSONObject.parseObject(res);
        log.info("json:"+json);
        return json;
    }

    /**
     * 部门数据同步
     */
    private void deptSync() {
//        String api = "/api/thirdparty/v1/user/getzkdeps";

        JSONArray createTme = new JSONArray();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,-24);
        String yesterdayDate = dateFormat.format(calendar.getTime());

        String todayDate = dateFormat.format(new Date());

        createTme.add(yesterdayDate);
        createTme.add(todayDate);

        //计算总页数
        int total = getDatas(deptApi,createTme,0,100,1).getJSONObject("data").getInteger("totalElements");
        int pageSize = 100;
        int pageTotal = (total / pageSize);
        if (total % pageSize != 0) {
            pageTotal++;
        }
        log.info("pageTotal:"+pageTotal);

        //按页获取
        for (int k = 0; k < pageTotal; k++) {
            JSONObject json = getDatas(deptApi, createTme,k,pageSize,1);
            JSONObject data = json.getJSONObject("data");
            JSONArray content = data.getJSONArray("content");
            for (int i = 0; i < content.size(); i++) {
                Dept dept = JSONObject.parseObject(content.getString(i), Dept.class);
                deptRepository.save(dept);
            }
        }
    }

    /**
     * 部门数据同步(全量)
     */
    private void deptSyncAll() {
//        String api = "/api/thirdparty/v1/user/getzkdeps";

        //计算总页数
        int total = getDatas(deptApi,null,0,100,2).getJSONObject("data").getInteger("totalElements");
        int pageSize = 100;
        int pageTotal = (total / pageSize);
        if (total % pageSize != 0) {
            pageTotal++;
        }
        log.info("pageTotal:"+pageTotal);

        //按页获取
        for (int k = 0; k < pageTotal; k++) {
            JSONObject json = getDatas(deptApi,null,k,pageSize,2);
            JSONObject data = json.getJSONObject("data");
            JSONArray content = data.getJSONArray("content");
            for (int i = 0; i < content.size(); i++) {
                Dept dept = JSONObject.parseObject(content.getString(i), Dept.class);
                deptRepository.save(dept);
            }
        }
    }

    /**
     * 人员数据同步
     */
    private void userSync() {
//        String api = "/api/thirdparty/v1/user/getZkSysUsers";

        JSONArray createTme = new JSONArray();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,-24);
        String yesterdayDate = dateFormat.format(calendar.getTime());

        String todayDate = dateFormat.format(new Date());

        createTme.add(yesterdayDate);
        createTme.add(todayDate);

        //计算总页数
        int total = getDatas(userApi,createTme,0,1,1).getJSONObject("data").getInteger("totalElements");
        int pageSize = 10;
        int pageTotal = (total / pageSize);
        if (total % pageSize != 0) {
            pageTotal++;
        }
        log.info("pageTotal:"+pageTotal);

        //按页获取
        for (int k = 0; k <= pageTotal; k++) {
            JSONObject json = getDatas(userApi, createTme,k,pageSize,1);
            JSONObject data = json.getJSONObject("data");
            JSONArray content = data.getJSONArray("content");
            for (int i = 0; i < content.size(); i++) {
                User user = new User();
                JSONObject userData = content.getJSONObject(i);

                user.setId(userData.getString("id"));
                if(userData.containsKey("username")) {
                    user.setUsername(userData.getString("username"));
                }
                user.setPassword(userData.getString("password"));
                user.setOrgPassword("12345678");
                if(userData.containsKey("jobs")) {
                    Set<Job> jobs = new HashSet<>(JSONArray.parseArray(userData.getString("jobs"), Job.class));
                    user.setJobs(jobs);
                }
                if(userData.containsKey("roles")) {
                    Set<Role> roles = new HashSet<>(JSONArray.parseArray(userData.getString("roles"), Role.class));
                    user.setRoles(roles);
                }
                if(userData.containsKey("gender")) {
                    user.setGender(userData.getString("gender"));
                }

                if(userData.containsKey("dept")) {
                    user.setDept(JSONObject.parseObject(userData.getString("dept"), Dept.class));
                }

                if(userData.containsKey("email")) {
                    user.setEmail(userData.getString("email"));
                }

                if(userData.containsKey("nickName")) {
                    user.setNickName(userData.getString("nickName"));
                }

                if(userData.containsKey("phone")) {
                    user.setPhone(userData.getString("phone"));
                }

                if(userData.containsKey("enabled")) {
                    user.setEnabled(userData.getBoolean("enabled"));
                }

                if(userData.containsKey("userRootGroupId")) {
                    user.setUserRootGroupId(userData.getString("userRootGroupId"));
                }
                if(userData.containsKey("userRootGroupName")) {
                    user.setUserRootGroupName(userData.getString("userRootGroupName"));
                }

                DmUser dmUser = new DmUser();
                dmUser.setDept(user.getDept());
                dmUser.setId(user.getId());
                dmUser.setEmail(user.getEmail());
                dmUser.setContacts(user.getPhone());
                dmUser.setName(user.getNickName());
                dmUser.setSex(user.getGender());
                dmUser.setEnabled(user.getEnabled()?"2":"1");
                if(!ObjectUtils.isEmpty(userData.getJSONObject("dmUser"))){
                    JSONObject dmUserObject = userData.getJSONObject("dmUser");
                    if(dmUserObject.containsKey("cardid")) {
                        dmUser.setCardId(dmUserObject.getString("cardid"));
                    }
                    if(dmUserObject.containsKey("userNumber")) {
                        dmUser.setUserNumber(dmUserObject.getString("userNumber"));
                    }
                    if(dmUserObject.containsKey("type")) {
                        dmUser.setUsertype(dmUserObject.getString("type"));
                    }
                    if(dmUserObject.containsKey("faceid")) {
                        dmUser.setPicture(dmUserObject.getString("faceid"));
                    }
                }
                //判断是否是新离职的员工，如果是则修改门禁和停车权限
//                if(!user.getEnabled()){
//                    UserDto userDto = userService.findById(user.getId());
//                    if(!ObjectUtils.isEmpty(userDto)){
//                        if(userDto.getEnabled()){
//                            //删除门禁一楼进入设备权限
//                            JSONArray deviceInfoArray = new JSONArray();
//                            List<String> deviceList = Arrays.asList(deviceInfo.split(","));
//                            for(String device : deviceList){
//                                log.info("device:"+device);
//                                DmRoomDevice dmRoomDevice = dmRoomDeviceService.findByCode(device).get(0);
//                                if(!ObjectUtils.isEmpty(dmRoomDevice)){
//                                    JSONObject object = new JSONObject();
//                                    object.put("serialNumber",dmRoomDevice.getCode());
//                                    object.put("doorID",dmRoomDevice.getDoorID());
//                                    object.put("deviceType",dmRoomDevice.getDeviceType());
//                                    deviceInfoArray.add(object);
//                                }
//                            }
//                            JSONObject device = new JSONObject();
//                            device.put("userId",dmUser.getUserNumber());
//                            device.put("operateType","2");
//                            device.put("deviceInfo",deviceInfoArray);
//                            log.info("device:"+device.toJSONString());
//                            String msg = HttpRequest.post(synchronizationDeviceUrl).form("device", device.toJSONString()).execute().body();
//                            log.info("msg:"+msg);
//
//                            DmPlateNumberQueryCriteria dmPlateNumberQueryCriteria = new DmPlateNumberQueryCriteria();
//                            dmPlateNumberQueryCriteria.setUserNumber(dmUser.getId());
//                            List<DmPlateNumberDto> dmPlateNumberDtoList = dmPlateNumberService.queryAll(dmPlateNumberQueryCriteria);
//                            if(!ObjectUtils.isEmpty(dmPlateNumberDtoList)){
//                                for(DmPlateNumberDto dmPlateNumberDto : dmPlateNumberDtoList){
//                                    dmPlateNumberService.deleteYuePlate(dmPlateNumberDto.getPlateNumber());
//
//                                    JSONObject generateProcJson = new JSONObject();
//                                    generateProcJson.put("name",dmPlateNumberDto.getUserNumber().getName());
//                                    generateProcJson.put("phone",dmPlateNumberDto.getUserNumber().getContacts());
//                                    generateProcJson.put("carplate",dmPlateNumberDto.getPlateNumber());
//                                    SimpleDateFormat formater2 = new SimpleDateFormat("yyyy-MM-dd");
//                                    generateProcJson.put("startdate",formater2.format(dmPlateNumberDto.getStartTime()));
//                                    generateProcJson.put("enddate",formater2.format(dmPlateNumberDto.getEndTime()));
//                                    generateProcJson.put("cardtype","A");
//                                    generateProcJson.put("controllers", "3,4");
//                                    String generateProcData = BeanMapUtils.doPostForm(yueUrl,generateProcJson);
//                                    JSONObject generateProcDataJson = JSONObject.parseObject(generateProcData);
//                                    System.out.println("generateProcJson"+generateProcJson);
//                                    System.out.println("generateProcDataJson:"+generateProcDataJson);
//                                }
//                            }
//
//                        }
//                    }
//                }
                DmUser newDmUser = dmUserRepository.save(dmUser);
                user.setDmUser(newDmUser);
                userRepository.save(user);
            }
        }
    }


    /**
     * 人员数据同步（全量）
     */
    private void userSyncAll() {

//        String api = "/api/thirdparty/v1/user/getZkSysUsers";

        //计算总页数
        int total = getDatas(userApi,null,0,1,2).getJSONObject("data").getInteger("totalElements");
        int pageSize = 10;
        int pageTotal = (total / pageSize);
        if (total % pageSize != 0) {
            pageTotal++;
        }
        log.info("pageTotal:"+pageTotal);

        //按页获取
        for (int k = 0; k <= pageTotal; k++) {
            JSONObject json = getDatas(userApi, null,k,pageSize,1);
            JSONObject data = json.getJSONObject("data");
            JSONArray content = data.getJSONArray("content");
            for (int i = 0; i < content.size(); i++) {
                User user = new User();
                JSONObject userData = content.getJSONObject(i);

                user.setId(userData.getString("id"));
                if(userData.containsKey("username")) {
                    user.setUsername(userData.getString("username"));
                }
                user.setPassword(userData.getString("password"));
                user.setOrgPassword("12345678");
                if(userData.containsKey("jobs")) {
                    Set<Job> jobs = new HashSet<>(JSONArray.parseArray(userData.getString("jobs"), Job.class));
                    user.setJobs(jobs);
                }
                if(userData.containsKey("roles")) {
                    Set<Role> roles = new HashSet<>(JSONArray.parseArray(userData.getString("roles"), Role.class));
                    user.setRoles(roles);
                }
                if(userData.containsKey("gender")) {
                    user.setGender(userData.getString("gender"));
                }

                if(userData.containsKey("dept")) {
                    user.setDept(JSONObject.parseObject(userData.getString("dept"), Dept.class));
                }

                if(userData.containsKey("email")) {
                    user.setEmail(userData.getString("email"));
                }

                if(userData.containsKey("nickName")) {
                    user.setNickName(userData.getString("nickName"));
                }

                if(userData.containsKey("phone")) {
                    user.setPhone(userData.getString("phone"));
                }

                if(userData.containsKey("enabled")) {
                    user.setEnabled(userData.getBoolean("enabled"));
                }

                if(userData.containsKey("userRootGroupId")) {
                    user.setUserRootGroupId(userData.getString("userRootGroupId"));
                }
                if(userData.containsKey("userRootGroupName")) {
                    user.setUserRootGroupName(userData.getString("userRootGroupName"));
                }

                DmUser dmUser = new DmUser();
                dmUser.setDept(user.getDept());
                dmUser.setId(user.getId());
                dmUser.setEmail(user.getEmail());
                dmUser.setContacts(user.getPhone());
                dmUser.setName(user.getNickName());
                dmUser.setSex(user.getGender());
                dmUser.setEnabled(user.getEnabled()?"1":"2");
                if(!ObjectUtils.isEmpty(userData.getJSONObject("dmUser"))){
                    JSONObject dmUserObject = userData.getJSONObject("dmUser");
                    if(dmUserObject.containsKey("cardid")) {
                        dmUser.setCardId(dmUserObject.getString("cardid"));
                    }
                    if(dmUserObject.containsKey("userNumber")) {
                        dmUser.setUserNumber(dmUserObject.getString("userNumber"));
                    }
                    if(dmUserObject.containsKey("type")) {
                        dmUser.setUsertype(dmUserObject.getString("type"));
                    }
                    if(dmUserObject.containsKey("faceid")) {
                        dmUser.setPicture(dmUserObject.getString("faceid"));
                    }
                }
                //判断是否是新离职的员工，如果是则修改门禁和停车权限
//                if(!user.getEnabled()){
//                    UserDto userDto = userService.findById(user.getId());
//                    if(!ObjectUtils.isEmpty(userDto)){
//                        if(userDto.getEnabled()){
//                            //删除门禁一楼进入设备权限
//                            JSONArray deviceInfoArray = new JSONArray();
//                            List<String> deviceList = Arrays.asList(deviceInfo.split(","));
//                            for(String device : deviceList){
//                                log.info("device:"+device);
//                                DmRoomDevice dmRoomDevice = dmRoomDeviceService.findByCode(device).get(0);
//                                if(!ObjectUtils.isEmpty(dmRoomDevice)){
//                                    JSONObject object = new JSONObject();
//                                    object.put("serialNumber",dmRoomDevice.getCode());
//                                    object.put("doorID",dmRoomDevice.getDoorID());
//                                    object.put("deviceType",dmRoomDevice.getDeviceType());
//                                    deviceInfoArray.add(object);
//                                }
//                            }
//                            JSONObject device = new JSONObject();
//                            device.put("userId",dmUser.getUserNumber());
//                            device.put("operateType","2");
//                            device.put("deviceInfo",deviceInfoArray);
//                            log.info("device:"+device.toJSONString());
//                            String msg = HttpRequest.post(synchronizationDeviceUrl).form("device", device.toJSONString()).execute().body();
//                            log.info("msg:"+msg);
//
//                            DmPlateNumberQueryCriteria dmPlateNumberQueryCriteria = new DmPlateNumberQueryCriteria();
//                            dmPlateNumberQueryCriteria.setUserNumber(dmUser.getId());
//                            List<DmPlateNumberDto> dmPlateNumberDtoList = dmPlateNumberService.queryAll(dmPlateNumberQueryCriteria);
//                            if(!ObjectUtils.isEmpty(dmPlateNumberDtoList)){
//                                for(DmPlateNumberDto dmPlateNumberDto : dmPlateNumberDtoList){
//                                    dmPlateNumberService.deleteYuePlate(dmPlateNumberDto.getPlateNumber());
//
//                                    JSONObject generateProcJson = new JSONObject();
//                                    generateProcJson.put("name",dmPlateNumberDto.getUserNumber().getName());
//                                    generateProcJson.put("phone",dmPlateNumberDto.getUserNumber().getContacts());
//                                    generateProcJson.put("carplate",dmPlateNumberDto.getPlateNumber());
//                                    SimpleDateFormat formater2 = new SimpleDateFormat("yyyy-MM-dd");
//                                    generateProcJson.put("startdate",formater2.format(dmPlateNumberDto.getStartTime()));
//                                    generateProcJson.put("enddate",formater2.format(dmPlateNumberDto.getEndTime()));
//                                    generateProcJson.put("cardtype","A");
//                                    generateProcJson.put("controllers", "3,4");
//                                    String generateProcData = BeanMapUtils.doPostForm(yueUrl,generateProcJson);
//                                    JSONObject generateProcDataJson = JSONObject.parseObject(generateProcData);
//                                    System.out.println("generateProcJson"+generateProcJson);
//                                    System.out.println("generateProcDataJson:"+generateProcDataJson);
//                                }
//                            }
//
//                        }
//                    }
//                }
                DmUser newDmUser = dmUserRepository.save(dmUser);
                user.setDmUser(newDmUser);
                userRepository.save(user);
            }
        }
    }
}