package com.ics.admin.controller.meeting;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ics.admin.domain.BuildingDetail;
import com.ics.admin.domain.Customer;
import com.ics.admin.domain.Room;
import com.ics.admin.domain.meeting.*;
import com.ics.admin.service.IBuildingDetailService;
import com.ics.admin.service.ICustomerService;
import com.ics.admin.service.IIcsCustomerStaffService;
import com.ics.admin.service.IRoomService;
import com.ics.admin.service.meeting.*;
import com.ics.common.core.domain.IcsCustomerStaff;
import com.ics.common.core.domain.dto.DevicePersonDto;
import com.ics.common.core.domain.dto.FacesDto;
import com.ics.common.utils.DeviceUtils;
import com.ics.common.utils.IpUtils;
import com.ics.common.utils.UrlToBase64Util;
import com.ics.system.domain.User;
import com.ics.system.service.ICurrentUserService;
import com.ics.system.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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 com.ics.common.core.domain.R;
import com.ics.common.core.controller.BaseController;
import org.wf.jwtp.annotation.Ignore;
import org.wf.jwtp.annotation.RequiresPermissions;
import org.wf.jwtp.util.SubjectUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * 设备 提供者
 *
 * @author chen
 * @date 2024-02-25
 */
@Slf4j
@RestController
@RequestMapping("/meeting/equipment")
public class EquipmentController extends BaseController {

    @Autowired
    private IEquipmentService equipmentService;

    @Autowired
    private IRoomEquipmentService roomEquipmentService;

    @Autowired
    private IBuildingDetailService buildingDetailService;

    @Autowired
    private IRoomService roomService;

    @Autowired
    private IRoomRecordService roomRecordService;

    @Autowired
    private IIcsCustomerStaffService staffService;

    @Autowired
    private ICustomerService customerService;

    @Autowired
    private IUserEquipmentService userEquipmentService;

    @Autowired
    private IDetailEquipmentService detailEquipmentService;

    @Autowired
    private IRoomContentService roomContentService;

    @Autowired
    private IReservationService reservationService;

    @Autowired
    private IReservationPersonService reservationPersonService;

    @Autowired
    private ICurrentUserService currentUserService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IStaffCustomerService staffCustomerService;

    private static final String BASE64_PREFIX = "data:image/png;base64,";


    /**
     * app的密钥值
     */
    @Value("${dfs.path}")
    private String path;

    @Value("${dfs.domain}")
    private String url;

    /**
     * 查询设备
     */
    @Ignore
    @GetMapping("get/{id}")
    public Equipment get(@PathVariable("id") Long id) {
        Equipment equipment = equipmentService.selectEquipmentById(id);
        RoomEquipment roomEquipment = roomEquipmentService.selectByEquipmentId(equipment.getId());
        Room room = roomService.selectRoomById(roomEquipment.getRoomId());
        equipment.setBuildId(room.getBuildingId());
        equipment.setRoomName(room.getName());
        BuildingDetail buildingDetail = buildingDetailService.selectBuildingDetailById(room.getBuildingDetailId());
        equipment.setBuildName(buildingDetail.getFloorName());
        return equipment;
    }

