package com.ics.admin.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.ics.admin.domain.*;
import com.ics.admin.domain.meeting.*;
import com.ics.admin.listener.ImportPowerWaterFeeListener;
import com.ics.admin.service.*;
import com.ics.admin.service.meeting.*;
import com.ics.admin.utils.EasyPoiUtils;
import com.ics.admin.utils.ExcelView;
import com.ics.admin.utils.SellerVO;
import com.ics.admin.vo.ImportPowerWaterFeeVO;
import com.ics.common.constant.Constants;
import com.ics.common.core.controller.BaseController;
import com.ics.common.core.domain.BaseEntity;
import com.ics.common.core.domain.IcsCustomerStaff;
import com.ics.common.core.domain.R;
import com.ics.common.core.domain.dto.DevicePersonDto;
import com.ics.common.core.domain.dto.FacesDto;
import com.ics.common.utils.*;
import com.ics.common.utils.poi.ExcelUtil;
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.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.jxls.common.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.wf.jwtp.annotation.Ignore;
import org.wf.jwtp.annotation.RequiresPermissions;
import org.wf.jwtp.util.SubjectUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
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 ics
 * @date 2024-02-19
 */
@Slf4j
@RestController
@RequestMapping("/admin/staff")
public class CustomerStaffController extends BaseController {

    private final static String ACCESS_USERID = Constants.ACCESS_USERID;

    @Autowired
    private IIcsCustomerStaffService icsCustomerStaffService;
    @Autowired
    private IUserService userService;

    @Autowired
    private ICustomerService customerService;

    @Autowired
    private IRoomContentService roomContentService;
    @Autowired
    private IRoomService roomService;

    @Autowired
    private ICurrentUserService currentUserService;

    @Autowired
    private IRoomEquipmentService roomEquipmentService;

    @Autowired
    private IDetailEquipmentService detailEquipmentService;

    @Autowired
    private IUserEquipmentService userEquipmentService;

    @Autowired
    private IEquipmentService equipmentService;

    @Autowired
    private IBuildingDetailService buildingDetailService;

    @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;

    /**
     * 查询企业员工
     */
    @GetMapping("get/{id}")
    public IcsCustomerStaff get(@PathVariable("id") Long id) {
        return icsCustomerStaffService.selectIcsCustomerStaffById(id);
    }

    /**
     * 查询企业员工列表
     */
    @Ignore
    @GetMapping("list")
    public R list(IcsCustomerStaff icsCustomerStaff) {
        startPage();
        String customerId = icsCustomerStaff.getCustomerId();
        if (customerId != null && !"".equals(customerId)) {
            icsCustomerStaff.setIcsCustomerId(Long.valueOf(customerId));
        }
        icsCustomerStaff.setDataType(Constants.CUSTOMER_VISIT);
        return result(icsCustomerStaffService.selectIcsCustomerStaffList(icsCustomerStaff));
    }


    /**
     * 新增保存企业员工
     */
    @RequiresPermissions("admin:staff:add")
    @PostMapping("save")
    public R addSave(@RequestBody IcsCustomerStaff icsCustomerStaff) {

        icsCustomerStaff.setCreateTime(new Date());
        icsCustomerStaff.setCreateBy(getLoginName());
        icsCustomerStaff.setDataType(Constants.CUSTOMER_STAFF);
        int i = icsCustomerStaffService.insertIcsCustomerStaff(icsCustomerStaff);
        return toAjax(i);
    }

    /**
     * 修改保存企业员工
     */
    @Ignore
    @PostMapping("update")
    public R editSave(@RequestBody IcsCustomerStaff icsCustomerStaff) {

        icsCustomerStaff.setDataType(Constants.CUSTOMER_STAFF);
        icsCustomerStaff.setUpdateTime(new Date());
        return toAjax(icsCustomerStaffService.updateIcsCustomerStaff(icsCustomerStaff));
    }