    /**
     * 查询设备列表
     */
    @RequiresPermissions("meeting:equipment:list")
    @GetMapping("list")
    public R list(Equipment equipment) {
        startPage();
        boolean isAdmin = SubjectUtil.hasRole(getRequest(),"manager");
        if (isAdmin){
            Long parkId = currentUserService.getParkId();
            Long tenantId = currentUserService.getTenantId();
            equipment.setParkId(parkId);
//            equipment.setTenantId(tenantId);
        }
        boolean b = SubjectUtil.hasRole(getRequest(),"admin");
        if (b){
            User user = userService.selectUserById(getCurrentUserId());
            if (null != user.getCustomerId()){
                //todo 查询房间id
                Customer customer = customerService.selectCustomerById(user.getCustomerId());
                if (customer !=null){
                    String roomId = customer.getRoomId();
                    List<String> roomIds = StrUtil.split(roomId, ',');
                    List<Long> collect = roomIds.stream().map(Long::valueOf).collect(Collectors.toList());
                    equipment.setRoomIds(collect);
                }
            }
        }
        List<Equipment> equipment1 = equipmentService.selectEquipmentList(equipment);
        for (Equipment equipment2 : equipment1) {
            RoomEquipment roomEquipment = roomEquipmentService.selectByEquipmentId(equipment2.getId());
            if (roomEquipment != null) {
                Room room = roomService.selectRoomById(roomEquipment.getRoomId());
                if (room !=null){
                    equipment2.setRoomId(room.getId());
                    equipment2.setBuildId(room.getBuildingDetailId());
                    equipment2.setRoomName(room.getName());
                    BuildingDetail buildingDetail = buildingDetailService.selectBuildingDetailById(room.getBuildingDetailId());
                    if (buildingDetail != null) {
                        equipment2.setBuildName(buildingDetail.getFloorName());
                    }
                }

            }else {
                DetailEquipment detailEquipment = detailEquipmentService.selectByEquipmentId(equipment2.getId());
                if (detailEquipment != null) {
                    equipment2.setBuildId(detailEquipment.getBuildingDetailId());
                    BuildingDetail buildingDetail = buildingDetailService.selectBuildingDetailById(detailEquipment.getBuildingDetailId());
                    if (buildingDetail != null) {
                        equipment2.setBuildName(buildingDetail.getFloorName());
                    }
                }

            }
            UserEquipment userEquipment = new UserEquipment();
            userEquipment.setEquipmentId(equipment2.getId());
            List<UserEquipment> equipments = userEquipmentService.selectUserEquipmentNumByUserId(userEquipment);
            equipment2.setPersonCount(equipments.size());
        }
        return result(equipment1);
    }


    /**
     * 新增保存设备
     */
    @RequiresPermissions("meeting:equipment:add")
    @PostMapping("save")
    public R addSave(@RequestBody Equipment equipment) throws Exception {
        int i = equipmentService.insertEquipment(equipment);
        Assert.isTrue(i > 0, "添加失败");

        boolean ipv4 = Validator.isIpv4(equipment.getIp());
        Assert.isTrue(ipv4, "IP不合法");


        boolean ping = DeviceUtils.ping(equipment.getIp());
        log.info("设备IP:{} 是否ping通:{}", equipment.getIp(), ping);
        if (ping){
            equipment.setEquipmentNum(String.valueOf((new Date()).getTime()));

            String s = DeviceUtils.setDeviceInfo(equipment.getEquipmentNum(), equipment.getEquipmentName(), equipment.getIp());
            JSONObject jsonObject = JSONUtil.parseObj(s);
            Integer status = (Integer) jsonObject.get("status");
            Assert.isTrue(status == 0, "未找到对应设备");
        }else {
            return R.error("设备IP: " + equipment.getIp() + " 无法ping通");
        }

        if (equipment.getRoomId() != null) {
            RoomEquipment roomEquipment = new RoomEquipment();
            roomEquipment.setEquipmentId(equipment.getId());
            roomEquipment.setRoomId(equipment.getRoomId());
            int i1 = roomEquipmentService.insertRoomEquipment(roomEquipment);
            Assert.isTrue(i1 > 0, "添加失败");
            //给用户添加权限,先去查询 这个房间是否已经绑定企业
            Room room = roomService.selectRoomById(equipment.getRoomId());
            addPersonDeviceByCustomer(room,equipment.getId());
            addPersonDeviceByRoomContent(room,equipment.getId());
        } else {

            DetailEquipment detailEquipment = new DetailEquipment();
            detailEquipment.setEquipmentId(equipment.getId());
            detailEquipment.setBuildingDetailId(equipment.getBuildId());
            int i1 = detailEquipmentService.insertDetailEquipment(detailEquipment);
            Assert.isTrue(i1 > 0, "添加失败");
            //查询所有的房间
            List<Room> rooms = roomService.selectRoomByBuildId(equipment.getBuildId());
            for (Room room : rooms) {
                addPersonDeviceByCustomer(room,equipment.getId());
                addPersonDeviceByRoomContent(room,equipment.getId());
            }
        }
        return toAjax(i);
    }

    /**
     * 修改保存设备
     */
    @RequiresPermissions("meeting:equipment:edit")
    @PostMapping("update")
    public R editSave(@RequestBody Equipment equipment) {

        if (equipment.getRoomId() != null) {
            RoomEquipment roomEquipment = new RoomEquipment();
            roomEquipment.setEquipmentId(equipment.getId());
            roomEquipment.setRoomId(equipment.getRoomId());

            Equipment equipment1 = equipmentService.selectEquipmentById(equipment.getId());
            if (!ObjectUtil.equals(equipment1.getRoomId(),equipment.getRoomId())  ) {
                Room room = roomService.selectRoomById(equipment.getRoomId());
                addPersonDeviceByCustomer(room,equipment.getId());
                addPersonDeviceByRoomContent(room,equipment.getId());
            }
            RoomEquipment roomEquipment1 = roomEquipmentService.selectByEquipmentId(equipment.getId());
            if (null != roomEquipment1) {
                roomEquipment1.setRoomId(equipment.getRoomId());
                int i1 = roomEquipmentService.updateRoomEquipment(roomEquipment1);
                Assert.isTrue(i1 > 0, "修改失败");
            }else {
                int i1 = roomEquipmentService.insertRoomEquipment(roomEquipment);
                Assert.isTrue(i1 > 0, "修改失败");
            }
        } else {

            //查询之前是否有房间，删除之前的房间

            RoomEquipment roomEquipment = roomEquipmentService.selectByEquipmentId(equipment.getId());
            if (roomEquipment != null) {
                int i1 = roomEquipmentService.deleteRoomEquipment(roomEquipment.getEquipmentId());
                log.info("删除房间设备关系", i1);
            }

            Equipment equipment1 = equipmentService.selectEquipmentById(equipment.getId());
            if (!ObjectUtil.equals(equipment1.getBuildId(),equipment.getBuildId())) {
                List<Room> rooms = roomService.selectRoomByBuildId(equipment.getBuildId());
                for (Room room : rooms) {
                    addPersonDeviceByCustomer(room,equipment.getId());
                    addPersonDeviceByRoomContent(room,equipment.getId());
                }
            }
            DetailEquipment detailEquipment = new DetailEquipment();
            detailEquipment.setEquipmentId(equipment.getId());
            detailEquipment.setBuildingDetailId(equipment.getBuildId());
            DetailEquipment detailEquipment1 = detailEquipmentService.selectByEquipmentId(equipment.getId());
            if (null == detailEquipment1) {
                int i1 = detailEquipmentService.insertDetailEquipment(detailEquipment);
                Assert.isTrue(i1 > 0, "修改失败");
            }else {
                detailEquipment1.setBuildingDetailId(equipment.getBuildId());
                int i1 = detailEquipmentService.updateDetailEquipment(detailEquipment1);
            }

        }

        return toAjax(equipmentService.updateEquipment(equipment));
    }