    /**
     * 新增企业员工
     *
     * @param icsCustomerStaff
     * @return
     */
    @Ignore
    @PostMapping("updateStaff")
    public R updateStaff(@RequestBody IcsCustomerStaff icsCustomerStaff) {

        //如果没有注册小程序的话

        //如果是上海的小程序
        Long icsCustomerId = icsCustomerStaff.getIcsCustomerId();
        Customer customer1 = customerService.selectCustomerById(icsCustomerId);
        log.info("parkId为:",customer1.getParkId().toString());

        IcsCustomerStaff customerStaff = icsCustomerStaffService.selectUserByMobile(icsCustomerStaff.getMobile());
        if (customerStaff != null){
            icsCustomerStaff.setId(customerStaff.getId());
            int i = icsCustomerStaffService.updateIcsCustomerStaff(icsCustomerStaff);
            StaffCustomer staffCustomer = new StaffCustomer();
            staffCustomer.setIcsCustomerId(icsCustomerStaff.getIcsCustomerId());
            staffCustomer.setStaffId(customerStaff.getId());
            staffCustomer.setParkId(customer1.getParkId());
            staffCustomer.setTenantId(customer1.getTenantId());
            List<StaffCustomer> staffCustomers = staffCustomerService.selectStaffCustomerList(staffCustomer);
            if (staffCustomers.isEmpty()) {
                staffCustomerService.insertStaffCustomer(staffCustomer);
            }
            return toAjax(i);
        }else {
            icsCustomerStaff.setDataType("1");
            icsCustomerStaff.setParkId(customer1.getParkId());
            icsCustomerStaff.setTenantId(customer1.getTenantId());
            int i = icsCustomerStaffService.insertIcsCustomerStaff(icsCustomerStaff);
            Assert.isTrue(i > 0, "添加失败");
            //新增用户和企业 id
            StaffCustomer staffCustomer = new StaffCustomer();
            staffCustomer.setIcsCustomerId(icsCustomerStaff.getIcsCustomerId());
            staffCustomer.setStaffId(icsCustomerStaff.getId());
            staffCustomer.setParkId(customer1.getParkId());
            staffCustomer.setTenantId(customer1.getTenantId());
            staffCustomerService.insertStaffCustomer(staffCustomer);
            return toAjax(i);
        }



    }

    /**
     * 删除企业员工
     *
     * @param icsCustomerStaff
     * @return
     */
    @Ignore
    @PostMapping("updateStaffByCustomer")
    public R updateStaffByCustomer(@RequestBody IcsCustomerStaff icsCustomerStaff) {
        StaffCustomer staffCustomer = staffCustomerService.selectStaffIdAndCustomerId(icsCustomerStaff.getIcsCustomerId(), icsCustomerStaff.getId());
        int i = staffCustomerService.deleteStaffCustomerById(staffCustomer.getId());
        Assert.isTrue(i > 0, "删除失败");
        //删除用户与设备
        Long icsCustomerId = icsCustomerStaff.getIcsCustomerId();
        ArrayList<Long> ids = new ArrayList<>();

        //查询对应的企业
        Customer customer = customerService.selectCustomerById(icsCustomerId);


        if (null != customer) {
            String roomId = customer.getRoomId();
            String buildId = customer.getBuildId();

            List<Long> result = new ArrayList<>();

            List<String> buildIds = StrUtil.split(buildId, ',');

            List<String> roomIds = StrUtil.split(roomId, ',');
            List<Long> collect = roomIds.stream().map(Long::valueOf).collect(toList());
            List<Long> buildCollect = buildIds.stream().map(Long::valueOf).collect(toList());
            result.addAll(buildCollect);
            result.addAll(collect);
            //获取了房间集合，循环对应集合，
            for (Long id : result) {
                List<RoomEquipment> roomEquipment = roomEquipmentService.selectByRoomId(id);
                if (CollUtil.isNotEmpty(roomEquipment)) {
                    for (RoomEquipment equipment : roomEquipment) {
                        ids.add(equipment.getEquipmentId());
                    }
                }
                List<DetailEquipment> detailEquipments = detailEquipmentService.selectByRoomId(id);
                if (CollUtil.isNotEmpty(detailEquipments)) {
                    for (DetailEquipment detailEquipment : detailEquipments) {
                        ids.add(detailEquipment.getEquipmentId());
                    }
                }
            }
        }
        if (CollUtil.isNotEmpty(ids)) {
            for (Long id : ids) {
                int i1 = userEquipmentService.deleteUserEquipmentByUserId(icsCustomerStaff.getId(), id);
                //删除设备的用户
                Equipment equipment = equipmentService.selectEquipmentById(id);
                if (equipment != null) {
                    if (equipment.getType() == 0){
                        DeviceUtils.deletePersons(equipment.getIp(), icsCustomerStaff.getId());
                    }
                }
            }
        }
        return toAjax(i);
    }

    /**
     * 删除企业员工
     */
    @RequiresPermissions("admin:staff:remove")
    @PostMapping("remove")
    public R remove(String ids) {
        return toAjax(icsCustomerStaffService.deleteIcsCustomerStaffByIds(ids));
    }