    //根据企业id新增用户设备
    public void addPersonDeviceByCustomer(Room room,Long deviceId) {
        if (room != null) {
            List<Customer> customer = customerService.selectByRoomId(room.getId(),room.getParkId());
            if (CollUtil.isNotEmpty(customer)) {
                for (Customer customer1 : customer) {
                    List<IcsCustomerStaff> icsCustomerStaffs = staffService.selectUserByCustomer(customer1.getId());
                    if (CollUtil.isNotEmpty(icsCustomerStaffs)) {
                        List<Long> ids = icsCustomerStaffs.stream().map(item -> {
                            return item.getId();
                        }).collect(Collectors.toList());
                        for (Long id : ids) {
                            UserEquipment userEquipment = new UserEquipment();
                            userEquipment.setEquipmentId(deviceId);
                            userEquipment.setUserId(id);
                            userEquipment.setStartTime(customer1.getStartDate());
                            userEquipment.setEndDate(customer1.getEndDate());
                            userEquipmentService.insertUserEquipment(userEquipment);
                        }
                    }
                }

            }
        }
    }
    //根据会议室新增用户设备
    public void addPersonDeviceByRoomContent(Room room,Long deviceId){
        //先查出会议室的房间号
        RoomContent roomContent = roomContentService.selectByRoomId(room.getId());
        if (roomContent != null){
            //查询会议室的预约情况
            List<Reservation> reservations =reservationService.selectByRoomContent(roomContent);
            if (CollUtil.isNotEmpty(reservations)){
                for (Reservation reservation : reservations) {
                    List<ReservationPerson> reservations1 = reservationPersonService.selectListByReservationId(reservation.getId());
                    for (ReservationPerson reservationPerson : reservations1) {
                        UserEquipment userEquipment = new UserEquipment();
                        userEquipment.setEquipmentId(deviceId);
                        userEquipment.setUserId(reservationPerson.getUserId());
                        userEquipment.setStartTime(reservation.getStartTime());
                        userEquipment.setEndDate(reservation.getEndDate());
                        userEquipmentService.insertUserEquipment(userEquipment);

                        UserEquipment userEquipment1 = new UserEquipment();
                        userEquipment1.setEquipmentId(deviceId);
                        userEquipment1.setUserId(reservationPerson.getParticipantId());
                        userEquipment1.setStartTime(reservation.getStartTime());
                        userEquipment1.setEndDate(reservation.getEndDate());
                        userEquipmentService.insertUserEquipment(userEquipment1);
                    }
                }
            }
        }
    }


    /**
     * 删除设备
     */
    @RequiresPermissions("meeting:equipment:remove")
    @PostMapping("remove")
    public R remove(String ids) {
        int i = equipmentService.deleteEquipmentByIds(ids);
        List<String> deviceIds = StrUtil.split(ids, ',');
        for (String deviceId : deviceIds) {
            int i1 = userEquipmentService.deleteUserEquipmentByEquipmentId(Long.parseLong(deviceId));
            log.info("删除用户绑定设备成功"+i1);
            int i2 = roomEquipmentService.deleteRoomEquipment(Long.parseLong(deviceId));
            log.info("删除房间绑定设备成功"+i2);
            int i3 = detailEquipmentService.deleteDetailEquipment(Long.parseLong(deviceId));
            log.info("删除楼层绑定设备成功"+i3);
        }

        return toAjax(i);
    }


    /**
     * 查询设备开门记录
     */
    @Ignore
    @GetMapping("recordByDeviceId/{id}")
    public R recordByDeviceId(@PathVariable("id") Long id) {
        RoomRecord record = new RoomRecord();
        record.setDeviceId(id);
        List<RoomRecord> roomRecords = roomRecordService.selectRoomRecordList(record);
        for (RoomRecord roomRecord : roomRecords) {
            IcsCustomerStaff customerStaff = staffService.selectIcsCustomerStaffById(roomRecord.getUserId());
            if (null != customerStaff) {
                roomRecord.setUserName(customerStaff.getUsername());
            }
            if (roomRecord.getType().equals("0")) {
                roomRecord.setType("远程开门");
            } else if (roomRecord.getType().equals("1")){
                roomRecord.setType("人脸开门");
            } else {
                roomRecord.setType("二维码开门");
            }
        }
        return R.data(roomRecords);
    }

    /**
     * 获取所有的用户
     */