    @Ignore
    @GetMapping("selectCustomerStaffList")
    public R selectCustomerStaffList(IcsCustomerStaff icsCustomerStaff) {
        startPage();
        String customerId = icsCustomerStaff.getCustomerId();
        if (customerId != null && !"".equals(customerId)) {
            icsCustomerStaff.setIcsCustomerId(Long.valueOf(customerId));
        }
        List<IcsCustomerStaff> icsCustomerStaffs = icsCustomerStaffService.selectCustomerStaffList(icsCustomerStaff);
        for (IcsCustomerStaff customerStaff : icsCustomerStaffs) {
            //获取设备数量
            UserEquipment userEquipment = new UserEquipment();
            userEquipment.setUserId(customerStaff.getId());
            List<UserEquipment> equipments = userEquipmentService.selectUserEquipmentNum(userEquipment);
            customerStaff.setNum(equipments.size());

        }
        return result(icsCustomerStaffs);
    }

    //    @RequiresPermissions("admin:staff:import")
    @Ignore
    @PostMapping("/importData")
    public R importData(MultipartFile file, Long customerId) throws Exception {
//        }
        ExcelUtil<IcsCustomerStaff> util = new ExcelUtil<IcsCustomerStaff>(IcsCustomerStaff.class);
        List<IcsCustomerStaff> userList = util.importExcel(file.getInputStream());

        boolean isAdmin = SubjectUtil.hasRole(getRequest(), "manager");
        if (isAdmin) {
            Long parkId = currentUserService.getParkId();
            Long tenantId = currentUserService.getTenantId();

        }

        boolean b = SubjectUtil.hasRole(getRequest(), "admin");
        if (b) {
            for (IcsCustomerStaff customerStaff : userList) {
                User user = userService.selectUserById(getCurrentUserId());
                if (user != null) {
                    customerStaff.setIcsCustomerId(user.getCustomerId());
                }
            }
        }
        String message = icsCustomerStaffService.importCustomerStaff(userList, customerId);
        return R.data(message);
    }

    @Ignore
    @GetMapping("/exportTemplate")
    public void exportTemplate(HttpServletResponse response) throws IOException {

        List<SellerVO> sellerVOList = new ArrayList<>();
        String title = "用户导入数据";
        String sheetName = "用户导模板";
        String fileName = sheetName + "-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls";
        EasyPoiUtils.exportExcel(sellerVOList, null, sheetName, SellerVO.class, fileName, true, response);
    }


    //授权用户设备权限，查询出所有的设备
    @RequiresPermissions("meeting:roomContent:list")
    @PostMapping("/selectUserDeviceList")
    public R selectUserDeviceList() {

        //根据园区 角色 查询所有的设备信息
        boolean isAdmin = SubjectUtil.hasRole(getRequest(), "manager");
        if (isAdmin) {
            Long parkId = currentUserService.getParkId();
            Equipment equipment1 = new Equipment();
            equipment1.setParkId(parkId);

            //根据园区id 查询所有的设备信息
            List<Equipment> equipment = equipmentService.selectEquipmentList(equipment1);
            List<Equipment> equipment2 = selectEquipmentListByIds(equipment);

            return R.data(equipment2);
        }
        boolean b = SubjectUtil.hasRole(getRequest(), "admin");
        if (b) {
            User user = userService.selectUserById(getCurrentUserId());
            if (null != user.getCustomerId()) {
                ArrayList<Long> ids = new ArrayList<>();
                Customer customer = customerService.selectCustomerById(user.getCustomerId());
                //根据企业 查询对应的 房间，和对应的楼层
                String roomId = customer.getRoomId();
                List<String> roomIds = StrUtil.split(roomId, ',');
                List<Long> collect = roomIds.stream().map(Long::valueOf).collect(toList());
                for (Long roomid : collect) {
                    Room room = roomService.selectRoomById(roomid);
                    if (null != room) {
                        Long id = room.getId();
                        List<RoomEquipment> roomEquipment = roomEquipmentService.selectByRoomId(id);
                        if (CollUtil.isNotEmpty(roomEquipment)) {
                            for (RoomEquipment equipment : roomEquipment) {
                                ids.add(equipment.getEquipmentId());
                            }
                        }
                        List<DetailEquipment> detailEquipments = detailEquipmentService.selectByRoomId(room.getBuildingDetailId());
                        if (CollUtil.isNotEmpty(detailEquipments)) {
                            for (DetailEquipment detailEquipment : detailEquipments) {
                                ids.add(detailEquipment.getEquipmentId());
                            }
                        }
                    }
                }
                if (CollUtil.isNotEmpty(ids)) {
                    List<Equipment> equipment = equipmentService.selectListByIds(ids);
                    List<Equipment> equipment1 = selectEquipmentListByIds(equipment);

                    return R.data(equipment1);
                } else {
                    return R.data(new ArrayList<Equipment>());
                }
            }
        }

        List<Equipment> equipment = equipmentService.selectEquipmentList(new Equipment());
        List<Equipment> equipment1 = selectEquipmentListByIds(equipment);
        return R.data(equipment1);
    }