    @RequiresPermissions("meeting:roomContent:list")
    @GetMapping("getUserList")
    public R getUserList(IcsCustomerStaff customerStaff) {

        boolean isAdmin = SubjectUtil.hasRole(getRequest(),"manager");
        if (isAdmin){
            Long parkId = currentUserService.getParkId();
            Long tenantId = currentUserService.getTenantId();
            customerStaff.setParkId(parkId);
        }
        boolean b = SubjectUtil.hasRole(getRequest(),"admin");
        if (b){
            User user = userService.selectUserById(getCurrentUserId());
            if (null != user.getCustomerId()){
                Customer customer = customerService.selectCustomerById(user.getCustomerId());
                customerStaff.setIcsCustomerId(customer.getId());
            }
        }
        // todo  根据
        List<IcsCustomerStaff> icsCustomerStaffs = staffService.getUserList(customerStaff);

        for (IcsCustomerStaff icsCustomerStaff : icsCustomerStaffs) {
            List<StaffCustomer> staffCustomers = staffCustomerService.selectStaffCustomerByStaffId(icsCustomerStaff.getId());
            for (StaffCustomer staffCustomer : staffCustomers) {
                Customer customer = customerService.selectCustomerById(staffCustomer.getIcsCustomerId());
                if (null != customer) {
                    icsCustomerStaff.setCustomerName(customer.getName());
                }
            }
        }
        return R.data(icsCustomerStaffs);
    }

    /**
     * 获取所有的用户
     */

    @RequiresPermissions("meeting:roomContent:list")
    @GetMapping("getUserListByDeviceId/{id}")
    public R getUserListByDeviceId(@PathVariable("id") Long id) {
        UserEquipment userEquipment = new UserEquipment();
        userEquipment.setEquipmentId(id);
        ArrayList<Long> userId = new ArrayList<>();
        boolean isAdmin = SubjectUtil.hasRole(getRequest(),"manager");
        if (isAdmin){
            Long parkId = currentUserService.getParkId();
            userEquipment.setParkId(parkId);
        }
        boolean b = SubjectUtil.hasRole(getRequest(),"admin");
        if (b){
            User user = userService.selectUserById(getCurrentUserId());
            if (null != user.getCustomerId()){
                Customer customer = customerService.selectCustomerById(user.getCustomerId());
                //根据企业查询对应用户id
                List<IcsCustomerStaff> icsCustomerStaffs = staffService.selectUserByCustomer(customer.getId());
                List<Long> ids = icsCustomerStaffs.stream().map(item -> {
                    return item.getId();
                }).collect(Collectors.toList());
                userId.addAll(ids);
            }
        }
        userEquipment.setUserIds(userId);
        List<UserEquipment> equipments = userEquipmentService.selectUserEquipmentList(userEquipment);
        List<Long> userIds = equipments.stream().map(item -> {
            return item.getUserId();
        }).collect(Collectors.toList());

        if(CollUtil.isNotEmpty(userIds)){
            List<IcsCustomerStaff> icsCustomerStaffs = staffService.selectListByUserIds(userIds);
            for (IcsCustomerStaff icsCustomerStaff : icsCustomerStaffs) {
                Customer customer = customerService.selectCustomerById(icsCustomerStaff.getIcsCustomerId());
                if (null != customer) {
                    icsCustomerStaff.setCustomerName(customer.getName());
                }
            }
            return R.data(icsCustomerStaffs);
        }else {
            return R.data(new ArrayList<>());
        }

    }