    /**
     * 查询当前用户的所有设备
     *
     * @return
     */
    @RequiresPermissions("meeting:roomContent:list")
    @PostMapping("/selectEquipmentListById")
    public R selectEquipmentListById(@RequestBody UserEquipment equipment) {
        List<UserEquipment> equipments = userEquipmentService.selectUserEquipmentList(equipment);
        List<Long> collect = equipments.stream().map(UserEquipment::getEquipmentId).collect(toList());
        if (CollUtil.isNotEmpty(collect)) {
            List<Equipment> equipment1 = equipmentService.selectListByIds(collect);
            List<Equipment> equipment2 = selectEquipmentListByIds(equipment1);
            return R.data(equipment2);
        }
        return R.data(equipments);

    }


    public List<Equipment> selectEquipmentListByIds(List<Equipment> equipment) {
        for (Equipment equipment2 : equipment) {
            RoomEquipment roomEquipment = roomEquipmentService.selectByEquipmentId(equipment2.getId());
            if (roomEquipment != null) {
                Room room = roomService.selectRoomById(roomEquipment.getRoomId());
                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 (null != detailEquipment) {
                    BuildingDetail buildingDetail = buildingDetailService.selectBuildingDetailById(detailEquipment.getBuildingDetailId());
                    if (buildingDetail != null) {
                        equipment2.setBuildName(buildingDetail.getFloorName());
                    }
                }
            }
        }
        return equipment;
    }

    @RequiresPermissions("meeting:roomContent:list")
    @PostMapping("/saveUserEquipment")
    public R saveUserEquipment(@RequestBody UserEquipment equipment) {

        List<Long> ids =new ArrayList<>();


        List<Long> list = userEquipmentService.selectEquipmentIdByUserId(equipment.getUserId());
        //查询出当前用户的所有设备
        List<Long> userIds = equipment.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());

        log.info("reduce3------------------------------------:{}",ids);


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

                UserEquipment userEquipment = userEquipmentService.selectUserAndEquipment(equipment.getUserId(), id);
                if (userEquipment != null){
                    Equipment equipment1 = equipmentService.selectEquipmentById(id);
                    if (equipment1 != null) {
                        if (equipment1.getType() == 0){
                            DeviceUtils.deletePersons(equipment1.getIp(), equipment.getUserId());
                        }
                    }
                    int count = userEquipmentService.deleteUserEquipmentByUserId(equipment.getUserId(), id);
                    Assert.isTrue(count > 0, "删除失败");
                }else {
                    UserEquipment userEquipment1 = new UserEquipment();
                    userEquipment1.setEquipmentId(id);
                    userEquipment1.setUserId(equipment.getUserId());
                    IcsCustomerStaff customerStaff1 = icsCustomerStaffService.selectIcsCustomerStaffById(equipment.getUserId());
                    if (null != customerStaff1) {
                        List<StaffCustomer> staffCustomers = staffCustomerService.selectStaffCustomerByStaffId(customerStaff1.getId());
                        if (CollUtil.isNotEmpty(staffCustomers)) {
                            StaffCustomer staffCustomer = staffCustomers.get(0);
                            Customer customer = customerService.selectCustomerById(staffCustomer.getIcsCustomerId());
                            if (customer != null) {
                                userEquipment1.setStartTime(customer.getStartDate());
                                userEquipment1.setEndDate(customer.getEndDate());
                            }
                        }

                    }
                    userEquipmentService.insertUserEquipment(userEquipment1);
//                    //新增人脸
                    IcsCustomerStaff customerStaff = icsCustomerStaffService.selectIcsCustomerStaffById(equipment.getUserId());

                    Equipment equipment2 = equipmentService.selectEquipmentById(id);
                    if (equipment2 != null) {
                        if (equipment2.getType() == 0){
                            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);
                            Equipment equipment1 = equipmentService.selectEquipmentById(id);

                            String s = DeviceUtils.addPersons(equipment1.getIp(), devicePersonDto);
                            log.info("添加人员返回结果：" + s);
                        }
                    }

                }

            }
        }
        return R.ok();
    }

}