    /**
     * 新增保存设备  授权人员
     */
    @Ignore
    @PostMapping("saveDevice")
    public R saveDevice(@RequestBody UserEquipment userEquipment) {
        List<Long> ids =new ArrayList<>();

        List<Long> list = userEquipmentService.selectEquipmentIdByEquipmentId(userEquipment.getId());

        List<Long> userIds = userEquipment.getUserIds();

        List<Long> reduce2 = list.stream().filter(item -> !userIds.contains(item)).collect(toList());
        log.info("reduce2------------------------------------:{}",reduce2);

        List<Long> reduce3 = userIds.stream().filter(item -> !list.contains(item)).collect(toList());
        log.info("reduce3------------------------------------:{}",reduce3);

        ids = Stream.concat(reduce2.stream(), reduce3.stream())
                .collect(Collectors.toList());

        if (CollUtil.isNotEmpty(ids)){
            for (Long id : ids) {

                UserEquipment userEquipment1 = userEquipmentService.selectUserAndEquipment(id, userEquipment.getId());
                if (userEquipment1 != null){
                    Equipment equipment1 = equipmentService.selectEquipmentById(userEquipment.getId());
                    if (equipment1 != null) {
                        DeviceUtils.deletePersons(equipment1.getIp(), id);
                    }
                    int count = userEquipmentService.deleteUserEquipmentByUserId(id, userEquipment.getId());
                    Assert.isTrue(count > 0, "删除失败");
                }else {
                    UserEquipment userEquipment2 = new UserEquipment();
                    userEquipment2.setEquipmentId(userEquipment.getId());
                    userEquipment2.setUserId(id);
                    IcsCustomerStaff customerStaff1 = staffService.selectIcsCustomerStaffById(id);
                    if (null != customerStaff1) {
                        Customer customer = customerService.selectCustomerById(customerStaff1.getId());
                        if (customer != null) {
                            userEquipment2.setStartTime(customer.getStartDate());
                            userEquipment2.setEndDate(customer.getEndDate());
                        }
                    }
                    userEquipmentService.insertUserEquipment(userEquipment2);

//                    //新增人脸
                    IcsCustomerStaff customerStaff = staffService.selectIcsCustomerStaffById(id);

                    DevicePersonDto devicePersonDto = new DevicePersonDto();
                    ArrayList<FacesDto> facesDtos = new ArrayList<>();
                    devicePersonDto.setPersonId(String.valueOf(customerStaff.getId()));
                    devicePersonDto.setName(customerStaff.getName());
                    devicePersonDto.setPhone(String.valueOf(customerStaff.getMobile()));
                    devicePersonDto.setCertificateType("111");
                    devicePersonDto.setCertificateNumber(customerStaff.getCardNo());
                    //添加人员类型
                    devicePersonDto.setPersonType("whitelist");
                    //添加访客时间
                    FacesDto facesDto = new FacesDto();
                    facesDto.setFaceId(String.valueOf(customerStaff.getId()));
                    String photoUrl = url + customerStaff.getPhoto();
                    String faceData = BASE64_PREFIX + UrlToBase64Util.imageUrlToBase64(photoUrl);

                    facesDto.setData(faceData);
                    facesDtos.add(facesDto);
                    devicePersonDto.setFaces(facesDtos);
                    log.info("设备id1：--------------------------" + userEquipment.getId());
                    Equipment equipment1 = equipmentService.selectEquipmentById(userEquipment.getId());
                    log.info("设备id2：-------------------" + equipment1.getId());
                    String s = DeviceUtils.addPersons(equipment1.getIp(), devicePersonDto);
                    log.info("添加人员返回结果：" + s);
                }

            }
        }




//        if (userEquipment.getId() != null) {
//            int num = userEquipmentService.selectListByEquipmentId(userEquipment.getId());
//            if (num > 0) {
//                int count = userEquipmentService.deleteUserEquipmentByEquipmentId(userEquipment.getId());
//                Assert.isTrue(count > 0, "删除失败");
//            }
//        }
//        for (Long id : userEquipment.getUserIds()) {
//            UserEquipment userEquipment1 = new UserEquipment();
//
//            List<StaffCustomer> staffCustomers = staffCustomerService.selectStaffCustomerByStaffId(id);
//            if (CollUtil.isNotEmpty(staffCustomers)){
//                Customer customer = customerService.selectCustomerById(staffCustomers.get(0).getIcsCustomerId());;
//                if (customer !=null){
//                    userEquipment1.setStartTime(customer.getStartDate());
//                    userEquipment1.setEndDate(customer.getEndDate());
//                }
//
//            }
//
//            userEquipment1.setEquipmentId(userEquipment.getId());
//            userEquipment1.setUserId(id);
//            int i = userEquipmentService.insertUserEquipment(userEquipment1);
//
//            Assert.isTrue(i > 0, "添加失败");
//
//        }
        return R.data(userEquipment);
    }

    @Ignore
    @GetMapping("/getRoomList")
    public R list(Room room) {
        room.setDeleteFlag(0);
        room.setBuildingDetailId(room.getBuildingDetailId());
        return R.ok().put("data", roomService.selectRoomList(room));
    }


}
